@contractspec/bundle.library 3.9.4 → 3.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +9 -6
- package/CHANGELOG.md +39 -0
- package/dist/components/docs/advanced/AdvancedSpecExperimentsPage.js +4 -4
- package/dist/components/docs/advanced/index.js +10 -10
- package/dist/components/docs/index.js +168 -168
- package/dist/components/docs/libraries/LibrariesCrossPlatformUIPage.content.d.ts +3 -3
- package/dist/components/docs/libraries/LibrariesCrossPlatformUIPage.content.js +2 -2
- package/dist/components/docs/libraries/LibrariesCrossPlatformUIPage.js +2 -2
- package/dist/components/docs/libraries/index.js +2 -2
- package/dist/index.js +179 -179
- package/dist/node/components/docs/advanced/AdvancedSpecExperimentsPage.js +4 -4
- package/dist/node/components/docs/advanced/index.js +10 -10
- package/dist/node/components/docs/index.js +168 -168
- package/dist/node/components/docs/libraries/LibrariesCrossPlatformUIPage.content.js +2 -2
- package/dist/node/components/docs/libraries/LibrariesCrossPlatformUIPage.js +2 -2
- package/dist/node/components/docs/libraries/index.js +2 -2
- package/dist/node/index.js +179 -179
- package/package.json +24 -24
- package/src/components/docs/advanced/AdvancedSpecExperimentsPage.tsx +22 -14
- package/src/components/docs/generated/docs-index._common.json +1699 -2008
- package/src/components/docs/generated/docs-index.agent-console.json +377 -377
- package/src/components/docs/generated/docs-index.ai-chat-assistant.json +17 -17
- package/src/components/docs/generated/docs-index.ai-chat.json +105 -105
- package/src/components/docs/generated/docs-index.ai-support-bot.json +9 -9
- package/src/components/docs/generated/docs-index.analytics-dashboard.json +169 -169
- package/src/components/docs/generated/docs-index.app-config.json +137 -137
- package/src/components/docs/generated/docs-index.artisan-knowledge-product.json +17 -17
- package/src/components/docs/generated/docs-index.artisan-payments-stripe.json +33 -33
- package/src/components/docs/generated/docs-index.audit-trail.json +49 -49
- package/src/components/docs/generated/docs-index.calendar-google.json +9 -9
- package/src/components/docs/generated/docs-index.content-generation.json +9 -9
- package/src/components/docs/generated/docs-index.control-plane.json +17 -17
- package/src/components/docs/generated/docs-index.crm-pipeline.json +161 -161
- package/src/components/docs/generated/docs-index.data-grid-showcase.json +25 -25
- package/src/components/docs/generated/docs-index.defineExample.json +9 -9
- package/src/components/docs/generated/docs-index.email-gmail.json +9 -9
- package/src/components/docs/generated/docs-index.feature-flags.json +217 -217
- package/src/components/docs/generated/docs-index.files.json +177 -177
- package/src/components/docs/generated/docs-index.generated.ts +20 -20
- package/src/components/docs/generated/docs-index.harness-lab.json +9 -9
- package/src/components/docs/generated/docs-index.health.json +97 -97
- package/src/components/docs/generated/docs-index.identity-rbac.json +313 -313
- package/src/components/docs/generated/docs-index.in-app-docs.json +9 -9
- package/src/components/docs/generated/docs-index.integration-hub.json +265 -265
- package/src/components/docs/generated/docs-index.integration-posthog.json +9 -9
- package/src/components/docs/generated/docs-index.integration-stripe.json +9 -9
- package/src/components/docs/generated/docs-index.integration-supabase.json +9 -9
- package/src/components/docs/generated/docs-index.jobs.json +137 -137
- package/src/components/docs/generated/docs-index.kb-update-pipeline.json +129 -129
- package/src/components/docs/generated/docs-index.knowledge-canon.json +9 -9
- package/src/components/docs/generated/docs-index.learning-journey-ambient-coach.json +9 -9
- package/src/components/docs/generated/docs-index.learning-journey-crm-onboarding.json +49 -49
- package/src/components/docs/generated/docs-index.learning-journey-duo-drills.json +9 -9
- package/src/components/docs/generated/docs-index.learning-journey-platform-tour.json +49 -49
- package/src/components/docs/generated/docs-index.learning-journey-quest-challenges.json +9 -9
- package/src/components/docs/generated/docs-index.learning-journey-registry.json +33 -33
- package/src/components/docs/generated/docs-index.learning-journey-studio-onboarding.json +49 -49
- package/src/components/docs/generated/docs-index.learning-journey-ui-coaching.json +9 -9
- package/src/components/docs/generated/docs-index.learning-journey-ui-gamified.json +9 -9
- package/src/components/docs/generated/docs-index.learning-journey-ui-onboarding.json +9 -9
- package/src/components/docs/generated/docs-index.learning-journey-ui-shared.json +9 -9
- package/src/components/docs/generated/docs-index.learning-journey.json +241 -241
- package/src/components/docs/generated/docs-index.learning-patterns.json +9 -9
- package/src/components/docs/generated/docs-index.lifecycle-cli.json +9 -9
- package/src/components/docs/generated/docs-index.lifecycle-dashboard.json +9 -9
- package/src/components/docs/generated/docs-index.locale-jurisdiction-gate.json +65 -65
- package/src/components/docs/generated/docs-index.marketplace.json +337 -337
- package/src/components/docs/generated/docs-index.meeting-recorder-providers.json +9 -9
- package/src/components/docs/generated/docs-index.meeting-recorder.json +49 -49
- package/src/components/docs/generated/docs-index.messaging-agent-actions.json +17 -17
- package/src/components/docs/generated/docs-index.metrics.json +201 -201
- package/src/components/docs/generated/docs-index.minimal.json +17 -17
- package/src/components/docs/generated/docs-index.mobile-demo-landing.json +41 -41
- package/src/components/docs/generated/docs-index.notifications.json +65 -65
- package/src/components/docs/generated/docs-index.openbanking-powens.json +9 -9
- package/src/components/docs/generated/docs-index.openbanking.json +65 -65
- package/src/components/docs/generated/docs-index.opencode-cli.json +17 -17
- package/src/components/docs/generated/docs-index.personalization.json +9 -9
- package/src/components/docs/generated/docs-index.platform-acp.json +137 -137
- package/src/components/docs/generated/docs-index.platform-agent.json +201 -201
- package/src/components/docs/generated/docs-index.platform-context.json +121 -121
- package/src/components/docs/generated/docs-index.platform-control-plane.json +321 -321
- package/src/components/docs/generated/docs-index.platform-database.json +89 -89
- package/src/components/docs/generated/docs-index.platform-docs.json +161 -161
- package/src/components/docs/generated/docs-index.platform-harness.json +177 -177
- package/src/components/docs/generated/docs-index.platform-integrations.json +329 -329
- package/src/components/docs/generated/docs-index.platform-knowledge.json +57 -57
- package/src/components/docs/generated/docs-index.platform-provider-ranking.json +217 -217
- package/src/components/docs/generated/docs-index.pocket-family-office.json +129 -129
- package/src/components/docs/generated/docs-index.policy-safe-knowledge-assistant.json +9 -9
- package/src/components/docs/generated/docs-index.product-intent.json +9 -9
- package/src/components/docs/generated/docs-index.project-management-sync.json +9 -9
- package/src/components/docs/generated/docs-index.saas-boilerplate.json +209 -209
- package/src/components/docs/generated/docs-index.service-business-os.json +193 -193
- package/src/components/docs/generated/docs-index.team-hub.json +185 -185
- package/src/components/docs/generated/docs-index.unknown.json +521 -521
- package/src/components/docs/generated/docs-index.versioned-knowledge-base.json +81 -81
- package/src/components/docs/generated/docs-index.video-api-showcase.json +33 -33
- package/src/components/docs/generated/docs-index.video-docs-terminal.json +9 -9
- package/src/components/docs/generated/docs-index.video-marketing-clip.json +9 -9
- package/src/components/docs/generated/docs-index.visualization-showcase.json +17 -17
- package/src/components/docs/generated/docs-index.voice-providers.json +9 -9
- package/src/components/docs/generated/docs-index.wealth-snapshot.json +153 -153
- package/src/components/docs/generated/docs-index.workflow-system.json +433 -433
- package/src/components/docs/generated/docs-index.workspace-cli.json +9 -9
- package/src/components/docs/libraries/LibrariesCrossPlatformUIPage.content.ts +3 -3
package/dist/node/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
var ys=Object.defineProperty;var bs=(e)=>e;function vs(e,t){this[e]=bs.bind(null,t)}var Ns=(e,t)=>{for(var a in t)ys(e,a,{get:t[a],enumerable:!0,configurable:!0,set:vs.bind(t,a)})};var ws=(e,t)=>()=>(e&&(t=e(e=0)),t);var Bc="docs-index.manifest.json";var ur={};Ns(ur,{listGeneratedDocs:()=>hm,getGeneratedDocById:()=>bm,getDocsIndexManifest:()=>ym});import{readFile as Yr}from"node:fs/promises";import*as Qo from"node:path";import{fileURLToPath as mm}from"node:url";function gm(e){if(!e)return"_common";if(e.includes("/")){let[t]=e.split("/");return t||"_common"}return"_common"}async function Jr(){if(!Kr)Kr=Yr(Qo.join(mr,Bc),"utf8").then((e)=>JSON.parse(e));return Kr}function fm(e){let t=e.contentRoot??".";if(t==="../../../../../../../generated/docs")return um;return Qo.join(mr,t)}async function Uc(e){let t=Mc.get(e);if(t)return t;let a=Yr(Qo.join(mr,e),"utf8").then((r)=>JSON.parse(r));return Mc.set(e,a),a}async function hm(){if(!Qr)Qr=(async()=>{let e=await Jr();return(await Promise.all(e.chunks.map((a)=>Uc(a.file)))).flat()})();return Qr}async function ym(){return Jr()}async function bm(e){let t=await Jr(),a=gm(e),r=t.chunks.find((v)=>v.key===a);if(!r)return null;let b=(await Uc(r.file)).find((v)=>v.id===e);if(!b||!b.contentPath)return null;let h=Qo.join(fm(t),b.contentPath);try{let v=await Yr(h,"utf8");return{entry:b,content:v}}catch{return null}}var mr,um,Kr=null,Qr=null,Mc;var gr=ws(()=>{mr=Qo.dirname(mm(import.meta.url)),um=Qo.join(mr,"../../../../../../../generated/docs"),Mc=new Map});import{EventRegistry as ks,OperationSpecRegistry as Ss}from"@contractspec/lib.contracts-spec";import{DataViewRegistry as Cs}from"@contractspec/lib.contracts-spec/data-views";import{ContractReferenceDataView as Is,ContractReferenceQuery as Ps,DocsGenerateCommand as Ts,DocsGeneratedEvent as As,DocsIndexDataView as Rs,DocsIndexQuery as Ls,DocsLayoutPresentation as Ds,DocsPublishCommand as Es,DocsPublishedEvent as Os,DocsReferencePagePresentation as Bs,DocsSearchForm as Ms,ExampleCatalogDataView as Us}from"@contractspec/lib.contracts-spec/docs";import{FormRegistry as Ws}from"@contractspec/lib.contracts-spec/forms";import{PresentationRegistry as _s}from"@contractspec/lib.contracts-spec/presentations";import{serializeDataViewSpec as zs,serializeEventSpec as Gs,serializeFormSpec as qs,serializeOperationSpec as Hs,serializePresentationSpec as Vs}from"@contractspec/lib.contracts-spec/serialization";var rr=null;function Zn(){let e=new Ss;return e.register(Ls).register(Ps).register(Ts).register(Es),e}function $n(){if(!rr)rr=Zn();return rr}function Xn(e,t){return $n().get(e,t)}var nr=null;function xn(){let e=new ks;return e.register(As).register(Os),e}function jn(){if(!nr)nr=xn();return nr}function ec(e,t){return jn().get(e,t)}var cr=null;function tc(){let e=new _s;return e.register(Ds).register(Bs),e}function ac(){if(!cr)cr=tc();return cr}function oc(e,t){return ac().get(e,t)}var lr=null;function ic(){let e=new Cs;return e.register(Rs).register(Is).register(Us),e}function rc(){if(!lr)lr=ic();return lr}function nc(e,t){return rc().get(e,t)}var dr=null;function cc(){let e=new Ws;return e.register(Ms),e}function lc(){if(!dr)dr=cc();return dr}function dc(e,t){return lc().get(e)}function Fs(e,t){let a=Xn(e,t);return Hs(a)??void 0}function Ks(e,t){let a=ec(e,t);return Gs(a)??void 0}function Qs(e,t){let a=oc(e,t);return Vs(a)??void 0}function Ys(e,t){let a=nc(e,t);return zs(a)??void 0}function Js(e,t){let a=dc(e,t);return qs(a)??void 0}function sc(){rr=null}function pc(){nr=null}function mc(){cr=null}function uc(){lr=null}function gc(){dr=null}function Zs(){sc(),pc(),mc(),uc(),gc()}import{defineModuleBundle as $s}from"@contractspec/lib.surface-runtime/spec";var IN=$s({meta:{key:"bundles.library",version:"1.0.0",title:"Library",description:"ContractSpec package declaration for @contractspec/bundle.library."},routes:[{routeId:"default",path:"/",defaultSurface:"main"}],surfaces:{main:{surfaceId:"main",kind:"workbench",title:"Library",slots:[],layouts:[],data:[],verification:{dimensions:{guidance:"Scaffolded guidance profile for Library.",density:"Scaffolded density profile for Library.",dataDepth:"Scaffolded data-depth profile for Library.",control:"Scaffolded control profile for Library.",media:"Scaffolded media profile for Library.",pace:"Scaffolded pace profile for Library.",narrative:"Scaffolded narrative profile for Library."}}}}});var zr=[{key:"start",title:"Start",description:"Install ContractSpec, wire a first contract, and adopt it into an existing codebase."},{key:"core-model",title:"Core Model",description:"Learn how contracts, generated surfaces, policies, overlays, and safe regeneration fit together."},{key:"build",title:"Build",description:"Use practical guides, libraries, architecture patterns, and examples to ship real surfaces."},{key:"operate",title:"Operate",description:"Run the system safely with governance, auditability, tracing, and operator-grade controls."},{key:"integrations",title:"Integrations",description:"Connect models, messaging, storage, payments, search, and external systems through typed bindings."},{key:"reference",title:"Reference",description:"Search generated contract docs, inspect example packages, and navigate the system as source of truth."},{key:"studio",title:"Studio",description:"Understand what Studio adds on top of the open system and when to adopt it."}],sr=[{href:"/docs",title:"Documentation",description:"OSS-first documentation for ContractSpec, the open spec system for AI-native software.",audience:"oss",ctaMode:"oss-next"},{href:"/docs/getting-started/start-here",title:"Start here",description:"The fastest path from install to your first contract and generated surface.",section:"start",order:10,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/getting-started/installation",title:"Installation",description:"Install the CLI and core packages, then prepare a workspace for incremental adoption.",section:"start",order:20,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/getting-started/hello-world",title:"Hello world",description:"Define a first operation, generate the surface, and verify the end-to-end loop.",section:"start",order:30,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/getting-started/compatibility",title:"Compatibility",description:"Check the supported runtimes, package managers, and adoption assumptions before rollout.",section:"start",order:40,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/getting-started/tools",title:"Developer tools",description:"Use the CLI, editors, and helper tooling that make the OSS workflow practical day to day.",section:"start",order:50,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/getting-started/troubleshooting",title:"Troubleshooting",description:"Resolve the common installation, validation, and runtime mistakes you hit during first adoption.",section:"start",order:60,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/specs",title:"Contracts and specs",description:"Understand the spec model that drives generated surfaces, validation, policy, and safe regeneration.",section:"core-model",order:10,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/specs/capabilities",title:"Capabilities",description:"Model commands, queries, presentations, and events as explicit contract surfaces.",section:"core-model",order:20,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/specs/dataviews",title:"Data views",description:"Define queryable, presentable views that stay aligned with the rest of the system.",section:"core-model",order:30,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/specs/workflows",title:"Workflows",description:"Compose multi-step behavior from typed contracts, policies, and runtime orchestration.",section:"core-model",order:40,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/specs/policy",title:"Policy",description:"Apply consistent governance, access rules, and risk controls across every surface.",section:"core-model",order:50,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/specs/overlays",title:"Overlays",description:"Customize generated surfaces safely without forking the system or breaking regeneration.",section:"core-model",order:60,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/specs/module-bundles",title:"Module bundles",description:"Define AI-native surfaces as typed bundle specs that resolve into personalized, auditable runtime plans.",section:"core-model",order:70,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/specs/connect",title:"ContractSpec Connect",description:"Guard coding-agent edits and shell actions with task-scoped context, plan packets, patch verdicts, and review packets.",section:"core-model",order:80,navTitle:"Connect",primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/specs/builder-control-plane",title:"Builder control plane",description:"Route multimodal authoring work through governed builder contracts, provider policies, readiness gates, and mobile review flows.",section:"core-model",order:90,primaryNav:!0,audience:"studio-bridge",ctaMode:"studio-bridge"},{href:"/docs/guides/contract-types",title:"Contract types",description:"Choose the right contract surface for the behavior you want to make explicit.",section:"core-model",order:100,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/guides",title:"Guides",description:"Follow concrete adoption paths for existing apps, generated docs, CI gating, and typed surfaces.",section:"build",order:10,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/guides/nextjs-one-endpoint",title:"Adopt one endpoint in Next.js",description:"Start with one endpoint, one contract, and one generated surface in an existing Next.js app.",section:"build",order:20,navTitle:"Next.js endpoint",primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/guides/import-existing-codebases",title:"Import an existing codebase",description:"Stabilize a live codebase incrementally instead of rewriting it from scratch.",section:"build",order:30,navTitle:"Import existing code",primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/guides/spec-validation-and-typing",title:"Validation and typing",description:"Keep runtime validation and TypeScript types aligned from the same source definitions.",section:"build",order:40,navTitle:"Validation and typing",primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/guides/generate-docs-clients-schemas",title:"Generate docs, clients, and schemas",description:"Export stable docs and client-facing artifacts from the same contract layer.",section:"build",order:50,navTitle:"Generate docs and clients",primaryNav:!0,audience:"oss",ctaMode:"reference"},{href:"/docs/guides/docs-generation-pipeline",title:"Docs generation pipeline",description:"Feed generated docs into the public docs site without breaking source-of-truth ownership.",section:"build",order:60,navTitle:"Docs pipeline",primaryNav:!0,audience:"oss",ctaMode:"reference"},{href:"/docs/guides/first-module-bundle",title:"Build a first module bundle",description:"Define one bundle spec, resolve a personalized surface plan, and render it through the React host layer.",section:"build",order:65,navTitle:"First module bundle",primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/guides/host-builder-workbench",title:"Host the Builder workbench",description:"Load a Builder workspace snapshot, wire common commands, and keep runtime mode plus mobile review flows explicit.",section:"build",order:66,navTitle:"Host Builder workbench",primaryNav:!0,audience:"studio-bridge",ctaMode:"studio-bridge"},{href:"/docs/guides/connect-in-a-repo",title:"Use Connect in a repo",description:"Enable Connect in workspace config, verify agent actions, and inspect local review and replay artifacts.",section:"build",order:67,navTitle:"Connect in a repo",primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/libraries",title:"Libraries overview",description:"Navigate the core libraries, runtimes, and system packages that make up the open foundation.",section:"build",order:70,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/libraries/cross-platform-ui",title:"Cross-platform UI",description:"Understand how the presentation runtimes, ui-kit-web, ui-kit, and design-system stay aligned across React and React Native.",section:"build",order:71,audience:"oss",ctaMode:"oss-next"},{href:"/docs/architecture",title:"Architecture",description:"See how the spec layer, runtimes, integrations, and multi-surface outputs fit together.",section:"build",order:80,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/safety",title:"Operate safely",description:"Add auditability, migrations, policy controls, and trustworthy release behavior from the start.",section:"operate",order:10,navTitle:"Safety overview",primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/guides/ci-contract-diff-gating",title:"CI diff gating",description:"Use deterministic checks to block drift and risky changes before they reach production.",section:"operate",order:20,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/guides/release-capsules",title:"Author release capsules",description:"Pair changesets with structured release capsules, generate release artifacts, and keep changelog plus docs surfaces aligned.",section:"operate",order:25,navTitle:"Release capsules",primaryNav:!0,audience:"operator",ctaMode:"reference"},{href:"/docs/safety/security-trust",title:"Security and trust",description:"Understand the trust model, artifact validation expectations, and operational boundaries.",section:"operate",order:30,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/safety/auditing",title:"Audit trails",description:"Track changes, policy decisions, and operational actions with a clear evidence trail.",section:"operate",order:40,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/safety/migrations",title:"Migrations",description:"Evolve schemas and data safely without abandoning the contract layer.",section:"operate",order:50,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/safety/tenant-isolation",title:"Tenant isolation",description:"Keep tenant data, config, policies, and integrations separated at runtime.",section:"operate",order:60,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/knowledge",title:"Knowledge and context",description:"Bind trusted knowledge sources to the system without losing governance or isolation.",section:"operate",order:70,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/advanced/telemetry",title:"Telemetry",description:"Instrument surfaces, collect evidence, and keep observability aligned with the contract model.",section:"operate",order:80,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/advanced/workflow-monitoring",title:"Workflow monitoring",description:"Observe multi-step execution with enough context to understand failures and regressions.",section:"operate",order:90,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/ops/distributed-tracing",title:"Distributed tracing",description:"Trace contract execution across integrations, workflows, and generated surfaces.",section:"operate",order:100,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/integrations",title:"Integrations overview",description:"Understand the binding model for external services, providers, and tenant-owned connections.",section:"integrations",order:10,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/integrations/spec-model",title:"Integration spec model",description:"Define what an integration provides before wiring it into an app or runtime.",section:"integrations",order:20,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/integrations/openai",title:"OpenAI integration",description:"Connect OpenAI through typed capabilities, explicit provider config, and governed runtime usage.",section:"integrations",order:30,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/integrations/mistral",title:"Mistral integration",description:"Use Mistral through the same provider contract model and runtime guardrails.",section:"integrations",order:40,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/integrations/qdrant",title:"Qdrant integration",description:"Store and retrieve knowledge embeddings with explicit provider configuration and ownership.",section:"integrations",order:50,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/integrations/stripe",title:"Stripe integration",description:"Bind payments and billing behavior without smearing provider logic across the codebase.",section:"integrations",order:60,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/integrations/twilio",title:"Twilio integration",description:"Handle messaging and telephony through typed transport boundaries and explicit configuration.",section:"integrations",order:70,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/integrations/github",title:"GitHub integration",description:"Push execution context into GitHub workflows and automation surfaces without hidden glue.",section:"integrations",order:80,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/reference",title:"Contract reference",description:"Browse the generated reference index for public contract surfaces, versions, and examples.",section:"reference",order:10,primaryNav:!0,audience:"reference",ctaMode:"reference"},{href:"/docs/examples",title:"Examples",description:"Explore runnable examples and use them as reference implementations for new systems.",section:"reference",order:20,primaryNav:!0,audience:"reference",ctaMode:"reference"},{href:"/docs/studio",title:"Studio overview",description:"See what Studio adds on top of OSS ContractSpec and when a team should adopt the operating layer.",section:"studio",order:10,primaryNav:!0,audience:"studio-bridge",ctaMode:"studio-bridge"},{href:"/docs/manifesto",title:"Manifesto",description:"Why ContractSpec is built as an open system, how incremental adoption works, and why Studio stays additive.",audience:"secondary"},{href:"/docs/intent/contract-first-api",title:"Contract-first API",description:"Use contracts as the durable source of truth for API behavior and generated surfaces.",audience:"secondary"},{href:"/docs/intent/spec-driven-development",title:"Spec-driven development",description:"See how explicit specs stabilize change across APIs, UI, data, and agent-facing surfaces.",audience:"secondary"},{href:"/docs/intent/deterministic-codegen",title:"Deterministic regeneration",description:"Understand safe regeneration, conflict boundaries, and why teams keep control of the output.",audience:"secondary"},{href:"/docs/intent/schema-validation-typescript",title:"Schema validation and TypeScript",description:"Keep schema, runtime validation, and TypeScript behavior aligned without duplicate work.",audience:"secondary"},{href:"/docs/intent/openapi-alternative",title:"OpenAPI alternative",description:"Compare a multi-surface contract system with API-only description tooling.",audience:"secondary"},{href:"/docs/intent/generate-client-from-schema",title:"Generate client from schema",description:"Generate client-facing artifacts from the same source that drives runtime behavior.",audience:"secondary"},{href:"/docs/comparison",title:"Comparison overview",description:"Compare ContractSpec with workflow engines, internal-tool builders, and enterprise orchestration products.",audience:"secondary"},{href:"/docs/comparison/workflow-engines",title:"Workflow engines",description:"Contrast a contract system with workflow-only orchestration approaches.",audience:"secondary"},{href:"/docs/comparison/internal-tool-builders",title:"Internal-tool builders",description:"Compare ContractSpec with builders that optimize for screens instead of durable system contracts.",audience:"secondary"},{href:"/docs/comparison/automation-platforms",title:"Automation platforms",description:"Compare automation-first tools with a system that owns explicit contracts and generated surfaces.",audience:"secondary"},{href:"/docs/comparison/windmill",title:"Windmill comparison",description:"Understand where Windmill fits and where ContractSpec solves a different class of system problem.",audience:"secondary"},{href:"/docs/comparison/enterprise-platforms",title:"Enterprise orchestrators",description:"Compare ContractSpec with enterprise platforms that centralize execution in a closed operating surface.",audience:"secondary"},{href:"/docs/ecosystem/templates",title:"Templates",description:"Use templates and starter systems as proof points and accelerators for OSS adoption.",audience:"secondary"},{href:"/docs/ecosystem/plugins",title:"Plugins",description:"Explore marketplace and editor integrations that support the OSS workflow.",audience:"secondary"},{href:"/docs/ecosystem/registry",title:"Registry",description:"Inspect registry and manifest concepts that help package reusable capability surfaces.",audience:"secondary"}];function TN(e){return sr.find((t)=>t.href===e)}function Xs(){return zr.map((e)=>({...e,items:sr.filter((t)=>t.section===e.key&&t.primaryNav).sort((t,a)=>(t.order??0)-(a.order??0))}))}function xs(){return sr.filter((e)=>e.primaryNav).sort((e,t)=>zr.findIndex((a)=>a.key===e.section)-zr.findIndex((a)=>a.key===t.section)||(e.order??0)-(t.order??0))}function AN(e){let t=xs(),a=t.findIndex((r)=>r.href===e);if(a<0)return{previous:null,next:null};return{previous:t[a-1]??null,next:t[a+1]??null}}function fc(){return sr.filter((e)=>e.audience==="secondary")}function hc(){return Xs().map((e)=>({...e,featured:e.items.slice(0,3)}))}import{CodeBlock as js}from"@contractspec/lib.design-system";import Vo from"@contractspec/lib.ui-link";import{ArrowRight as Gr,Boxes as yc,FileSearch as ep,ShieldCheck as tp,Waypoints as ap}from"lucide-react";import{jsx as A,jsxs as se}from"react/jsx-runtime";var op=[{title:"One system, many surfaces",body:"Define explicit contracts once, then keep APIs, UI, data, events, and agent-facing surfaces aligned.",icon:yc},{title:"Incremental adoption",body:"Start with one endpoint, one workflow, or one unsafe module. You do not need a rewrite to begin.",icon:ap},{title:"Operator-grade controls",body:"Carry policy, auditability, migrations, tracing, and integration boundaries forward with the same system model.",icon:tp}],ip=[{title:"ContractSpec Connect",body:"Guard coding-agent edits and commands with local-first context, plan packets, patch verdicts, and review packets.",specHref:"/docs/specs/connect",guideHref:"/docs/guides/connect-in-a-repo"},{title:"Module bundles",body:"Define AI-native surfaces as typed bundle specs that resolve into auditable runtime plans.",specHref:"/docs/specs/module-bundles",guideHref:"/docs/guides/first-module-bundle"},{title:"Builder control plane",body:"Coordinate multimodal authoring, provider routing, readiness, export, and mobile review through governed contracts.",specHref:"/docs/specs/builder-control-plane",guideHref:"/docs/guides/host-builder-workbench"}];function rp(){let e=hc(),t=fc().slice(0,6);return se("div",{className:"space-y-12",children:[se("section",{className:"space-y-6",children:[A("p",{className:"editorial-kicker",children:"OSS documentation"}),A("h1",{className:"editorial-title max-w-5xl",children:"Build AI-native systems on explicit contracts, then add Studio when you want the operating layer."}),A("p",{className:"editorial-subtitle",children:"These docs are optimized for OSS adopters first. Learn the contract model, generate and govern surfaces safely, wire integrations, and run the system in production without giving up ownership of your code."}),se("div",{className:"flex flex-wrap gap-3",children:[se(Vo,{href:"/docs/getting-started/start-here",className:"btn-primary text-sm",children:["Start with OSS ",A(Gr,{size:16})]}),A(Vo,{href:"/docs/studio",className:"btn-ghost text-sm",children:"See what Studio adds"})]})]}),A("section",{className:"grid gap-5 md:grid-cols-3",children:op.map((a)=>{let r=a.icon;return se("article",{className:"editorial-panel space-y-3",children:[se("div",{className:"flex items-center gap-3",children:[A("div",{className:"rounded-full border border-border/80 bg-background/85 p-2",children:A(r,{size:18})}),A("h2",{className:"font-semibold text-xl",children:a.title})]}),A("p",{className:"editorial-copy text-sm",children:a.body})]},a.title)})}),se("section",{className:"space-y-5",children:[se("div",{className:"space-y-2",children:[A("p",{className:"editorial-kicker",children:"Implemented packs"}),A("h2",{className:"editorial-panel-title",children:"Use the three higher-order systems that are already wired"}),A("p",{className:"editorial-copy text-sm",children:"These pages are the canonical landing points for agent enforcement, AI-native surface composition, and Builder authoring. Each one now has a matching practical guide."})]}),A("div",{className:"grid gap-4 lg:grid-cols-3",children:ip.map((a)=>se("article",{className:"editorial-panel space-y-4",children:[se("div",{children:[A("h3",{className:"font-semibold text-xl",children:a.title}),A("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:a.body})]}),se("div",{className:"flex flex-wrap gap-3",children:[se(Vo,{href:a.specHref,className:"btn-primary text-sm",children:["Open spec page ",A(Gr,{size:16})]}),A(Vo,{href:a.guideHref,className:"btn-ghost text-sm",children:"Read practical guide"})]})]},a.title))})]}),se("section",{className:"editorial-panel space-y-5",children:[se("div",{className:"space-y-2",children:[A("p",{className:"editorial-kicker",children:"Quick start"}),A("h2",{className:"editorial-panel-title",children:"Start with one contract"}),A("p",{className:"editorial-copy text-sm",children:"Use the CLI and core libraries to define one explicit capability, generate the surface, and validate the contract boundary before you expand."})]}),A(js,{language:"bash",filename:"docs-quick-start",code:`bun add -D contractspec
|
|
1
|
+
var Ns=Object.defineProperty;var ws=(e)=>e;function ks(e,t){this[e]=ws.bind(null,t)}var Ss=(e,t)=>{for(var a in t)Ns(e,a,{get:t[a],enumerable:!0,configurable:!0,set:ks.bind(t,a)})};var Cs=(e,t)=>()=>(e&&(t=e(e=0)),t);var Wc="docs-index.manifest.json";var ur={};Ss(ur,{listGeneratedDocs:()=>wm,getGeneratedDocById:()=>Sm,getDocsIndexManifest:()=>km});import{readFile as Zr}from"node:fs/promises";import*as Qo from"node:path";import{fileURLToPath as ym}from"node:url";function vm(e){if(!e)return"_common";if(e.includes("/")){let[t]=e.split("/");return t||"_common"}return"_common"}async function $r(){if(!Yr)Yr=Zr(Qo.join(mr,Wc),"utf8").then((e)=>JSON.parse(e));return Yr}function Nm(e){let t=e.contentRoot??".";if(t==="../../../../../../../generated/docs")return bm;return Qo.join(mr,t)}async function zc(e){let t=_c.get(e);if(t)return t;let a=Zr(Qo.join(mr,e),"utf8").then((r)=>JSON.parse(r));return _c.set(e,a),a}async function wm(){if(!Jr)Jr=(async()=>{let e=await $r();return(await Promise.all(e.chunks.map((a)=>zc(a.file)))).flat()})();return Jr}async function km(){return $r()}async function Sm(e){let t=await $r(),a=vm(e),r=t.chunks.find((v)=>v.key===a);if(!r)return null;let b=(await zc(r.file)).find((v)=>v.id===e);if(!b||!b.contentPath)return null;let h=Qo.join(Nm(t),b.contentPath);try{let v=await Zr(h,"utf8");return{entry:b,content:v}}catch{return null}}var mr,bm,Yr=null,Jr=null,_c;var gr=Cs(()=>{mr=Qo.dirname(ym(import.meta.url)),bm=Qo.join(mr,"../../../../../../../generated/docs"),_c=new Map});import{EventRegistry as Is,OperationSpecRegistry as Ps}from"@contractspec/lib.contracts-spec";import{DataViewRegistry as Ts}from"@contractspec/lib.contracts-spec/data-views";import{ContractReferenceDataView as As,ContractReferenceQuery as Rs,DocsGenerateCommand as Ls,DocsGeneratedEvent as Ds,DocsIndexDataView as Es,DocsIndexQuery as Os,DocsLayoutPresentation as Bs,DocsPublishCommand as Ms,DocsPublishedEvent as Us,DocsReferencePagePresentation as Ws,DocsSearchForm as _s,ExampleCatalogDataView as zs}from"@contractspec/lib.contracts-spec/docs";import{FormRegistry as Gs}from"@contractspec/lib.contracts-spec/forms";import{PresentationRegistry as qs}from"@contractspec/lib.contracts-spec/presentations";import{serializeDataViewSpec as Hs,serializeEventSpec as Vs,serializeFormSpec as Fs,serializeOperationSpec as Ks,serializePresentationSpec as Qs}from"@contractspec/lib.contracts-spec/serialization";var rr=null;function Xn(){let e=new Ps;return e.register(Os).register(Rs).register(Ls).register(Ms),e}function xn(){if(!rr)rr=Xn();return rr}function jn(e,t){return xn().get(e,t)}var nr=null;function ec(){let e=new Is;return e.register(Ds).register(Us),e}function tc(){if(!nr)nr=ec();return nr}function ac(e,t){return tc().get(e,t)}var cr=null;function oc(){let e=new qs;return e.register(Bs).register(Ws),e}function ic(){if(!cr)cr=oc();return cr}function rc(e,t){return ic().get(e,t)}var lr=null;function nc(){let e=new Ts;return e.register(Es).register(As).register(zs),e}function cc(){if(!lr)lr=nc();return lr}function lc(e,t){return cc().get(e,t)}var dr=null;function dc(){let e=new Gs;return e.register(_s),e}function sc(){if(!dr)dr=dc();return dr}function pc(e,t){return sc().get(e)}function Ys(e,t){let a=jn(e,t);return Ks(a)??void 0}function Js(e,t){let a=ac(e,t);return Vs(a)??void 0}function Zs(e,t){let a=rc(e,t);return Qs(a)??void 0}function $s(e,t){let a=lc(e,t);return Hs(a)??void 0}function Xs(e,t){let a=pc(e,t);return Fs(a)??void 0}function mc(){rr=null}function uc(){nr=null}function gc(){cr=null}function fc(){lr=null}function hc(){dr=null}function xs(){mc(),uc(),gc(),fc(),hc()}import{defineModuleBundle as js}from"@contractspec/lib.surface-runtime/spec";var LN=js({meta:{key:"bundles.library",version:"1.0.0",title:"Library",description:"ContractSpec package declaration for @contractspec/bundle.library."},routes:[{routeId:"default",path:"/",defaultSurface:"main"}],surfaces:{main:{surfaceId:"main",kind:"workbench",title:"Library",slots:[],layouts:[],data:[],verification:{dimensions:{guidance:"Scaffolded guidance profile for Library.",density:"Scaffolded density profile for Library.",dataDepth:"Scaffolded data-depth profile for Library.",control:"Scaffolded control profile for Library.",media:"Scaffolded media profile for Library.",pace:"Scaffolded pace profile for Library.",narrative:"Scaffolded narrative profile for Library."}}}}});var zr=[{key:"start",title:"Start",description:"Install ContractSpec, wire a first contract, and adopt it into an existing codebase."},{key:"core-model",title:"Core Model",description:"Learn how contracts, generated surfaces, policies, overlays, and safe regeneration fit together."},{key:"build",title:"Build",description:"Use practical guides, libraries, architecture patterns, and examples to ship real surfaces."},{key:"operate",title:"Operate",description:"Run the system safely with governance, auditability, tracing, and operator-grade controls."},{key:"integrations",title:"Integrations",description:"Connect models, messaging, storage, payments, search, and external systems through typed bindings."},{key:"reference",title:"Reference",description:"Search generated contract docs, inspect example packages, and navigate the system as source of truth."},{key:"studio",title:"Studio",description:"Understand what Studio adds on top of the open system and when to adopt it."}],sr=[{href:"/docs",title:"Documentation",description:"OSS-first documentation for ContractSpec, the open spec system for AI-native software.",audience:"oss",ctaMode:"oss-next"},{href:"/docs/getting-started/start-here",title:"Start here",description:"The fastest path from install to your first contract and generated surface.",section:"start",order:10,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/getting-started/installation",title:"Installation",description:"Install the CLI and core packages, then prepare a workspace for incremental adoption.",section:"start",order:20,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/getting-started/hello-world",title:"Hello world",description:"Define a first operation, generate the surface, and verify the end-to-end loop.",section:"start",order:30,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/getting-started/compatibility",title:"Compatibility",description:"Check the supported runtimes, package managers, and adoption assumptions before rollout.",section:"start",order:40,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/getting-started/tools",title:"Developer tools",description:"Use the CLI, editors, and helper tooling that make the OSS workflow practical day to day.",section:"start",order:50,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/getting-started/troubleshooting",title:"Troubleshooting",description:"Resolve the common installation, validation, and runtime mistakes you hit during first adoption.",section:"start",order:60,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/specs",title:"Contracts and specs",description:"Understand the spec model that drives generated surfaces, validation, policy, and safe regeneration.",section:"core-model",order:10,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/specs/capabilities",title:"Capabilities",description:"Model commands, queries, presentations, and events as explicit contract surfaces.",section:"core-model",order:20,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/specs/dataviews",title:"Data views",description:"Define queryable, presentable views that stay aligned with the rest of the system.",section:"core-model",order:30,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/specs/workflows",title:"Workflows",description:"Compose multi-step behavior from typed contracts, policies, and runtime orchestration.",section:"core-model",order:40,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/specs/policy",title:"Policy",description:"Apply consistent governance, access rules, and risk controls across every surface.",section:"core-model",order:50,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/specs/overlays",title:"Overlays",description:"Customize generated surfaces safely without forking the system or breaking regeneration.",section:"core-model",order:60,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/specs/module-bundles",title:"Module bundles",description:"Define AI-native surfaces as typed bundle specs that resolve into personalized, auditable runtime plans.",section:"core-model",order:70,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/specs/connect",title:"ContractSpec Connect",description:"Guard coding-agent edits and shell actions with task-scoped context, plan packets, patch verdicts, and review packets.",section:"core-model",order:80,navTitle:"Connect",primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/specs/builder-control-plane",title:"Builder control plane",description:"Route multimodal authoring work through governed builder contracts, provider policies, readiness gates, and mobile review flows.",section:"core-model",order:90,primaryNav:!0,audience:"studio-bridge",ctaMode:"studio-bridge"},{href:"/docs/guides/contract-types",title:"Contract types",description:"Choose the right contract surface for the behavior you want to make explicit.",section:"core-model",order:100,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/guides",title:"Guides",description:"Follow concrete adoption paths for existing apps, generated docs, CI gating, and typed surfaces.",section:"build",order:10,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/guides/nextjs-one-endpoint",title:"Adopt one endpoint in Next.js",description:"Start with one endpoint, one contract, and one generated surface in an existing Next.js app.",section:"build",order:20,navTitle:"Next.js endpoint",primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/guides/import-existing-codebases",title:"Import an existing codebase",description:"Stabilize a live codebase incrementally instead of rewriting it from scratch.",section:"build",order:30,navTitle:"Import existing code",primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/guides/spec-validation-and-typing",title:"Validation and typing",description:"Keep runtime validation and TypeScript types aligned from the same source definitions.",section:"build",order:40,navTitle:"Validation and typing",primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/guides/generate-docs-clients-schemas",title:"Generate docs, clients, and schemas",description:"Export stable docs and client-facing artifacts from the same contract layer.",section:"build",order:50,navTitle:"Generate docs and clients",primaryNav:!0,audience:"oss",ctaMode:"reference"},{href:"/docs/guides/docs-generation-pipeline",title:"Docs generation pipeline",description:"Feed generated docs into the public docs site without breaking source-of-truth ownership.",section:"build",order:60,navTitle:"Docs pipeline",primaryNav:!0,audience:"oss",ctaMode:"reference"},{href:"/docs/guides/first-module-bundle",title:"Build a first module bundle",description:"Define one bundle spec, resolve a personalized surface plan, and render it through the React host layer.",section:"build",order:65,navTitle:"First module bundle",primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/guides/host-builder-workbench",title:"Host the Builder workbench",description:"Load a Builder workspace snapshot, wire common commands, and keep runtime mode plus mobile review flows explicit.",section:"build",order:66,navTitle:"Host Builder workbench",primaryNav:!0,audience:"studio-bridge",ctaMode:"studio-bridge"},{href:"/docs/guides/connect-in-a-repo",title:"Use Connect in a repo",description:"Enable Connect in workspace config, verify agent actions, and inspect local review and replay artifacts.",section:"build",order:67,navTitle:"Connect in a repo",primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/libraries",title:"Libraries overview",description:"Navigate the core libraries, runtimes, and system packages that make up the open foundation.",section:"build",order:70,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/libraries/cross-platform-ui",title:"Cross-platform UI",description:"Understand how the presentation runtimes, ui-kit-web, ui-kit, and design-system stay aligned across React and React Native.",section:"build",order:71,audience:"oss",ctaMode:"oss-next"},{href:"/docs/architecture",title:"Architecture",description:"See how the spec layer, runtimes, integrations, and multi-surface outputs fit together.",section:"build",order:80,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/safety",title:"Operate safely",description:"Add auditability, migrations, policy controls, and trustworthy release behavior from the start.",section:"operate",order:10,navTitle:"Safety overview",primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/guides/ci-contract-diff-gating",title:"CI diff gating",description:"Use deterministic checks to block drift and risky changes before they reach production.",section:"operate",order:20,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/guides/release-capsules",title:"Author release capsules",description:"Pair changesets with structured release capsules, generate release artifacts, and keep changelog plus docs surfaces aligned.",section:"operate",order:25,navTitle:"Release capsules",primaryNav:!0,audience:"operator",ctaMode:"reference"},{href:"/docs/safety/security-trust",title:"Security and trust",description:"Understand the trust model, artifact validation expectations, and operational boundaries.",section:"operate",order:30,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/safety/auditing",title:"Audit trails",description:"Track changes, policy decisions, and operational actions with a clear evidence trail.",section:"operate",order:40,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/safety/migrations",title:"Migrations",description:"Evolve schemas and data safely without abandoning the contract layer.",section:"operate",order:50,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/safety/tenant-isolation",title:"Tenant isolation",description:"Keep tenant data, config, policies, and integrations separated at runtime.",section:"operate",order:60,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/knowledge",title:"Knowledge and context",description:"Bind trusted knowledge sources to the system without losing governance or isolation.",section:"operate",order:70,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/advanced/telemetry",title:"Telemetry",description:"Instrument surfaces, collect evidence, and keep observability aligned with the contract model.",section:"operate",order:80,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/advanced/workflow-monitoring",title:"Workflow monitoring",description:"Observe multi-step execution with enough context to understand failures and regressions.",section:"operate",order:90,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/ops/distributed-tracing",title:"Distributed tracing",description:"Trace contract execution across integrations, workflows, and generated surfaces.",section:"operate",order:100,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/integrations",title:"Integrations overview",description:"Understand the binding model for external services, providers, and tenant-owned connections.",section:"integrations",order:10,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/integrations/spec-model",title:"Integration spec model",description:"Define what an integration provides before wiring it into an app or runtime.",section:"integrations",order:20,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/integrations/openai",title:"OpenAI integration",description:"Connect OpenAI through typed capabilities, explicit provider config, and governed runtime usage.",section:"integrations",order:30,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/integrations/mistral",title:"Mistral integration",description:"Use Mistral through the same provider contract model and runtime guardrails.",section:"integrations",order:40,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/integrations/qdrant",title:"Qdrant integration",description:"Store and retrieve knowledge embeddings with explicit provider configuration and ownership.",section:"integrations",order:50,primaryNav:!0,audience:"operator",ctaMode:"oss-next"},{href:"/docs/integrations/stripe",title:"Stripe integration",description:"Bind payments and billing behavior without smearing provider logic across the codebase.",section:"integrations",order:60,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/integrations/twilio",title:"Twilio integration",description:"Handle messaging and telephony through typed transport boundaries and explicit configuration.",section:"integrations",order:70,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/integrations/github",title:"GitHub integration",description:"Push execution context into GitHub workflows and automation surfaces without hidden glue.",section:"integrations",order:80,primaryNav:!0,audience:"oss",ctaMode:"oss-next"},{href:"/docs/reference",title:"Contract reference",description:"Browse the generated reference index for public contract surfaces, versions, and examples.",section:"reference",order:10,primaryNav:!0,audience:"reference",ctaMode:"reference"},{href:"/docs/examples",title:"Examples",description:"Explore runnable examples and use them as reference implementations for new systems.",section:"reference",order:20,primaryNav:!0,audience:"reference",ctaMode:"reference"},{href:"/docs/studio",title:"Studio overview",description:"See what Studio adds on top of OSS ContractSpec and when a team should adopt the operating layer.",section:"studio",order:10,primaryNav:!0,audience:"studio-bridge",ctaMode:"studio-bridge"},{href:"/docs/manifesto",title:"Manifesto",description:"Why ContractSpec is built as an open system, how incremental adoption works, and why Studio stays additive.",audience:"secondary"},{href:"/docs/intent/contract-first-api",title:"Contract-first API",description:"Use contracts as the durable source of truth for API behavior and generated surfaces.",audience:"secondary"},{href:"/docs/intent/spec-driven-development",title:"Spec-driven development",description:"See how explicit specs stabilize change across APIs, UI, data, and agent-facing surfaces.",audience:"secondary"},{href:"/docs/intent/deterministic-codegen",title:"Deterministic regeneration",description:"Understand safe regeneration, conflict boundaries, and why teams keep control of the output.",audience:"secondary"},{href:"/docs/intent/schema-validation-typescript",title:"Schema validation and TypeScript",description:"Keep schema, runtime validation, and TypeScript behavior aligned without duplicate work.",audience:"secondary"},{href:"/docs/intent/openapi-alternative",title:"OpenAPI alternative",description:"Compare a multi-surface contract system with API-only description tooling.",audience:"secondary"},{href:"/docs/intent/generate-client-from-schema",title:"Generate client from schema",description:"Generate client-facing artifacts from the same source that drives runtime behavior.",audience:"secondary"},{href:"/docs/comparison",title:"Comparison overview",description:"Compare ContractSpec with workflow engines, internal-tool builders, and enterprise orchestration products.",audience:"secondary"},{href:"/docs/comparison/workflow-engines",title:"Workflow engines",description:"Contrast a contract system with workflow-only orchestration approaches.",audience:"secondary"},{href:"/docs/comparison/internal-tool-builders",title:"Internal-tool builders",description:"Compare ContractSpec with builders that optimize for screens instead of durable system contracts.",audience:"secondary"},{href:"/docs/comparison/automation-platforms",title:"Automation platforms",description:"Compare automation-first tools with a system that owns explicit contracts and generated surfaces.",audience:"secondary"},{href:"/docs/comparison/windmill",title:"Windmill comparison",description:"Understand where Windmill fits and where ContractSpec solves a different class of system problem.",audience:"secondary"},{href:"/docs/comparison/enterprise-platforms",title:"Enterprise orchestrators",description:"Compare ContractSpec with enterprise platforms that centralize execution in a closed operating surface.",audience:"secondary"},{href:"/docs/ecosystem/templates",title:"Templates",description:"Use templates and starter systems as proof points and accelerators for OSS adoption.",audience:"secondary"},{href:"/docs/ecosystem/plugins",title:"Plugins",description:"Explore marketplace and editor integrations that support the OSS workflow.",audience:"secondary"},{href:"/docs/ecosystem/registry",title:"Registry",description:"Inspect registry and manifest concepts that help package reusable capability surfaces.",audience:"secondary"}];function EN(e){return sr.find((t)=>t.href===e)}function ep(){return zr.map((e)=>({...e,items:sr.filter((t)=>t.section===e.key&&t.primaryNav).sort((t,a)=>(t.order??0)-(a.order??0))}))}function tp(){return sr.filter((e)=>e.primaryNav).sort((e,t)=>zr.findIndex((a)=>a.key===e.section)-zr.findIndex((a)=>a.key===t.section)||(e.order??0)-(t.order??0))}function ON(e){let t=tp(),a=t.findIndex((r)=>r.href===e);if(a<0)return{previous:null,next:null};return{previous:t[a-1]??null,next:t[a+1]??null}}function yc(){return sr.filter((e)=>e.audience==="secondary")}function bc(){return ep().map((e)=>({...e,featured:e.items.slice(0,3)}))}import{CodeBlock as ap}from"@contractspec/lib.design-system";import Vo from"@contractspec/lib.ui-link";import{ArrowRight as Gr,Boxes as vc,FileSearch as op,ShieldCheck as ip,Waypoints as rp}from"lucide-react";import{jsx as A,jsxs as se}from"react/jsx-runtime";var np=[{title:"One system, many surfaces",body:"Define explicit contracts once, then keep APIs, UI, data, events, and agent-facing surfaces aligned.",icon:vc},{title:"Incremental adoption",body:"Start with one endpoint, one workflow, or one unsafe module. You do not need a rewrite to begin.",icon:rp},{title:"Operator-grade controls",body:"Carry policy, auditability, migrations, tracing, and integration boundaries forward with the same system model.",icon:ip}],cp=[{title:"ContractSpec Connect",body:"Guard coding-agent edits and commands with local-first context, plan packets, patch verdicts, and review packets.",specHref:"/docs/specs/connect",guideHref:"/docs/guides/connect-in-a-repo"},{title:"Module bundles",body:"Define AI-native surfaces as typed bundle specs that resolve into auditable runtime plans.",specHref:"/docs/specs/module-bundles",guideHref:"/docs/guides/first-module-bundle"},{title:"Builder control plane",body:"Coordinate multimodal authoring, provider routing, readiness, export, and mobile review through governed contracts.",specHref:"/docs/specs/builder-control-plane",guideHref:"/docs/guides/host-builder-workbench"}];function lp(){let e=bc(),t=yc().slice(0,6);return se("div",{className:"space-y-12",children:[se("section",{className:"space-y-6",children:[A("p",{className:"editorial-kicker",children:"OSS documentation"}),A("h1",{className:"editorial-title max-w-5xl",children:"Build AI-native systems on explicit contracts, then add Studio when you want the operating layer."}),A("p",{className:"editorial-subtitle",children:"These docs are optimized for OSS adopters first. Learn the contract model, generate and govern surfaces safely, wire integrations, and run the system in production without giving up ownership of your code."}),se("div",{className:"flex flex-wrap gap-3",children:[se(Vo,{href:"/docs/getting-started/start-here",className:"btn-primary text-sm",children:["Start with OSS ",A(Gr,{size:16})]}),A(Vo,{href:"/docs/studio",className:"btn-ghost text-sm",children:"See what Studio adds"})]})]}),A("section",{className:"grid gap-5 md:grid-cols-3",children:np.map((a)=>{let r=a.icon;return se("article",{className:"editorial-panel space-y-3",children:[se("div",{className:"flex items-center gap-3",children:[A("div",{className:"rounded-full border border-border/80 bg-background/85 p-2",children:A(r,{size:18})}),A("h2",{className:"font-semibold text-xl",children:a.title})]}),A("p",{className:"editorial-copy text-sm",children:a.body})]},a.title)})}),se("section",{className:"space-y-5",children:[se("div",{className:"space-y-2",children:[A("p",{className:"editorial-kicker",children:"Implemented packs"}),A("h2",{className:"editorial-panel-title",children:"Use the three higher-order systems that are already wired"}),A("p",{className:"editorial-copy text-sm",children:"These pages are the canonical landing points for agent enforcement, AI-native surface composition, and Builder authoring. Each one now has a matching practical guide."})]}),A("div",{className:"grid gap-4 lg:grid-cols-3",children:cp.map((a)=>se("article",{className:"editorial-panel space-y-4",children:[se("div",{children:[A("h3",{className:"font-semibold text-xl",children:a.title}),A("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:a.body})]}),se("div",{className:"flex flex-wrap gap-3",children:[se(Vo,{href:a.specHref,className:"btn-primary text-sm",children:["Open spec page ",A(Gr,{size:16})]}),A(Vo,{href:a.guideHref,className:"btn-ghost text-sm",children:"Read practical guide"})]})]},a.title))})]}),se("section",{className:"editorial-panel space-y-5",children:[se("div",{className:"space-y-2",children:[A("p",{className:"editorial-kicker",children:"Quick start"}),A("h2",{className:"editorial-panel-title",children:"Start with one contract"}),A("p",{className:"editorial-copy text-sm",children:"Use the CLI and core libraries to define one explicit capability, generate the surface, and validate the contract boundary before you expand."})]}),A(ap,{language:"bash",filename:"docs-quick-start",code:`bun add -D contractspec
|
|
2
2
|
bun add @contractspec/lib.contracts-spec @contractspec/lib.schema
|
|
3
3
|
|
|
4
4
|
contractspec init
|
|
5
5
|
contractspec create --type operation
|
|
6
6
|
contractspec build src/contracts/mySpec.ts
|
|
7
|
-
contractspec validate src/contracts/mySpec.ts`})]}),se("section",{className:"space-y-5",children:[se("div",{className:"space-y-2",children:[A("p",{className:"editorial-kicker",children:"Primary path"}),A("h2",{className:"editorial-panel-title",children:"Move through the system in the right order"}),A("p",{className:"editorial-copy text-sm",children:"Start with onboarding, then learn the model, then build and operate with confidence. The primary docs path is intentionally shorter than the full route inventory."})]}),A("div",{className:"grid gap-5 lg:grid-cols-2",children:e.map((a)=>se("article",{className:"editorial-panel space-y-4",children:[se("div",{children:[A("p",{className:"editorial-kicker",children:a.title}),A("h3",{className:"mt-2 font-serif text-3xl tracking-[-0.03em]",children:a.title}),A("p",{className:"mt-3 text-muted-foreground text-sm leading-7",children:a.description})]}),A("div",{className:"space-y-3",children:a.featured.map((r)=>se(Vo,{href:r.href,className:"flex items-start justify-between gap-4 rounded-[22px] border border-border/70 bg-background/70 p-4 transition-colors hover:border-[color:rgb(162_79_42_/_0.45)]",children:[se("div",{children:[A("h4",{className:"font-semibold text-base",children:r.title}),A("p",{className:"mt-1 text-muted-foreground text-sm leading-6",children:r.description})]}),A(Gr,{className:"mt-1 shrink-0",size:16})]},r.href))})]},a.key))})]}),se("section",{className:"grid gap-5 lg:grid-cols-[1.2fr_0.8fr]",children:[se("article",{className:"editorial-panel space-y-4",children:[se("div",{className:"space-y-2",children:[A("p",{className:"editorial-kicker",children:"Reference and evidence"}),A("h2",{className:"editorial-panel-title",children:"Use generated docs and examples as proof, not just narrative copy"}),A("p",{className:"editorial-copy text-sm",children:"The reference index and example catalog stay close to the repo truth. Use them when you need exact public surfaces, not just the explanatory layer."})]}),se("div",{className:"grid gap-4 md:grid-cols-2",children:[se(Vo,{href:"/docs/reference",className:"docs-footer-link",children:[se("div",{className:"flex items-center gap-2 text-muted-foreground text-sm",children:[A(
|
|
7
|
+
contractspec validate src/contracts/mySpec.ts`})]}),se("section",{className:"space-y-5",children:[se("div",{className:"space-y-2",children:[A("p",{className:"editorial-kicker",children:"Primary path"}),A("h2",{className:"editorial-panel-title",children:"Move through the system in the right order"}),A("p",{className:"editorial-copy text-sm",children:"Start with onboarding, then learn the model, then build and operate with confidence. The primary docs path is intentionally shorter than the full route inventory."})]}),A("div",{className:"grid gap-5 lg:grid-cols-2",children:e.map((a)=>se("article",{className:"editorial-panel space-y-4",children:[se("div",{children:[A("p",{className:"editorial-kicker",children:a.title}),A("h3",{className:"mt-2 font-serif text-3xl tracking-[-0.03em]",children:a.title}),A("p",{className:"mt-3 text-muted-foreground text-sm leading-7",children:a.description})]}),A("div",{className:"space-y-3",children:a.featured.map((r)=>se(Vo,{href:r.href,className:"flex items-start justify-between gap-4 rounded-[22px] border border-border/70 bg-background/70 p-4 transition-colors hover:border-[color:rgb(162_79_42_/_0.45)]",children:[se("div",{children:[A("h4",{className:"font-semibold text-base",children:r.title}),A("p",{className:"mt-1 text-muted-foreground text-sm leading-6",children:r.description})]}),A(Gr,{className:"mt-1 shrink-0",size:16})]},r.href))})]},a.key))})]}),se("section",{className:"grid gap-5 lg:grid-cols-[1.2fr_0.8fr]",children:[se("article",{className:"editorial-panel space-y-4",children:[se("div",{className:"space-y-2",children:[A("p",{className:"editorial-kicker",children:"Reference and evidence"}),A("h2",{className:"editorial-panel-title",children:"Use generated docs and examples as proof, not just narrative copy"}),A("p",{className:"editorial-copy text-sm",children:"The reference index and example catalog stay close to the repo truth. Use them when you need exact public surfaces, not just the explanatory layer."})]}),se("div",{className:"grid gap-4 md:grid-cols-2",children:[se(Vo,{href:"/docs/reference",className:"docs-footer-link",children:[se("div",{className:"flex items-center gap-2 text-muted-foreground text-sm",children:[A(op,{size:16}),A("span",{children:"Reference index"})]}),A("p",{className:"text-muted-foreground text-sm",children:"Search generated contract docs, versions, tags, and visibility metadata."})]}),se(Vo,{href:"/docs/examples",className:"docs-footer-link",children:[se("div",{className:"flex items-center gap-2 text-muted-foreground text-sm",children:[A(vc,{size:16}),A("span",{children:"Examples"})]}),A("p",{className:"text-muted-foreground text-sm",children:"Browse runnable examples and follow the reference routes back to their source artifacts."})]})]})]}),se("article",{className:"editorial-panel space-y-4",children:[se("div",{className:"space-y-2",children:[A("p",{className:"editorial-kicker",children:"Secondary reading"}),A("h2",{className:"editorial-panel-title",children:"Why ContractSpec"}),A("p",{className:"editorial-copy text-sm",children:"Positioning, comparisons, and philosophy remain available, but they no longer define the main docs path."})]}),A("div",{className:"flex flex-wrap gap-2",children:t.map((a)=>A(Vo,{href:a.href,className:"docs-chip-link",children:a.title},a.href))})]})]})]})}import qi from"@contractspec/lib.ui-link";import{ChevronRight as dp}from"lucide-react";import{jsx as B,jsxs as ft}from"react/jsx-runtime";function VN(){return ft("div",{className:"space-y-8",children:[ft("div",{className:"space-y-4",children:[B("h1",{className:"font-bold text-4xl",children:"MCP Adapters"}),ft("p",{className:"text-muted-foreground",children:["The ",B("strong",{children:"Model Context Protocol (MCP)"})," is an open standard for connecting AI models to external tools and data sources. ContractSpec provides MCP adapters that allow you to expose your capabilities as MCP tools and consume external MCP servers as capabilities."]})]}),ft("div",{className:"space-y-4",children:[B("h2",{className:"font-bold text-2xl",children:"Why MCP integration matters"}),B("p",{className:"text-muted-foreground",children:"AI agents need access to real-world tools and data to be useful. MCP provides a standardized way to expose these capabilities. By integrating ContractSpec with MCP, you can:"}),ft("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[B("li",{children:"Let AI agents invoke your ContractSpec capabilities safely and securely"}),B("li",{children:"Use external MCP servers (databases, APIs, search engines) as capability providers in your workflows"}),B("li",{children:"Build AI-powered features without writing custom integration code"}),B("li",{children:"Enforce policies on AI agent actions just like any other user"})]})]}),ft("div",{className:"space-y-4",children:[B("h2",{className:"font-bold text-2xl",children:"Exposing capabilities as MCP tools"}),ft("p",{className:"text-muted-foreground",children:["Any"," ",B(qi,{href:"/docs/specs/capabilities",className:"text-violet-400 hover:text-violet-300",children:"CapabilitySpec"})," ","can be automatically exposed as an MCP tool. ContractSpec generates:"]}),ft("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[B("li",{children:"A tool schema describing the capability's inputs, outputs, and purpose"}),B("li",{children:"An MCP server endpoint that AI agents can connect to"}),B("li",{children:"Policy enforcement ensuring agents can only invoke capabilities they're authorized to use"}),B("li",{children:"Audit logging of all agent actions for compliance and debugging"})]})]}),ft("div",{className:"space-y-4",children:[B("h2",{className:"font-bold text-2xl",children:"Example: Exposing a capability"}),B("p",{className:"text-muted-foreground",children:"Here's how to expose ContractSpec operations as MCP tools:"}),B("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:B("pre",{children:`import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
8
8
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
9
9
|
import { createMcpServer } from '@contractspec/lib.contracts-runtime-server-mcp/provider-mcp';
|
|
10
10
|
import { registry, resources, prompts } from './lib/registry';
|
|
@@ -73,7 +73,7 @@ export const AIAgentRestrictions = definePolicy({
|
|
|
73
73
|
!ctx.approvalGranted,
|
|
74
74
|
},
|
|
75
75
|
],
|
|
76
|
-
});`})})]}),ft("div",{className:"space-y-4",children:[B("h2",{className:"font-bold text-2xl",children:"Human-in-the-loop workflows"}),B("p",{className:"text-muted-foreground",children:"For sensitive operations, you can require human approval before an AI agent can proceed. ContractSpec provides built-in approval workflows:"}),ft("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[B("li",{children:"Agent requests permission to invoke a capability"}),B("li",{children:"Request is sent to designated approvers (via email, Slack, etc.)"}),B("li",{children:"Approver reviews the request and approves or denies it"}),B("li",{children:"Agent receives the decision and can proceed if approved"})]}),ft("p",{className:"text-muted-foreground",children:["All approval decisions are logged in the"," ",B(qi,{href:"/docs/safety/auditing",className:"text-violet-400 hover:text-violet-300",children:"audit log"}),"."]})]}),ft("div",{className:"space-y-4",children:[B("h2",{className:"font-bold text-2xl",children:"Best practices"}),ft("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[B("li",{children:"Start with read-only capabilities for AI agents—only grant write access when necessary."}),B("li",{children:"Use human-in-the-loop approval for any capability that modifies critical data or triggers financial transactions."}),B("li",{children:"Set rate limits to prevent runaway agents from overwhelming your system."}),B("li",{children:"Provide clear, detailed descriptions for each capability so agents know when to use them."}),B("li",{children:"Monitor agent actions closely in production and adjust policies as needed."}),B("li",{children:"Test agent integrations thoroughly with realistic scenarios before deploying."})]})]}),ft("div",{className:"flex items-center gap-4 pt-4",children:[B(qi,{href:"/docs/advanced/renderers",className:"btn-ghost",children:"Previous: Custom Renderers"}),ft(qi,{href:"/docs/advanced/telemetry",className:"btn-primary",children:["Next: Telemetry ",B(
|
|
76
|
+
});`})})]}),ft("div",{className:"space-y-4",children:[B("h2",{className:"font-bold text-2xl",children:"Human-in-the-loop workflows"}),B("p",{className:"text-muted-foreground",children:"For sensitive operations, you can require human approval before an AI agent can proceed. ContractSpec provides built-in approval workflows:"}),ft("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[B("li",{children:"Agent requests permission to invoke a capability"}),B("li",{children:"Request is sent to designated approvers (via email, Slack, etc.)"}),B("li",{children:"Approver reviews the request and approves or denies it"}),B("li",{children:"Agent receives the decision and can proceed if approved"})]}),ft("p",{className:"text-muted-foreground",children:["All approval decisions are logged in the"," ",B(qi,{href:"/docs/safety/auditing",className:"text-violet-400 hover:text-violet-300",children:"audit log"}),"."]})]}),ft("div",{className:"space-y-4",children:[B("h2",{className:"font-bold text-2xl",children:"Best practices"}),ft("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[B("li",{children:"Start with read-only capabilities for AI agents—only grant write access when necessary."}),B("li",{children:"Use human-in-the-loop approval for any capability that modifies critical data or triggers financial transactions."}),B("li",{children:"Set rate limits to prevent runaway agents from overwhelming your system."}),B("li",{children:"Provide clear, detailed descriptions for each capability so agents know when to use them."}),B("li",{children:"Monitor agent actions closely in production and adjust policies as needed."}),B("li",{children:"Test agent integrations thoroughly with realistic scenarios before deploying."})]})]}),ft("div",{className:"flex items-center gap-4 pt-4",children:[B(qi,{href:"/docs/advanced/renderers",className:"btn-ghost",children:"Previous: Custom Renderers"}),ft(qi,{href:"/docs/advanced/telemetry",className:"btn-primary",children:["Next: Telemetry ",B(dp,{size:16})]})]})]})}import sp from"@contractspec/lib.ui-link";import{jsx as ta,jsxs as Ao}from"react/jsx-runtime";function YN(){return Ao("div",{className:"space-y-8",children:[Ao("div",{className:"space-y-4",children:[ta("h1",{className:"font-bold text-4xl",children:"Overlay Editor"}),ta("p",{className:"text-lg text-muted-foreground",children:"A Next.js app (`@contractspec/app.overlay-editor`) that lets tenant admins tweak field visibility, labels, and ordering, then sign OverlaySpecs."})]}),Ao("div",{className:"space-y-4",children:[ta("h2",{className:"font-bold text-2xl",children:"Features"}),Ao("ul",{className:"list-disc space-y-2 pl-6",children:[ta("li",{children:"Toggle visibility and rename labels without touching code."}),ta("li",{children:"Move fields up/down to define the overlay order."}),ta("li",{children:"Preview JSON output powered by `@contractspec/lib.overlay-engine`."}),ta("li",{children:"Server action for PEM signing (Ed25519/RSA-PSS)."})]}),Ao("p",{children:["Project path: ",ta("code",{children:"packages/apps/overlay-editor"})]})]}),Ao("div",{className:"space-y-4",children:[ta("h2",{className:"font-bold text-2xl",children:"Provisioning flow"}),Ao("ol",{className:"list-decimal space-y-2 pl-6",children:[Ao("li",{children:["Clone the repo and run ",ta("code",{children:"bun dev"})," inside the app."]}),ta("li",{children:"Use the UI to craft the overlay for a tenant."}),ta("li",{children:"Paste the tenant's PEM private key (stored in Vault/KMS)."}),ta("li",{children:"Click “Sign overlay” to get the final JSON payload."}),ta("li",{children:"Persist in the `Overlay` table and register with `OverlayRegistry`."})]}),Ao("p",{children:["See also:"," ",ta(sp,{href:"/docs/ops/tenant-customization",className:"text-violet-400 underline",children:"Tenant customization runbook"}),"."]})]})]})}import pp from"@contractspec/lib.ui-link";import{ChevronRight as mp}from"lucide-react";import{jsx as aa,jsxs as mo}from"react/jsx-runtime";function xN(){return mo("div",{className:"space-y-8",children:[mo("div",{className:"space-y-2",children:[aa("h1",{className:"font-bold text-4xl",children:"Custom Renderers"}),aa("p",{className:"text-lg text-muted-foreground",children:"ContractSpec ships with React and React Native renderers. You can build custom renderers for any framework."})]}),mo("div",{className:"space-y-6",children:[mo("div",{className:"space-y-3",children:[aa("h2",{className:"font-bold text-2xl",children:"Overview"}),mo("p",{className:"text-muted-foreground",children:["The presentation runtime libraries (",aa("code",{children:"@contractspec/lib.presentation-runtime-react"})," and",aa("code",{children:"@contractspec/lib.presentation-runtime-react-native"}),") provide hooks and components to render ContractSpec-defined UI like workflows and data views. You can extend these or create custom implementations for other frameworks."]})]}),mo("div",{className:"space-y-3",children:[aa("h2",{className:"font-bold text-2xl",children:"Using the React Renderer"}),aa("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:aa("pre",{children:`import { useWorkflow, WorkflowStepRenderer } from '@contractspec/lib.presentation-runtime-react';
|
|
77
77
|
import { MyWorkflowSpec } from './specs';
|
|
78
78
|
|
|
79
79
|
export function WorkflowPage() {
|
|
@@ -88,7 +88,7 @@ export function WorkflowPage() {
|
|
|
88
88
|
</button>
|
|
89
89
|
</div>
|
|
90
90
|
);
|
|
91
|
-
}`})})]}),mo("div",{className:"space-y-3",children:[aa("h2",{className:"font-bold text-2xl",children:"Custom Platform Support"}),aa("p",{className:"text-muted-foreground",children:"To support a new platform (e.g., Vue, Svelte), you would:"}),mo("ol",{className:"list-inside list-decimal space-y-2 text-muted-foreground",children:[mo("li",{children:["Implement the core workflow state machine (from"," ",aa("code",{children:"@contractspec/lib.presentation-runtime-core"}),")"]}),aa("li",{children:"Create framework-specific hooks/components for step rendering"}),aa("li",{children:"Handle validation and submission via the ContractSpec I/O schemas"})]})]}),aa("div",{className:"flex items-center gap-4 pt-4",children:mo(
|
|
91
|
+
}`})})]}),mo("div",{className:"space-y-3",children:[aa("h2",{className:"font-bold text-2xl",children:"Custom Platform Support"}),aa("p",{className:"text-muted-foreground",children:"To support a new platform (e.g., Vue, Svelte), you would:"}),mo("ol",{className:"list-inside list-decimal space-y-2 text-muted-foreground",children:[mo("li",{children:["Implement the core workflow state machine (from"," ",aa("code",{children:"@contractspec/lib.presentation-runtime-core"}),")"]}),aa("li",{children:"Create framework-specific hooks/components for step rendering"}),aa("li",{children:"Handle validation and submission via the ContractSpec I/O schemas"})]})]}),aa("div",{className:"flex items-center gap-4 pt-4",children:mo(pp,{href:"/docs",className:"btn-primary",children:["Back to docs ",aa(mp,{size:16})]})})]})]})}import{Code as qr,H1 as up,H2 as Hr,H3 as gp,P as Nc}from"@contractspec/lib.design-system/components/typography";import{jsx as eo,jsxs as Si}from"react/jsx-runtime";function aw(){return Si("div",{className:"space-y-8",children:[Si("div",{className:"space-y-4",children:[eo(up,{className:"font-bold text-4xl",children:"Spec Experiments"}),eo(Nc,{className:"text-lg text-muted-foreground",children:"Run controlled experiments on ContractSpec operations, gradually shift traffic, and roll back automatically when guardrails trip."})]}),Si("div",{className:"space-y-3",children:[eo(Hr,{className:"font-bold text-2xl",children:"Define control + variants"}),eo(qr,{className:"rounded-lg border bg-muted p-4 text-sm",children:`import { SpecExperimentRegistry } from '@contractspec/lib.growth/spec-experiments';
|
|
92
92
|
|
|
93
93
|
const registry = new SpecExperimentRegistry().register({
|
|
94
94
|
target: { name: 'billing.createInvoice', version: 4 },
|
|
@@ -108,12 +108,12 @@ const registry = new SpecExperimentRegistry().register({
|
|
|
108
108
|
],
|
|
109
109
|
rolloutStages: [0.01, 0.1, 0.5, 1],
|
|
110
110
|
guardrails: { errorRateThreshold: 0.02, latencyP99ThresholdMs: 500 },
|
|
111
|
-
});`})]}),Si("div",{className:"space-y-3",children:[eo(
|
|
111
|
+
});`})]}),Si("div",{className:"space-y-3",children:[eo(Hr,{className:"font-bold text-2xl",children:"Attach to runtime"}),eo(qr,{className:"rounded-lg border bg-muted p-4 text-sm",children:`import { createSpecVariantResolver } from '@contractspec/lib.growth/spec-experiments';
|
|
112
112
|
|
|
113
113
|
adapterContext.specVariantResolver = createSpecVariantResolver({
|
|
114
114
|
adapter,
|
|
115
115
|
resolveUserId: (ctx) => ctx.userId ?? ctx.organizationId ?? 'anon',
|
|
116
|
-
});`})]}),Si("div",{className:"space-y-3",children:[eo(
|
|
116
|
+
});`})]}),Si("div",{className:"space-y-3",children:[eo(Hr,{className:"font-bold text-2xl",children:"Track outcomes + auto-rollback"}),eo(qr,{className:"rounded-lg border bg-muted p-4 text-sm",children:`import {
|
|
117
117
|
SpecExperimentAnalyzer,
|
|
118
118
|
SpecExperimentController,
|
|
119
119
|
} from '@contractspec/lib.growth/spec-experiments';
|
|
@@ -123,7 +123,7 @@ const controller = new SpecExperimentController({
|
|
|
123
123
|
registry,
|
|
124
124
|
analyzer,
|
|
125
125
|
onRollback: (target, evaluation) => notifyOps(target, evaluation.reasons),
|
|
126
|
-
});`})]}),eo("div",{className:"grid gap-4 md:grid-cols-2",children:[{title:"Deterministic bucketing",description:"ExperimentRunner reuses the same hashing logic as growth experiments—every user sticks to a variant."},{title:"Multi-stage rollouts",description:"Use `rolloutStages` to shift 1% → 10% → 50% → 100%. Guardrails trigger rollbacks automatically."}].map((e)=>Si("div",{className:"card-subtle space-y-2 p-4",children:[eo(
|
|
126
|
+
});`})]}),eo("div",{className:"grid gap-4 md:grid-cols-2",children:[{title:"Deterministic bucketing",description:"ExperimentRunner reuses the same hashing logic as growth experiments—every user sticks to a variant."},{title:"Multi-stage rollouts",description:"Use `rolloutStages` to shift 1% → 10% → 50% → 100%. Guardrails trigger rollbacks automatically."}].map((e)=>Si("div",{className:"card-subtle space-y-2 p-4",children:[eo(gp,{className:"font-semibold text-lg",children:e.title}),eo(Nc,{className:"text-muted-foreground text-sm",children:e.description})]},e.title))})]})}import wc from"@contractspec/lib.ui-link";import{ChevronRight as fp}from"lucide-react";import{jsx as T,jsxs as F}from"react/jsx-runtime";function cw(){return F("div",{className:"space-y-8",children:[F("div",{className:"space-y-4",children:[T("h1",{className:"font-bold text-4xl",children:"Telemetry"}),F("p",{className:"text-muted-foreground",children:["A ",T("strong",{children:"TelemetrySpec"})," defines what metrics, logs, and traces to collect for observability. ContractSpec automatically instruments your application based on these specs, ensuring you have the visibility you need to monitor, debug, and optimize your system."]})]}),F("div",{className:"space-y-4",children:[T("h2",{className:"font-bold text-2xl",children:"Why telemetry matters"}),T("p",{className:"text-muted-foreground",children:"You can't fix what you can't see. Telemetry provides visibility into how your application is performing, where errors are occurring, and how users are interacting with your system. Without proper instrumentation, you're flying blind in production."}),T("p",{className:"text-muted-foreground",children:"ContractSpec takes a spec-first approach to telemetry: you declare what you want to observe, and runtime adapters instrument operations automatically. This ensures consistent, comprehensive coverage without manual effort."})]}),F("div",{className:"space-y-4",children:[T("h2",{className:"font-bold text-2xl",children:"Three pillars of observability"}),F("div",{className:"space-y-3",children:[F("div",{children:[T("h3",{className:"font-semibold text-lg",children:"Metrics"}),T("p",{className:"text-muted-foreground",children:"Numerical measurements collected over time. Examples: request count, error rate, latency percentiles, active users, queue depth. Metrics are cheap to collect and store, making them ideal for high-level monitoring and alerting."})]}),F("div",{children:[T("h3",{className:"font-semibold text-lg",children:"Logs"}),T("p",{className:"text-muted-foreground",children:'Timestamped text records of events. Examples: "User 123 logged in", "Payment failed for order 456", "Database connection pool exhausted". Logs provide detailed context for debugging specific issues.'})]}),F("div",{children:[T("h3",{className:"font-semibold text-lg",children:"Traces"}),T("p",{className:"text-muted-foreground",children:"Records of requests as they flow through your system. A trace shows the complete path of a request—which services it touched, how long each step took, and where errors occurred. Traces are essential for debugging distributed systems."})]})]})]}),F("div",{className:"space-y-4",children:[T("h2",{className:"font-bold text-2xl",children:"Example TelemetrySpec"}),T("p",{className:"text-muted-foreground",children:"Here's how telemetry is configured in TypeScript:"}),T("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:T("pre",{children:`import { defineTelemetry } from '@contractspec/lib.contracts-spec/telemetry';
|
|
127
127
|
|
|
128
128
|
export const OrderProcessingTelemetry = defineTelemetry({
|
|
129
129
|
meta: {
|
|
@@ -168,7 +168,7 @@ export const OrderProcessingTelemetry = defineTelemetry({
|
|
|
168
168
|
notify: ['pagerduty', 'slack'],
|
|
169
169
|
},
|
|
170
170
|
],
|
|
171
|
-
});`})})]}),F("div",{className:"space-y-4",children:[T("h2",{className:"font-bold text-2xl",children:"Automatic instrumentation"}),T("p",{className:"text-muted-foreground",children:"ContractSpec automatically instruments:"}),F("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[F("li",{children:[T("strong",{children:"All operations"})," – Request count, latency, error rate per Command/Query"]}),F("li",{children:[T("strong",{children:"All workflows"})," – Step execution time, retry counts, compensation events"]}),F("li",{children:[T("strong",{children:"All data views"})," – Query execution time, result set size"]}),F("li",{children:[T("strong",{children:"All policy decisions"})," – Decision time, permit/deny ratio"]}),F("li",{children:[T("strong",{children:"System resources"})," – CPU, memory, disk, network usage"]})]}),T("p",{className:"text-muted-foreground",children:"You don't need to add instrumentation code manually—the runtime handles it based on your specs."})]}),F("div",{className:"space-y-4",children:[T("h2",{className:"font-bold text-2xl",children:"Integration with observability platforms"}),T("p",{className:"text-muted-foreground",children:"ContractSpec supports multiple observability backends:"}),F("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[F("li",{children:[T("strong",{children:"Prometheus"})," – For metrics collection and alerting"]}),F("li",{children:[T("strong",{children:"Grafana"})," – For dashboards and visualization"]}),F("li",{children:[T("strong",{children:"Jaeger / Tempo"})," – For distributed tracing"]}),F("li",{children:[T("strong",{children:"Loki"})," – For log aggregation"]}),F("li",{children:[T("strong",{children:"Datadog"})," – All-in-one observability platform"]}),F("li",{children:[T("strong",{children:"New Relic"})," – Application performance monitoring"]}),F("li",{children:[T("strong",{children:"Honeycomb"})," – Observability for complex systems"]})]}),T("p",{className:"text-muted-foreground",children:"You can configure multiple backends and send telemetry to all of them simultaneously."})]}),F("div",{className:"space-y-4",children:[T("h2",{className:"font-bold text-2xl",children:"Sampling and performance"}),T("p",{className:"text-muted-foreground",children:"Collecting telemetry has a cost—CPU, memory, network bandwidth, and storage. ContractSpec provides several mechanisms to control overhead:"}),F("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[F("li",{children:[T("strong",{children:"Sampling"})," – Trace only a percentage of requests (e.g., 10%)"]}),F("li",{children:[T("strong",{children:"Adaptive sampling"})," – Automatically reduce sampling rate under high load"]}),F("li",{children:[T("strong",{children:"Tail-based sampling"})," – Keep traces for failed requests, sample successful ones"]}),F("li",{children:[T("strong",{children:"Field redaction"})," – Remove sensitive data from traces and logs"]}),F("li",{children:[T("strong",{children:"Aggregation"})," – Pre-aggregate metrics before sending to reduce network traffic"]})]})]}),F("div",{className:"space-y-4",children:[T("h2",{className:"font-bold text-2xl",children:"Best practices"}),F("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[T("li",{children:"Start with high-level metrics (request rate, error rate, latency) and add more detailed instrumentation as needed."}),T("li",{children:"Use structured logging—log events with structured fields, not free-form text."}),T("li",{children:"Set up alerts for critical metrics so you're notified when things go wrong."}),T("li",{children:"Use traces to debug complex issues—they show the complete picture of a request."}),T("li",{children:"Redact sensitive data from logs and traces to comply with privacy regulations."}),T("li",{children:"Review dashboards regularly to understand normal behavior—this makes anomalies easier to spot."}),T("li",{children:"Use sampling to control costs, but always trace errors and slow requests."})]})]}),F("div",{className:"flex items-center gap-4 pt-4",children:[T(
|
|
171
|
+
});`})})]}),F("div",{className:"space-y-4",children:[T("h2",{className:"font-bold text-2xl",children:"Automatic instrumentation"}),T("p",{className:"text-muted-foreground",children:"ContractSpec automatically instruments:"}),F("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[F("li",{children:[T("strong",{children:"All operations"})," – Request count, latency, error rate per Command/Query"]}),F("li",{children:[T("strong",{children:"All workflows"})," – Step execution time, retry counts, compensation events"]}),F("li",{children:[T("strong",{children:"All data views"})," – Query execution time, result set size"]}),F("li",{children:[T("strong",{children:"All policy decisions"})," – Decision time, permit/deny ratio"]}),F("li",{children:[T("strong",{children:"System resources"})," – CPU, memory, disk, network usage"]})]}),T("p",{className:"text-muted-foreground",children:"You don't need to add instrumentation code manually—the runtime handles it based on your specs."})]}),F("div",{className:"space-y-4",children:[T("h2",{className:"font-bold text-2xl",children:"Integration with observability platforms"}),T("p",{className:"text-muted-foreground",children:"ContractSpec supports multiple observability backends:"}),F("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[F("li",{children:[T("strong",{children:"Prometheus"})," – For metrics collection and alerting"]}),F("li",{children:[T("strong",{children:"Grafana"})," – For dashboards and visualization"]}),F("li",{children:[T("strong",{children:"Jaeger / Tempo"})," – For distributed tracing"]}),F("li",{children:[T("strong",{children:"Loki"})," – For log aggregation"]}),F("li",{children:[T("strong",{children:"Datadog"})," – All-in-one observability platform"]}),F("li",{children:[T("strong",{children:"New Relic"})," – Application performance monitoring"]}),F("li",{children:[T("strong",{children:"Honeycomb"})," – Observability for complex systems"]})]}),T("p",{className:"text-muted-foreground",children:"You can configure multiple backends and send telemetry to all of them simultaneously."})]}),F("div",{className:"space-y-4",children:[T("h2",{className:"font-bold text-2xl",children:"Sampling and performance"}),T("p",{className:"text-muted-foreground",children:"Collecting telemetry has a cost—CPU, memory, network bandwidth, and storage. ContractSpec provides several mechanisms to control overhead:"}),F("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[F("li",{children:[T("strong",{children:"Sampling"})," – Trace only a percentage of requests (e.g., 10%)"]}),F("li",{children:[T("strong",{children:"Adaptive sampling"})," – Automatically reduce sampling rate under high load"]}),F("li",{children:[T("strong",{children:"Tail-based sampling"})," – Keep traces for failed requests, sample successful ones"]}),F("li",{children:[T("strong",{children:"Field redaction"})," – Remove sensitive data from traces and logs"]}),F("li",{children:[T("strong",{children:"Aggregation"})," – Pre-aggregate metrics before sending to reduce network traffic"]})]})]}),F("div",{className:"space-y-4",children:[T("h2",{className:"font-bold text-2xl",children:"Best practices"}),F("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[T("li",{children:"Start with high-level metrics (request rate, error rate, latency) and add more detailed instrumentation as needed."}),T("li",{children:"Use structured logging—log events with structured fields, not free-form text."}),T("li",{children:"Set up alerts for critical metrics so you're notified when things go wrong."}),T("li",{children:"Use traces to debug complex issues—they show the complete picture of a request."}),T("li",{children:"Redact sensitive data from logs and traces to comply with privacy regulations."}),T("li",{children:"Review dashboards regularly to understand normal behavior—this makes anomalies easier to spot."}),T("li",{children:"Use sampling to control costs, but always trace errors and slow requests."})]})]}),F("div",{className:"flex items-center gap-4 pt-4",children:[T(wc,{href:"/docs/advanced/mcp",className:"btn-ghost",children:"Previous: MCP Adapters"}),F(wc,{href:"/docs/comparison",className:"btn-primary",children:["Next: Comparison ",T(fp,{size:16})]})]})]})}import{jsx as Na,jsxs as Fo}from"react/jsx-runtime";function sw(){return Fo("div",{className:"space-y-8",children:[Fo("div",{className:"space-y-4",children:[Na("h1",{className:"font-bold text-4xl",children:"Workflow Monitoring"}),Na("p",{className:"text-lg text-muted-foreground",children:"Production workflows need robust observability. ContractSpec provides SLA monitoring, distributed tracing, and audit logging out of the box."})]}),Fo("div",{className:"space-y-4",children:[Na("h2",{className:"font-bold text-2xl",children:"SLA Monitoring"}),Fo("p",{children:["Use the ",Na("code",{children:"SLAMonitor"})," to detect when workflows or individual steps exceed their budgeted duration."]}),Na("pre",{className:"rounded-lg border bg-muted p-4 text-sm",children:`import { SLAMonitor } from '@contractspec/lib.contracts-spec/workflow/sla-monitor';
|
|
172
172
|
|
|
173
173
|
const monitor = new SLAMonitor((event, payload) => {
|
|
174
174
|
if (event === 'workflow.sla_breach') {
|
|
@@ -178,7 +178,7 @@ const monitor = new SLAMonitor((event, payload) => {
|
|
|
178
178
|
});
|
|
179
179
|
|
|
180
180
|
// Check periodically
|
|
181
|
-
monitor.check(currentState, workflowSpec);`})]}),Fo("div",{className:"space-y-4",children:[Na("h2",{className:"font-bold text-2xl",children:"Telemetry & Tracing"}),Na("p",{children:"Workflows automatically generate OpenTelemetry spans for:"}),Fo("ul",{className:"list-disc space-y-2 pl-6",children:[Na("li",{children:"Overall workflow execution"}),Na("li",{children:"Individual steps"}),Na("li",{children:"Retries and compensation"})]}),Na("p",{children:"Configure your OpenTelemetry exporter to send traces to Jaeger, Datadog, or Honeycomb."})]}),Fo("div",{className:"space-y-4",children:[Na("h2",{className:"font-bold text-2xl",children:"Dashboarding"}),Fo("p",{children:["You can build a custom dashboard using ",Na("code",{children:"DataViews"})," over your workflow state database. See the DataViews tutorial for how to visualize ",Na("code",{children:"WorkflowState"})," records."]})]})]})}import{CodeBlock as Hi}from"@contractspec/lib.design-system";import
|
|
181
|
+
monitor.check(currentState, workflowSpec);`})]}),Fo("div",{className:"space-y-4",children:[Na("h2",{className:"font-bold text-2xl",children:"Telemetry & Tracing"}),Na("p",{children:"Workflows automatically generate OpenTelemetry spans for:"}),Fo("ul",{className:"list-disc space-y-2 pl-6",children:[Na("li",{children:"Overall workflow execution"}),Na("li",{children:"Individual steps"}),Na("li",{children:"Retries and compensation"})]}),Na("p",{children:"Configure your OpenTelemetry exporter to send traces to Jaeger, Datadog, or Honeycomb."})]}),Fo("div",{className:"space-y-4",children:[Na("h2",{className:"font-bold text-2xl",children:"Dashboarding"}),Fo("p",{children:["You can build a custom dashboard using ",Na("code",{children:"DataViews"})," over your workflow state database. See the DataViews tutorial for how to visualize ",Na("code",{children:"WorkflowState"})," records."]})]})]})}import{CodeBlock as Hi}from"@contractspec/lib.design-system";import kc from"@contractspec/lib.ui-link";import{ChevronRight as hp}from"lucide-react";import{jsx as ie,jsxs as at}from"react/jsx-runtime";function yp(){return at("div",{className:"space-y-8",children:[at("div",{className:"space-y-4",children:[ie("h1",{className:"font-bold text-4xl",children:"App Configuration"}),ie("p",{className:"text-muted-foreground",children:"ContractSpec uses a three-tier configuration model that separates global app definitions from tenant-specific settings and runtime resolution."})]}),at("div",{className:"space-y-4",children:[ie("h2",{className:"font-bold text-2xl",children:"AppBlueprintSpec"}),at("p",{className:"text-muted-foreground",children:["The ",ie("strong",{children:"AppBlueprintSpec"})," is the global, versioned definition of your application. It contains no tenant-specific information and is stored in version control."]}),ie(Hi,{language:"typescript",code:`type AppBlueprintSpec = {
|
|
182
182
|
id: string;
|
|
183
183
|
version: string;
|
|
184
184
|
name: string;
|
|
@@ -323,7 +323,7 @@ monitor.check(currentState, workflowSpec);`})]}),Fo("div",{className:"space-y-4"
|
|
|
323
323
|
knowledge: ResolvedKnowledge[]; // [{ binding, space, sources }]
|
|
324
324
|
branding: ResolvedBranding; // { appName, assets, colors, domain }
|
|
325
325
|
notes?: string;
|
|
326
|
-
};`})]}),at("div",{className:"space-y-4",children:[ie("h2",{className:"font-bold text-2xl",children:"Configuration flow"}),ie("p",{className:"text-muted-foreground",children:"Here's how configuration flows from definition to runtime:"}),at("ol",{className:"list-inside list-decimal space-y-3 text-muted-foreground",children:[at("li",{children:[ie("strong",{children:"Development"})," - Define AppBlueprintSpec with required integrations and knowledge spaces"]}),at("li",{children:[ie("strong",{children:"Deployment"})," - Deploy blueprint to environment (sandbox, staging, production)"]}),at("li",{children:[ie("strong",{children:"Tenant Setup"})," - Create TenantAppConfig with specific integration connections and knowledge sources"]}),at("li",{children:[ie("strong",{children:"Runtime"})," - Resolve configuration on-demand when tenant accesses the app"]}),at("li",{children:[ie("strong",{children:"Execution"})," - Use ResolvedAppConfig to execute capabilities, workflows, and enforce policies"]})]})]}),at("div",{className:"space-y-4",children:[ie("h2",{className:"font-bold text-2xl",children:"Best practices"}),at("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[ie("li",{children:"Keep AppBlueprintSpec environment-agnostic - no secrets or tenant-specific data"}),ie("li",{children:"Use TenantAppConfig for all tenant-specific settings and connections"}),ie("li",{children:"Cache ResolvedAppConfig per request to avoid repeated resolution"}),ie("li",{children:"Version blueprints carefully - migrations affect all tenants"}),ie("li",{children:"Test blueprint changes in sandbox before promoting to production"})]})]}),at("div",{className:"flex items-center gap-4 pt-4",children:[ie(
|
|
326
|
+
};`})]}),at("div",{className:"space-y-4",children:[ie("h2",{className:"font-bold text-2xl",children:"Configuration flow"}),ie("p",{className:"text-muted-foreground",children:"Here's how configuration flows from definition to runtime:"}),at("ol",{className:"list-inside list-decimal space-y-3 text-muted-foreground",children:[at("li",{children:[ie("strong",{children:"Development"})," - Define AppBlueprintSpec with required integrations and knowledge spaces"]}),at("li",{children:[ie("strong",{children:"Deployment"})," - Deploy blueprint to environment (sandbox, staging, production)"]}),at("li",{children:[ie("strong",{children:"Tenant Setup"})," - Create TenantAppConfig with specific integration connections and knowledge sources"]}),at("li",{children:[ie("strong",{children:"Runtime"})," - Resolve configuration on-demand when tenant accesses the app"]}),at("li",{children:[ie("strong",{children:"Execution"})," - Use ResolvedAppConfig to execute capabilities, workflows, and enforce policies"]})]})]}),at("div",{className:"space-y-4",children:[ie("h2",{className:"font-bold text-2xl",children:"Best practices"}),at("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[ie("li",{children:"Keep AppBlueprintSpec environment-agnostic - no secrets or tenant-specific data"}),ie("li",{children:"Use TenantAppConfig for all tenant-specific settings and connections"}),ie("li",{children:"Cache ResolvedAppConfig per request to avoid repeated resolution"}),ie("li",{children:"Version blueprints carefully - migrations affect all tenants"}),ie("li",{children:"Test blueprint changes in sandbox before promoting to production"})]})]}),at("div",{className:"flex items-center gap-4 pt-4",children:[ie(kc,{href:"/docs/architecture",className:"btn-ghost",children:"Back to Architecture"}),at(kc,{href:"/docs/architecture/integration-binding",className:"btn-primary",children:["Integration Binding ",ie(hp,{size:16})]})]})]})}import{CodeBlock as Sc}from"@contractspec/lib.design-system";import pr from"@contractspec/lib.ui-link";import{ChevronRight as bp}from"lucide-react";import{jsx as be,jsxs as wa}from"react/jsx-runtime";function vp(){return wa("div",{className:"space-y-8",children:[wa("div",{className:"space-y-4",children:[be("h1",{className:"font-bold text-4xl",children:"Control Plane Runtime"}),be("p",{className:"text-muted-foreground",children:"The control plane is the governance layer for agentic execution. It turns incoming intent into deterministic plans, enforces risk policy before side effects, and records replayable traces for audits."})]}),wa("div",{className:"space-y-4",children:[be("h2",{className:"font-bold text-2xl",children:"Canonical execution loop"}),wa("ol",{className:"list-inside list-decimal space-y-2 text-muted-foreground",children:[be("li",{children:"Accept intent and create execution identity + trace context."}),be("li",{children:"Compile intent into a typed, deterministic plan DAG."}),be("li",{children:"Verify plan against policy and risk rules."}),be("li",{children:"Route into autonomous or assist mode based on verdict."}),be("li",{children:"Execute steps with idempotent keys and explicit stage events."}),be("li",{children:"Persist outcomes for replay, audits, and operator visibility."})]})]}),wa("div",{className:"space-y-4",children:[be("h2",{className:"font-bold text-2xl",children:"Contract surfaces (v1 baseline)"}),wa("p",{className:"text-muted-foreground",children:["The runtime is contract-first. Commands, queries, events, and capabilities are explicit and versioned under",be("code",{children:" @contractspec/lib.contracts-spec"}),"."]}),be(Sc,{language:"text",code:`Commands
|
|
327
327
|
- controlPlane.intent.submit
|
|
328
328
|
- controlPlane.plan.compile
|
|
329
329
|
- controlPlane.plan.verify
|
|
@@ -359,7 +359,7 @@ Capabilities
|
|
|
359
359
|
- control-plane.approval
|
|
360
360
|
- control-plane.audit
|
|
361
361
|
- control-plane.skill-registry
|
|
362
|
-
- control-plane.channel-runtime`})]}),wa("div",{className:"space-y-4",children:[be("h2",{className:"font-bold text-2xl",children:"Policy and safety posture"}),wa("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[be("li",{children:"No side-effect action executes unless it comes from a compiled plan."}),be("li",{children:"High-risk actions are blocked from autonomous mode in v1."}),be("li",{children:"Approval commands provide explicit human-in-the-loop transitions."}),be("li",{children:"Skill installation is modeled as governance-controlled operations."}),be("li",{children:"Trace queries expose policy rationale and step outcomes for replay."})]})]}),wa("section",{className:"editorial-panel space-y-4",children:[be("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Apply the runtime locally with Connect"}),be("p",{className:"text-muted-foreground text-sm leading-7",children:"The control plane defines the governance contracts. Connect is the local adapter that turns those contracts into task-scoped context, plan, verification, review, and replay flows for coding agents."}),wa("div",{className:"flex flex-wrap gap-3",children:[be(pr,{href:"/docs/specs/connect",className:"btn-primary",children:"Connect spec"}),be(pr,{href:"/docs/guides/connect-in-a-repo",className:"btn-ghost",children:"Use Connect in a repo"})]})]}),wa("div",{className:"space-y-4",children:[be("h2",{className:"font-bold text-2xl",children:"Implementation map"}),be(
|
|
362
|
+
- control-plane.channel-runtime`})]}),wa("div",{className:"space-y-4",children:[be("h2",{className:"font-bold text-2xl",children:"Policy and safety posture"}),wa("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[be("li",{children:"No side-effect action executes unless it comes from a compiled plan."}),be("li",{children:"High-risk actions are blocked from autonomous mode in v1."}),be("li",{children:"Approval commands provide explicit human-in-the-loop transitions."}),be("li",{children:"Skill installation is modeled as governance-controlled operations."}),be("li",{children:"Trace queries expose policy rationale and step outcomes for replay."})]})]}),wa("section",{className:"editorial-panel space-y-4",children:[be("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Apply the runtime locally with Connect"}),be("p",{className:"text-muted-foreground text-sm leading-7",children:"The control plane defines the governance contracts. Connect is the local adapter that turns those contracts into task-scoped context, plan, verification, review, and replay flows for coding agents."}),wa("div",{className:"flex flex-wrap gap-3",children:[be(pr,{href:"/docs/specs/connect",className:"btn-primary",children:"Connect spec"}),be(pr,{href:"/docs/guides/connect-in-a-repo",className:"btn-ghost",children:"Use Connect in a repo"})]})]}),wa("div",{className:"space-y-4",children:[be("h2",{className:"font-bold text-2xl",children:"Implementation map"}),be(Sc,{language:"text",code:`packages/libs/contracts-spec/src/control-plane/
|
|
363
363
|
commands/
|
|
364
364
|
queries/
|
|
365
365
|
events/
|
|
@@ -368,7 +368,7 @@ Capabilities
|
|
|
368
368
|
contracts.test.ts
|
|
369
369
|
|
|
370
370
|
packages/apps/web-landing/src/app/docs/architecture/control-plane/page.tsx
|
|
371
|
-
implementation_plan_controle_plane.md`})]}),wa("div",{className:"space-y-4",children:[be("h2",{className:"font-bold text-2xl",children:"What comes next"}),be("p",{className:"text-muted-foreground",children:"WS1 delivers the contract fabric. Next increments add planner/executor split, policy escalation, capability-bound authorization, signed skill compatibility checks, and full replay tooling."})]}),wa("div",{className:"flex items-center gap-4 pt-4",children:[be(pr,{href:"/docs/architecture/integration-binding",className:"btn-ghost",children:"Previous: Integration Binding"}),wa(pr,{href:"/docs/safety/auditing",className:"btn-primary",children:["Audit Logs ",be(
|
|
371
|
+
implementation_plan_controle_plane.md`})]}),wa("div",{className:"space-y-4",children:[be("h2",{className:"font-bold text-2xl",children:"What comes next"}),be("p",{className:"text-muted-foreground",children:"WS1 delivers the contract fabric. Next increments add planner/executor split, policy escalation, capability-bound authorization, signed skill compatibility checks, and full replay tooling."})]}),wa("div",{className:"flex items-center gap-4 pt-4",children:[be(pr,{href:"/docs/architecture/integration-binding",className:"btn-ghost",children:"Previous: Integration Binding"}),wa(pr,{href:"/docs/safety/auditing",className:"btn-primary",children:["Audit Logs ",be(bp,{size:16})]})]})]})}import{CodeBlock as Ci}from"@contractspec/lib.design-system";import Cc from"@contractspec/lib.ui-link";import{ChevronRight as Np}from"lucide-react";import{jsx as K,jsxs as ot}from"react/jsx-runtime";function wp(){return ot("div",{className:"space-y-8",children:[ot("div",{className:"space-y-4",children:[K("h1",{className:"font-bold text-4xl",children:"Integration Binding"}),K("p",{className:"text-muted-foreground",children:"Integration binding connects your app's capabilities to external service providers. Each tenant can configure their own integration connections while sharing the same app blueprint."})]}),ot("div",{className:"space-y-4",children:[K("h2",{className:"font-bold text-2xl",children:"How it works"}),K("p",{className:"text-muted-foreground",children:"Integration binding follows a three-layer model:"}),ot("ol",{className:"list-inside list-decimal space-y-3 text-muted-foreground",children:[ot("li",{children:[K("strong",{children:"IntegrationSpec"})," (global) - Defines what an integration provides"]}),ot("li",{children:[K("strong",{children:"IntegrationConnection"})," (per-tenant) - A tenant's configured connection"]}),ot("li",{children:[K("strong",{children:"AppIntegrationBinding"})," (per-app) - Maps named slots to concrete tenant connections"]})]})]}),ot("div",{className:"space-y-4",children:[K("h2",{className:"font-bold text-2xl",children:"Example: Payment processing"}),K("p",{className:"text-muted-foreground",children:"Let's walk through a complete example of binding Stripe for payments."}),ot("div",{className:"space-y-3",children:[K("h3",{className:"font-semibold text-lg",children:"Step 1: Blueprint declares requirement"}),K(Ci,{language:"typescript",code:`// AppBlueprintSpec
|
|
372
372
|
{
|
|
373
373
|
meta: { name: "invoice-app", version: '1.0.0', appId: "invoice" },
|
|
374
374
|
integrationSlots: [
|
|
@@ -501,7 +501,7 @@ const result = await executeCapability(
|
|
|
501
501
|
connectionId: "conn_stripe_acme_prod"
|
|
502
502
|
}
|
|
503
503
|
]
|
|
504
|
-
}`})]}),ot("div",{className:"space-y-4",children:[K("h2",{className:"font-bold text-2xl",children:"Security & validation"}),ot("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[K("li",{children:"Integration connections are validated before binding - health checks ensure connectivity"}),K("li",{children:"Secrets are never stored in TenantAppConfig - only references to encrypted secrets"}),K("li",{children:"Policy Decision Point (PDP) enforces which workflows can use which integrations"}),K("li",{children:"All integration calls are audited with full request/response logging"}),K("li",{children:"Rate limiting and quotas are enforced per connection"})]})]}),ot("div",{className:"space-y-4",children:[K("h2",{className:"font-bold text-2xl",children:"Best practices"}),ot("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[ot("li",{children:["Use wildcard patterns sparingly in ",K("code",{children:"allowedWorkflows"})," - be explicit about access"]}),K("li",{children:"Always maintain separate sandbox and production connections"}),K("li",{children:"Monitor integration health checks and set up alerts for failures"}),K("li",{children:"Document the purpose of each integration binding for your team"}),K("li",{children:"Test integration changes in sandbox before promoting to production"})]})]}),ot("div",{className:"flex items-center gap-4 pt-4",children:[K(
|
|
504
|
+
}`})]}),ot("div",{className:"space-y-4",children:[K("h2",{className:"font-bold text-2xl",children:"Security & validation"}),ot("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[K("li",{children:"Integration connections are validated before binding - health checks ensure connectivity"}),K("li",{children:"Secrets are never stored in TenantAppConfig - only references to encrypted secrets"}),K("li",{children:"Policy Decision Point (PDP) enforces which workflows can use which integrations"}),K("li",{children:"All integration calls are audited with full request/response logging"}),K("li",{children:"Rate limiting and quotas are enforced per connection"})]})]}),ot("div",{className:"space-y-4",children:[K("h2",{className:"font-bold text-2xl",children:"Best practices"}),ot("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[ot("li",{children:["Use wildcard patterns sparingly in ",K("code",{children:"allowedWorkflows"})," - be explicit about access"]}),K("li",{children:"Always maintain separate sandbox and production connections"}),K("li",{children:"Monitor integration health checks and set up alerts for failures"}),K("li",{children:"Document the purpose of each integration binding for your team"}),K("li",{children:"Test integration changes in sandbox before promoting to production"})]})]}),ot("div",{className:"flex items-center gap-4 pt-4",children:[K(Cc,{href:"/docs/architecture/app-config",className:"btn-ghost",children:"Previous: App Configuration"}),ot(Cc,{href:"/docs/architecture/knowledge-binding",className:"btn-primary",children:["Knowledge Binding ",K(Np,{size:16})]})]})]})}import{CodeBlock as Vi}from"@contractspec/lib.design-system";import Ic from"@contractspec/lib.ui-link";import{ChevronRight as kp}from"lucide-react";import{jsx as y,jsxs as ve}from"react/jsx-runtime";function Sp(){return ve("div",{className:"space-y-8",children:[ve("div",{className:"space-y-4",children:[y("h1",{className:"font-bold text-4xl",children:"Knowledge Binding"}),y("p",{className:"text-muted-foreground",children:"Knowledge binding connects your app's workflows and agents to structured knowledge spaces. This enables semantic search, RAG (Retrieval-Augmented Generation), and context-aware decision-making."})]}),ve("div",{className:"space-y-4",children:[y("h2",{className:"font-bold text-2xl",children:"How it works"}),y("p",{className:"text-muted-foreground",children:"Knowledge binding follows a three-layer model:"}),ve("ol",{className:"list-inside list-decimal space-y-3 text-muted-foreground",children:[ve("li",{children:[y("strong",{children:"KnowledgeSpaceSpec"})," (global) - Defines a logical knowledge domain"]}),ve("li",{children:[y("strong",{children:"KnowledgeSourceConfig"})," (per-tenant) - Tenant's data sources feeding spaces"]}),ve("li",{children:[y("strong",{children:"AppKnowledgeBinding"})," (per-app) - Maps spaces to workflows/agents"]})]})]}),ve("div",{className:"space-y-4",children:[y("h2",{className:"font-bold text-2xl",children:"Example: Support agent with RAG"}),y("p",{className:"text-muted-foreground",children:"Let's build a support agent that uses canonical product documentation and operational support history."}),ve("div",{className:"space-y-3",children:[y("h3",{className:"font-semibold text-lg",children:"Step 1: Blueprint declares knowledge needs"}),y(Vi,{language:"typescript",code:`// AppBlueprintSpec
|
|
505
505
|
{
|
|
506
506
|
id: "support-app",
|
|
507
507
|
version: "1.0.0",
|
|
@@ -660,17 +660,17 @@ steps:
|
|
|
660
660
|
allowedCategories: ["operational"],
|
|
661
661
|
sources: ["src_crm_data", "src_past_invoices"]
|
|
662
662
|
}
|
|
663
|
-
]`})]}),ve("div",{className:"space-y-4",children:[y("h2",{className:"font-bold text-2xl",children:"Security & validation"}),ve("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[y("li",{children:"Knowledge sources are validated before sync - credentials and permissions checked"}),y("li",{children:"PDP enforces which workflows/agents can access which spaces"}),y("li",{children:"All knowledge queries are audited with search terms and results"}),y("li",{children:"Canonical knowledge is immutable once indexed - changes require re-sync"}),y("li",{children:"Ephemeral knowledge is automatically purged based on retention policies"})]})]}),ve("div",{className:"space-y-4",children:[y("h2",{className:"font-bold text-2xl",children:"Best practices"}),ve("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[y("li",{children:"Use canonical spaces for policy-critical decisions, operational for suggestions"}),y("li",{children:"Never allow workflows to write to canonical spaces - maintain read-only access"}),y("li",{children:"Set up monitoring for sync failures and stale knowledge sources"}),y("li",{children:"Document the purpose and trust level of each knowledge space"}),y("li",{children:"Test knowledge queries in sandbox before promoting to production"}),ve("li",{children:["Use explicit ",y("code",{children:"allowedConsumers"})," - avoid wildcard access"]})]})]}),ve("div",{className:"flex items-center gap-4 pt-4",children:[y(
|
|
663
|
+
]`})]}),ve("div",{className:"space-y-4",children:[y("h2",{className:"font-bold text-2xl",children:"Security & validation"}),ve("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[y("li",{children:"Knowledge sources are validated before sync - credentials and permissions checked"}),y("li",{children:"PDP enforces which workflows/agents can access which spaces"}),y("li",{children:"All knowledge queries are audited with search terms and results"}),y("li",{children:"Canonical knowledge is immutable once indexed - changes require re-sync"}),y("li",{children:"Ephemeral knowledge is automatically purged based on retention policies"})]})]}),ve("div",{className:"space-y-4",children:[y("h2",{className:"font-bold text-2xl",children:"Best practices"}),ve("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[y("li",{children:"Use canonical spaces for policy-critical decisions, operational for suggestions"}),y("li",{children:"Never allow workflows to write to canonical spaces - maintain read-only access"}),y("li",{children:"Set up monitoring for sync failures and stale knowledge sources"}),y("li",{children:"Document the purpose and trust level of each knowledge space"}),y("li",{children:"Test knowledge queries in sandbox before promoting to production"}),ve("li",{children:["Use explicit ",y("code",{children:"allowedConsumers"})," - avoid wildcard access"]})]})]}),ve("div",{className:"flex items-center gap-4 pt-4",children:[y(Ic,{href:"/docs/architecture/integration-binding",className:"btn-ghost",children:"Previous: Integration Binding"}),ve(Ic,{href:"/docs/knowledge",className:"btn-primary",children:["Knowledge & Context ",y(kp,{size:16})]})]})]})}import{CodeBlock as Cp}from"@contractspec/lib.design-system";import Pc from"@contractspec/lib.ui-link";import{ChevronRight as Ip}from"lucide-react";import{jsx as ht,jsxs as Gt}from"react/jsx-runtime";function Pp(){return Gt("div",{className:"space-y-8",children:[Gt("div",{className:"space-y-4",children:[ht("h1",{className:"font-bold text-4xl",children:"Multi-Tenancy"}),ht("p",{className:"text-muted-foreground",children:"ContractSpec is designed from the ground up for multi-tenancy. Apps built with ContractSpec can serve multiple organizations (tenants) from a single deployment, while ensuring strict data isolation and configuration separation."})]}),Gt("div",{className:"space-y-4",children:[ht("h2",{className:"font-bold text-2xl",children:"Core Concepts"}),Gt("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Gt("li",{children:[ht("strong",{children:"Tenant"}),": An organization or customer that uses your app. Each tenant has a unique ",ht("code",{children:"tenantId"}),"."]}),Gt("li",{children:[ht("strong",{children:"Tenant Isolation"}),": Data and configuration for one tenant is never accessible to another tenant unless explicitly shared."]}),Gt("li",{children:[ht("strong",{children:"Tenant Context"}),": Every request and operation runs within the context of a specific tenant."]})]})]}),Gt("div",{className:"space-y-4",children:[ht("h2",{className:"font-bold text-2xl",children:"Tenant Resolution"}),ht("p",{className:"text-muted-foreground",children:"The runtime automatically resolves the tenant context for every request based on:"}),Gt("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Gt("li",{children:["Subdomain (e.g., ",ht("code",{children:"acme.app.com"}),")"]}),Gt("li",{children:["Custom Domain (e.g., ",ht("code",{children:"portal.acme.com"}),")"]}),Gt("li",{children:["Header (e.g., ",ht("code",{children:"x-tenant-id: acme-corp"}),")"]}),ht("li",{children:"Authentication Token (embedded tenant claim)"})]})]}),Gt("div",{className:"space-y-4",children:[ht("h2",{className:"font-bold text-2xl",children:"Configuration Isolation"}),Gt("p",{className:"text-muted-foreground",children:["Each tenant has its own ",ht("code",{children:"TenantAppConfig"})," which defines:"]}),ht(Cp,{language:"typescript",code:`type TenantAppConfig = {
|
|
664
664
|
tenantId: string;
|
|
665
665
|
blueprintId: string;
|
|
666
666
|
// ...
|
|
667
667
|
integrationBindings: AppIntegrationBinding[];
|
|
668
668
|
knowledgeBindings: AppKnowledgeBinding[];
|
|
669
669
|
featureFlags: Record<string, boolean>;
|
|
670
|
-
};`}),ht("p",{className:"mt-2 text-muted-foreground",children:"This allows you to customize feature flags, integration connections, and knowledge sources per tenant without changing the application code."})]}),Gt("div",{className:"flex items-center gap-4 pt-4",children:[ht(Sc,{href:"/docs/architecture",className:"btn-ghost",children:"Back to Architecture"}),Gt(Sc,{href:"/docs/libraries/multi-tenancy",className:"btn-primary",children:["Multi-Tenancy Library ",ht(Np,{size:16})]})]})]})}import Ii from"@contractspec/lib.ui-link";import{jsx as Ye,jsxs as oa}from"react/jsx-runtime";var kp=[{title:"Contracts and schemas",body:"Explicit specs define the durable boundary for behavior, data, and governance."},{title:"Bindings and configuration",body:"Apps, tenants, integrations, and knowledge sources are wired through explicit configuration instead of hidden glue."},{title:"Runtimes and generators",body:"Serve or generate aligned surfaces for API, UI, workflows, docs, and agent-facing interfaces."},{title:"Operate and observe",body:"Carry auditability, policy, tracing, migrations, and tenant isolation through the same model."}];function Sp(){return oa("div",{className:"space-y-10",children:[oa("div",{className:"space-y-3",children:[Ye("p",{className:"editorial-kicker",children:"Build"}),Ye("h1",{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"The architecture keeps contracts, runtime behavior, and operations in the same system."}),Ye("p",{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:"ContractSpec is not a single runtime. It is a layered system that lets you define explicit boundaries, bind real-world configuration, and then serve or generate aligned surfaces without losing control of the output."})]}),Ye("div",{className:"grid gap-4 md:grid-cols-2",children:kp.map((e)=>oa("article",{className:"editorial-panel space-y-3",children:[Ye("h2",{className:"font-semibold text-xl",children:e.title}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:e.body})]},e.title))}),oa("section",{className:"editorial-panel space-y-5",children:[oa("div",{className:"space-y-2",children:[Ye("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"UI composition belongs in the bundle runtime layer"}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:"When the system needs adaptive layouts, entity workbenches, assistant slots, and safe overlays, use module bundles as the layer between the contract model and the rendered surface."})]}),oa("div",{className:"grid gap-4 md:grid-cols-2",children:[oa(Ii,{href:"/docs/specs/module-bundles",className:"docs-footer-link",children:[Ye("h3",{className:"font-semibold text-lg",children:"Module bundles spec"}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:"See the typed bundle contract, resolved surface plan model, and bounded AI/runtime behavior."})]}),oa(Ii,{href:"/docs/guides/first-module-bundle",className:"docs-footer-link",children:[Ye("h3",{className:"font-semibold text-lg",children:"Build a first module bundle"}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:"Follow the route-to-plan-to-render path with one practical host example."})]})]})]}),oa("section",{className:"editorial-panel space-y-5",children:[oa("div",{className:"space-y-2",children:[Ye("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Follow the architecture by responsibility"}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:"Use the architecture pages when you need to understand how the pieces snap together in a real deployment."})]}),oa("div",{className:"grid gap-4 md:grid-cols-2",children:[oa(Ii,{href:"/docs/architecture/app-config",className:"docs-footer-link",children:[Ye("h3",{className:"font-semibold text-lg",children:"App configuration"}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:"How blueprint-level and tenant-level config stay explicit and merge safely."})]}),oa(Ii,{href:"/docs/architecture/integration-binding",className:"docs-footer-link",children:[Ye("h3",{className:"font-semibold text-lg",children:"Integration binding"}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:"How apps connect to tenant-owned integrations without leaking provider logic everywhere."})]}),oa(Ii,{href:"/docs/architecture/knowledge-binding",className:"docs-footer-link",children:[Ye("h3",{className:"font-semibold text-lg",children:"Knowledge binding"}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:"How trusted knowledge enters the system and stays isolated by context and tenant."})]}),oa(Ii,{href:"/docs/architecture/control-plane",className:"docs-footer-link",children:[Ye("h3",{className:"font-semibold text-lg",children:"Control plane runtime"}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:"How intent, policy, planning, and execution flow through the system runtime."})]})]})]})]})}import{jsx as U,jsxs as Ot}from"react/jsx-runtime";function Cp(){return Ot("div",{className:"space-y-8",children:[Ot("div",{className:"space-y-4",children:[U("h1",{className:"font-bold text-4xl",children:"Automation platforms"}),U("p",{className:"text-muted-foreground",children:"Automation platforms connect apps and automate tasks through triggers and actions. They serve operations and non-technical users well but stop short of generating full applications or enforcing fine-grained policies."})]}),Ot("div",{className:"space-y-4",children:[U("h2",{className:"font-bold text-2xl",children:"Feature comparison"}),U("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:Ot("table",{className:"w-full text-left text-sm",children:[U("thead",{className:"bg-card/50",children:Ot("tr",{className:"border-border/50 border-b",children:[U("th",{className:"px-4 py-3 font-semibold",children:"Feature"}),U("th",{className:"px-4 py-3 font-semibold",children:"Zapier"}),U("th",{className:"px-4 py-3 font-semibold",children:"Make (Integromat)"}),U("th",{className:"px-4 py-3 font-semibold",children:"n8n"}),U("th",{className:"px-4 py-3 font-semibold",children:"Pipedream"})]})}),Ot("tbody",{className:"divide-y divide-border/50",children:[Ot("tr",{children:[U("td",{className:"px-4 py-3 align-top font-semibold",children:"Workflow model"}),U("td",{className:"px-4 py-3 align-top",children:"Zaps: trigger + one or more actions"}),U("td",{className:"px-4 py-3 align-top",children:"Real-time visual orchestration for AI agents and automations"}),U("td",{className:"px-4 py-3 align-top",children:"Node-based workflow builder with drag-and-drop and code; build multi-step AI agents"}),U("td",{className:"px-4 py-3 align-top",children:"Workflows connect any API; Pipedream Connect SDK adds integrations quickly"})]}),Ot("tr",{children:[U("td",{className:"px-4 py-3 align-top font-semibold",children:"Visual builder?"}),U("td",{className:"px-4 py-3 align-top",children:"Yes (simple; web-based)."}),U("td",{className:"px-4 py-3 align-top",children:"Yes; AI-assisted editor"}),U("td",{className:"px-4 py-3 align-top",children:"Yes; visual canvas."}),U("td",{className:"px-4 py-3 align-top",children:"Code-centric editor; no visual UI builder"})]}),Ot("tr",{children:[U("td",{className:"px-4 py-3 align-top font-semibold",children:"Self-host?"}),U("td",{className:"px-4 py-3 align-top",children:"No (cloud only)."}),U("td",{className:"px-4 py-3 align-top",children:"Cloud only."}),U("td",{className:"px-4 py-3 align-top",children:"Yes (Docker, self-host)"}),U("td",{className:"px-4 py-3 align-top",children:"Cloud only (hosted)."})]}),Ot("tr",{children:[U("td",{className:"px-4 py-3 align-top font-semibold",children:"Integrations & AI"}),U("td",{className:"px-4 py-3 align-top",children:"Connects almost 8 000 apps; limited AI features."}),U("td",{className:"px-4 py-3 align-top",children:"3 000+ pre-built apps; supports GenAI tools; GDPR/SOC2 and SSO"}),U("td",{className:"px-4 py-3 align-top",children:"Integrates LLMs; allows JS or Python code and library imports; chatbots with Slack/Teams"}),U("td",{className:"px-4 py-3 align-top",children:"MCP servers add 3 000+ APIs and 10 000+ tools to agents; AI agent builder prompts and deploys agents; SOC 2/ HIPAA/GDPR compliant"})]}),Ot("tr",{children:[U("td",{className:"px-4 py-3 align-top font-semibold",children:"Policy & UI generation"}),U("td",{className:"px-4 py-3 align-top",children:"No policy engine; does not generate user interfaces."}),U("td",{className:"px-4 py-3 align-top",children:"No policy engine; does not generate UIs beyond a workflow dashboard."}),U("td",{className:"px-4 py-3 align-top",children:"No policy engine; no UI builder"}),U("td",{className:"px-4 py-3 align-top",children:"No policy engine; does not generate UI."})]})]})]})})]}),Ot("div",{className:"space-y-3",children:[U("h2",{className:"font-bold text-2xl",children:"Why ContractSpec differs"}),Ot("ul",{className:"space-y-2 text-muted-foreground",children:[Ot("li",{children:[U("strong",{children:"Full application generation"})," – ContractSpec compiles specs into back-end, events and user interfaces for both web and mobile."]}),Ot("li",{children:[U("strong",{children:"Policy enforcement"})," – A built-in policy engine governs PII access and mutations across the UI."]}),Ot("li",{children:[U("strong",{children:"Customisation via overlays"})," – Non-technical users can safely personalise layouts while respecting policies."]}),Ot("li",{children:[U("strong",{children:"Extensible capabilities"})," – Connect to external APIs and services via capability providers while maintaining type safety."]})]}),U("p",{className:"text-muted-foreground",children:"Automation tools simplify integrations and tasks; ContractSpec goes further by generating a complete, policy-safe application around your data and processes."})]})]})}import Ip from"@contractspec/lib.ui-link";import{jsx as Y,jsxs as yt}from"react/jsx-runtime";function Pp(){return yt("div",{className:"space-y-8",children:[yt("div",{className:"space-y-4",children:[Y("h1",{className:"font-bold text-4xl",children:"Enterprise orchestration platforms"}),Y("p",{className:"text-muted-foreground",children:"Enterprise orchestration platforms manage mission-critical workloads and integrate deeply with ERP systems. They prioritise governance, reliability and compliance, but they do not provide spec-driven app generation or per-user customisation."})]}),yt("div",{className:"space-y-4",children:[Y("h2",{className:"font-bold text-2xl",children:"Redwood RunMyJobs"}),yt("p",{className:"text-muted-foreground",children:[Y(Ip,{href:"https://www.redwood.com/workload-automation/",className:"underline decoration-dotted underline-offset-4 hover:text-foreground",target:"_blank",rel:"noreferrer",children:"RunMyJobs by Redwood"})," ","is a cloud-native service orchestration and automation platform. Key attributes include:"]}),yt("ul",{className:"space-y-2 text-muted-foreground",children:[yt("li",{children:[Y("strong",{children:"Self-service portal."})," Business users can run and customise workloads while IT ensures governance and compliance"]}),yt("li",{children:[Y("strong",{children:"Full-stack orchestration."})," Integrates with both SAP and non-SAP systems; Redwood is recognised as a Leader in Gartner’s Magic Quadrant for service orchestration"]}),yt("li",{children:[Y("strong",{children:"Observability and AI insights."})," Dashboards and AI-enhanced analytics identify bottlenecks and forecast issues"]}),yt("li",{children:[Y("strong",{children:"Deep SAP integration."})," Supports SAP’s latest technologies and orchestrates mission-critical business processes"]}),yt("li",{children:[Y("strong",{children:"Connectors & wizard."})," Provides pre-built connectors and a wizard to link on-prem and cloud systems"]})]})]}),yt("div",{className:"space-y-4",children:[Y("h3",{className:"font-semibold text-xl",children:"Comparison with ContractSpec"}),Y("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:yt("table",{className:"w-full text-left text-sm",children:[Y("thead",{className:"bg-card/50",children:yt("tr",{className:"border-border/50 border-b",children:[Y("th",{className:"px-4 py-3 font-semibold",children:"Aspect"}),Y("th",{className:"px-4 py-3 font-semibold",children:"RunMyJobs"}),Y("th",{className:"px-4 py-3 font-semibold",children:"ContractSpec"})]})}),yt("tbody",{className:"divide-y divide-border/50",children:[yt("tr",{children:[Y("td",{className:"px-4 py-3 align-top",children:Y("strong",{children:"Target user"})}),Y("td",{className:"px-4 py-3 align-top",children:"Enterprise IT and operations teams automating SAP and mission-critical workflows."}),Y("td",{className:"px-4 py-3 align-top",children:"Developers, product teams and SMBs wanting to generate policy-safe apps with customisable UIs."})]}),yt("tr",{children:[Y("td",{className:"px-4 py-3 align-top",children:Y("strong",{children:"Workload focus"})}),Y("td",{className:"px-4 py-3 align-top",children:"Service orchestration and job scheduling across ERP/legacy systems"}),Y("td",{className:"px-4 py-3 align-top",children:"End-to-end application generation with back-end, UI and policies."})]}),yt("tr",{children:[Y("td",{className:"px-4 py-3 align-top",children:Y("strong",{children:"User interface"})}),Y("td",{className:"px-4 py-3 align-top",children:"Self-service portal to run/monitor jobs; no custom UI generation for new apps."}),Y("td",{className:"px-4 py-3 align-top",children:"Generates React/React-Native UIs from specs; users can personalise layout via overlays."})]}),yt("tr",{children:[Y("td",{className:"px-4 py-3 align-top",children:Y("strong",{children:"Open source"})}),Y("td",{className:"px-4 py-3 align-top",children:"Proprietary SaaS; enterprise agreements."}),Y("td",{className:"px-4 py-3 align-top",children:"Core compiler is proprietary; SDK and certain modules may be open-source; offers hosted and on-prem options."})]}),yt("tr",{children:[Y("td",{className:"px-4 py-3 align-top",children:Y("strong",{children:"Policy & personalisation"})}),Y("td",{className:"px-4 py-3 align-top",children:"IT controls governance; no per-user overlay concept."}),Y("td",{className:"px-4 py-3 align-top",children:"Built-in policy engine and per-user overlays for safe personalisation."})]})]})]})}),Y("p",{className:"text-muted-foreground",children:"Redwood RunMyJobs is designed for orchestrating enterprise workloads and SAP processes. ContractSpec targets a different problem: generating complete applications from typed specs and letting end users adapt them safely."})]})]})}import{jsx as W,jsxs as Bt}from"react/jsx-runtime";function Tp(){return Bt("div",{className:"space-y-8",children:[Bt("div",{className:"space-y-4",children:[W("h1",{className:"font-bold text-4xl",children:"Internal-tool builders"}),W("p",{className:"text-muted-foreground",children:"Internal-tool builders let teams quickly assemble dashboards and admin panels. These platforms often provide drag-and-drop UIs and connectors to databases and APIs, but they rely on developers to write custom code for business logic and seldom enforce policies across surfaces."})]}),Bt("div",{className:"space-y-4",children:[W("h2",{className:"font-bold text-2xl",children:"Feature comparison"}),W("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:Bt("table",{className:"w-full text-left text-sm",children:[W("thead",{className:"bg-card/50",children:Bt("tr",{className:"border-border/50 border-b",children:[W("th",{className:"px-4 py-3 font-semibold",children:"Feature"}),W("th",{className:"px-4 py-3 font-semibold",children:"Retool"}),W("th",{className:"px-4 py-3 font-semibold",children:"Appsmith"}),W("th",{className:"px-4 py-3 font-semibold",children:"ToolJet"}),W("th",{className:"px-4 py-3 font-semibold",children:"Budibase"})]})}),Bt("tbody",{className:"divide-y divide-border/50",children:[Bt("tr",{children:[W("td",{className:"px-4 py-3 align-top font-semibold",children:"UI builder"}),W("td",{className:"px-4 py-3 align-top",children:"Drag-and-drop canvas; shape UI components easily"}),W("td",{className:"px-4 py-3 align-top",children:"Visual builder with drag-and-drop widgets"}),W("td",{className:"px-4 py-3 align-top",children:"Drag-and-drop UI widgets (tables, charts, forms)"}),W("td",{className:"px-4 py-3 align-top",children:"Pre-built components and templates for mobile/desktop"})]}),Bt("tr",{children:[W("td",{className:"px-4 py-3 align-top font-semibold",children:"Custom code & logic"}),W("td",{className:"px-4 py-3 align-top",children:"Full code insertion anywhere via IDE"}),W("td",{className:"px-4 py-3 align-top",children:"Logic via JavaScript or natural-language prompts in a central IDE"}),W("td",{className:"px-4 py-3 align-top",children:"Supports business logic in JavaScript or Python queries"}),W("td",{className:"px-4 py-3 align-top",children:"Custom logic via JavaScript; plugins and external embeds"})]}),Bt("tr",{children:[W("td",{className:"px-4 py-3 align-top font-semibold",children:"Data connectors"}),W("td",{className:"px-4 py-3 align-top",children:"Wide support for databases and APIs (PostgreSQL, MongoDB, GraphQL, etc.)."}),W("td",{className:"px-4 py-3 align-top",children:"Connects to LLMs and databases"}),W("td",{className:"px-4 py-3 align-top",children:"Built-in database; connects to PostgreSQL, MongoDB, APIs, GraphQL, SaaS"}),W("td",{className:"px-4 py-3 align-top",children:"Connects to external databases, REST, CSV or built-in DB"})]}),Bt("tr",{children:[W("td",{className:"px-4 py-3 align-top font-semibold",children:"Open source & self-host"}),W("td",{className:"px-4 py-3 align-top",children:"Proprietary; cloud or on-prem subscription."}),W("td",{className:"px-4 py-3 align-top",children:"Open source (Apache-2.0); self-host or cloud."}),W("td",{className:"px-4 py-3 align-top",children:"Open source; self-host via Docker or cloud."}),W("td",{className:"px-4 py-3 align-top",children:"Open source; self-host via Docker/Kubernetes"})]}),Bt("tr",{children:[W("td",{className:"px-4 py-3 align-top font-semibold",children:"Policy & personalisation"}),W("td",{className:"px-4 py-3 align-top",children:"No built-in policy engine; personalisation limited to user roles."}),W("td",{className:"px-4 py-3 align-top",children:"No typed policy engine; customisation depends on user roles."}),W("td",{className:"px-4 py-3 align-top",children:"No policy engine; personalisation via user roles."}),W("td",{className:"px-4 py-3 align-top",children:"No policy engine; personalisation via RBAC & SSO"})]})]})]})})]}),Bt("div",{className:"space-y-3",children:[W("h2",{className:"font-bold text-2xl",children:"ContractSpec’s differences"}),Bt("ul",{className:"space-y-2 text-muted-foreground",children:[Bt("li",{children:[W("strong",{children:"Typed specifications"})," produce both the API and UI. You define capabilities, data views and workflows, and the compiler generates code, forms and screens—no manual widget wiring."]}),Bt("li",{children:[W("strong",{children:"Policy enforcement"})," at run time ensures PII and ABAC rules across the entire app."]}),Bt("li",{children:[W("strong",{children:"Overlay personalisation"})," allows tenants and users to change layouts safely without code."]}),Bt("li",{children:[W("strong",{children:"Unified mobile/web runtime"})," means you don’t need separate builders for React Native vs web."]})]}),W("p",{className:"text-muted-foreground",children:"Internal-tool builders are useful for quick dashboards. ContractSpec extends this by generating the whole stack from specs and enforcing policies throughout."})]})]})}import{jsx as Q,jsxs as to}from"react/jsx-runtime";function Ap(){return to("div",{className:"space-y-8",children:[to("div",{className:"space-y-4",children:[Q("h1",{className:"font-bold text-4xl",children:"Comparison overview"}),Q("p",{className:"text-muted-foreground",children:"ContractSpec sits at the intersection of several tool categories. To appreciate its unique offering—typed specifications for back-end, front-end, workflows and policies with a unified web/mobile runtime—this section compares it to related products."}),to("p",{className:"text-muted-foreground",children:["ContractSpec uses ",Q("strong",{children:"runtime adapters"})," to serve typed"," ",Q("strong",{children:"Operations"})," (Commands/Queries),"," ",Q("strong",{children:"DataViews"}),", ",Q("strong",{children:"Workflows"}),", and"," ",Q("strong",{children:"Policies"})," as REST/GraphQL/MCP endpoints. A"," ",Q("strong",{children:"policy decision point"})," governs every operation, and"," ",Q("strong",{children:"OverlaySpecs"})," allow non-technical users to personalise screens safely. Few competitors offer this combination of runtime type safety, policy enforcement, and end-user customisation."]})]}),to("div",{className:"space-y-4",children:[Q("h2",{className:"font-bold text-2xl",children:"Tool categories"}),Q("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:to("table",{className:"w-full text-left text-sm",children:[Q("thead",{className:"bg-card/50",children:to("tr",{className:"border-border/50 border-b",children:[Q("th",{className:"px-4 py-3 font-semibold",children:"Category"}),Q("th",{className:"px-4 py-3 font-semibold",children:"Examples"}),Q("th",{className:"px-4 py-3 font-semibold",children:"What they do"}),Q("th",{className:"px-4 py-3 font-semibold",children:"Limitations"})]})}),to("tbody",{className:"divide-y divide-border/50",children:[to("tr",{children:[Q("td",{className:"px-4 py-3 align-top",children:Q("strong",{children:"Workflow engines"})}),Q("td",{className:"px-4 py-3 align-top",children:"Prefect, Kestra, Temporal, Airflow, Dagster, Hatchet, Windmill"}),Q("td",{className:"px-4 py-3 align-top",children:"Orchestrate code or data pipelines; handle retries, scheduling and observability"}),Q("td",{className:"px-4 py-3 align-top",children:"Require writing code; no automatic UI generation or policy enforcement."})]}),to("tr",{children:[Q("td",{className:"px-4 py-3 align-top",children:Q("strong",{children:"Internal-tool builders"})}),Q("td",{className:"px-4 py-3 align-top",children:"Retool, Appsmith, ToolJet, Budibase"}),Q("td",{className:"px-4 py-3 align-top",children:"Drag-and-drop dashboards and admin panels; connect to databases/APIs"}),Q("td",{className:"px-4 py-3 align-top",children:"No typed back-end spec; limited enforcement of policies; custom code glues logic."})]}),to("tr",{children:[Q("td",{className:"px-4 py-3 align-top",children:Q("strong",{children:"Automation platforms"})}),Q("td",{className:"px-4 py-3 align-top",children:"Zapier, Make, n8n, Pipedream"}),Q("td",{className:"px-4 py-3 align-top",children:"Connect apps via triggers and actions; visual or low-code interfaces"}),Q("td",{className:"px-4 py-3 align-top",children:"Automate tasks but do not generate full apps or enforce per-field policies."})]}),to("tr",{children:[Q("td",{className:"px-4 py-3 align-top",children:Q("strong",{children:"Enterprise orchestrators"})}),Q("td",{className:"px-4 py-3 align-top",children:"Redwood RunMyJobs"}),Q("td",{className:"px-4 py-3 align-top",children:"Automate mission-critical workloads with self-service portals and SAP integrations"}),Q("td",{className:"px-4 py-3 align-top",children:"Focus on IT workloads; not built for custom app creation or per-user customisation."})]})]})]})}),Q("p",{className:"text-muted-foreground",children:"Use the pages below to explore each group in detail and see how ContractSpec compares."})]})]})}import{jsx as z,jsxs as Je}from"react/jsx-runtime";function Rp(){return Je("div",{className:"space-y-8",children:[Je("div",{className:"space-y-4",children:[z("h1",{className:"font-bold text-4xl",children:"Windmill"}),Je("p",{className:"text-muted-foreground",children:["Windmill is an open-source platform that turns"," ",z("strong",{children:"scripts"})," into endpoints, workflows and UIs. It seeks to remove boilerplate by generating interfaces and workflows around existing code"]})]}),Je("div",{className:"space-y-4",children:[z("h2",{className:"font-bold text-2xl",children:"Platform features"}),Je("ul",{className:"space-y-3 text-muted-foreground",children:[Je("li",{children:[z("strong",{children:"Script-driven model."})," Write scripts in TypeScript, Python, Go, PHP, Bash, C#, SQL or Rust; Windmill infers dependencies, creates lockfiles and JSON schemas, then serves minimal UIs automatically"]}),Je("li",{children:[z("strong",{children:"Visual flow editor."})," Compose scripts into workflows with retries, error handling, loops, branching, suspending flows and approval steps"]}),Je("li",{children:[z("strong",{children:"Low-code UI builder."})," Build dashboards and admin panels using inline scripts and trigger flows from the UI"]}),Je("li",{children:[z("strong",{children:"Enterprise readiness."})," Features include RBAC permissions, secret management, OAuth handling, CLI/git sync, scheduling and webhooks"]}),Je("li",{children:[z("strong",{children:"Use cases."})," Deploy scripts as webhooks or cron jobs; create “applicative workflows” combining external APIs; build ETLs and interactive dashboards"]}),Je("li",{children:[z("strong",{children:"Open source & self-hosting."})," Windmill emphasises an open-source codebase and self-hosting options"]})]})]}),Je("div",{className:"space-y-4",children:[z("h2",{className:"font-bold text-2xl",children:"Comparison with ContractSpec"}),z("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:Je("table",{className:"w-full text-left text-sm",children:[z("thead",{className:"bg-card/50",children:Je("tr",{className:"border-border/50 border-b",children:[z("th",{className:"px-4 py-3 font-semibold",children:"Feature"}),z("th",{className:"px-4 py-3 font-semibold",children:"Windmill"}),z("th",{className:"px-4 py-3 font-semibold",children:"ContractSpec"})]})}),Je("tbody",{className:"divide-y divide-border/50",children:[Je("tr",{children:[z("td",{className:"px-4 py-3 align-top",children:z("strong",{children:"Entry model"})}),z("td",{className:"px-4 py-3 align-top",children:"Write scripts; platform auto-generates UI and workflows"}),z("td",{className:"px-4 py-3 align-top",children:"Define typed specs (Capabilities, DataViews, Workflows, Policies); compiler outputs back-end, front-end and forms."})]}),Je("tr",{children:[z("td",{className:"px-4 py-3 align-top",children:z("strong",{children:"Language support"})}),z("td",{className:"px-4 py-3 align-top",children:"20+ languages via embedded runtimes"}),z("td",{className:"px-4 py-3 align-top",children:"Uses TypeScript/JavaScript for providers; supports other back-ends through capability providers."})]}),Je("tr",{children:[z("td",{className:"px-4 py-3 align-top",children:z("strong",{children:"UI generation"})}),z("td",{className:"px-4 py-3 align-top",children:"Minimal UI forms from script parameters; low-code app builder"}),z("td",{className:"px-4 py-3 align-top",children:"Generates full web and mobile UIs from specs; user layouts can be customised via signed overlays."})]}),Je("tr",{children:[z("td",{className:"px-4 py-3 align-top",children:z("strong",{children:"Policy & personalization"})}),z("td",{className:"px-4 py-3 align-top",children:"RBAC and secret management; no per-user overlay concept"}),z("td",{className:"px-4 py-3 align-top",children:"Built-in policy engine enforcing ABAC/PII on every render/mutate; overlays allow safe per-user customisation."})]}),Je("tr",{children:[z("td",{className:"px-4 py-3 align-top",children:z("strong",{children:"Open source"})}),z("td",{className:"px-4 py-3 align-top",children:"Fully open source and self-hostable"}),z("td",{className:"px-4 py-3 align-top",children:"Closed-source core (SDK is open); offers hosted and on-prem modes."})]}),Je("tr",{children:[z("td",{className:"px-4 py-3 align-top",children:z("strong",{children:"Ideal for"})}),z("td",{className:"px-4 py-3 align-top",children:"Teams wanting to expose scripts as APIs, workflows or dashboards without heavy infrastructure."}),z("td",{className:"px-4 py-3 align-top",children:"Teams needing a spec-driven platform that generates code and UI, enforces policies and lets non-technical users tailor the experience."})]})]})]})}),Je("p",{className:"text-muted-foreground",children:["Windmill excels at converting scripts into workflows and admin panels. ContractSpec takes a ",z("strong",{children:"spec-first"})," approach, generating the entire stack and enforcing policies, making it suitable for long-lived applications that must evolve safely."]})]})]})}import{jsx as u,jsxs as bt}from"react/jsx-runtime";function Lp(){return bt("div",{className:"space-y-8",children:[bt("div",{className:"space-y-4",children:[u("h1",{className:"font-bold text-4xl",children:"Workflow engines"}),u("p",{className:"text-muted-foreground",children:"Workflow engines orchestrate long-running tasks and data pipelines. They provide retries, scheduling and visibility, but most expect developers to write code and do not generate user interfaces. Here’s how the major engines compare to ContractSpec."})]}),bt("div",{className:"space-y-4",children:[u("h2",{className:"font-bold text-2xl",children:"Key differences summary"}),u("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:bt("table",{className:"w-full text-left text-sm",children:[u("thead",{className:"bg-card/50",children:bt("tr",{className:"border-border/50 border-b",children:[u("th",{className:"px-4 py-3 font-semibold",children:"Engine"}),u("th",{className:"px-4 py-3 font-semibold",children:"Core strengths"}),u("th",{className:"px-4 py-3 font-semibold",children:"UI generation?"}),u("th",{className:"px-4 py-3 font-semibold",children:"Policy/PII enforcement?"}),u("th",{className:"px-4 py-3 font-semibold",children:"Self-host?"}),u("th",{className:"px-4 py-3 font-semibold",children:"Primary use"})]})}),bt("tbody",{className:"divide-y divide-border/50",children:[bt("tr",{children:[u("td",{className:"px-4 py-3 align-top",children:u("strong",{children:"Prefect"})}),u("td",{className:"px-4 py-3 align-top",children:"Python-native; dynamic DAGs adapt to change; annotate code without rewriting; strong observability and audit logs"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"Yes"}),u("td",{className:"px-4 py-3 align-top",children:"Data pipelines and dynamic workflows."})]}),bt("tr",{children:[u("td",{className:"px-4 py-3 align-top",children:u("strong",{children:"Kestra"})}),u("td",{className:"px-4 py-3 align-top",children:"Declarative YAML; event-driven triggers; mix of code and no-code; write logic in Python/R/Java/Julia/Ruby; deploy anywhere"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"Yes"}),u("td",{className:"px-4 py-3 align-top",children:"Data pipelines and hybrid orchestration."})]}),bt("tr",{children:[u("td",{className:"px-4 py-3 align-top",children:u("strong",{children:"Temporal"})}),u("td",{className:"px-4 py-3 align-top",children:"Durable execution; workflows never lose state; multi-language SDKs; automatic retries"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"Yes"}),u("td",{className:"px-4 py-3 align-top",children:"Durable microservice and business workflows."})]}),bt("tr",{children:[u("td",{className:"px-4 py-3 align-top",children:u("strong",{children:"Airflow"})}),u("td",{className:"px-4 py-3 align-top",children:"Open-source; define workflows as Python code; schedule and monitor via UI; extensible via custom operators"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"Yes"}),u("td",{className:"px-4 py-3 align-top",children:"Data ETL pipelines."})]}),bt("tr",{children:[u("td",{className:"px-4 py-3 align-top",children:u("strong",{children:"Dagster"})}),u("td",{className:"px-4 py-3 align-top",children:"Data-asset model; local testing and reusable components; built-in data quality and catalog; orchestrates AI/data pipelines across multiple tools"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"Yes"}),u("td",{className:"px-4 py-3 align-top",children:"Data/AI pipelines with strong observability."})]}),bt("tr",{children:[u("td",{className:"px-4 py-3 align-top",children:u("strong",{children:"Hatchet"})}),u("td",{className:"px-4 py-3 align-top",children:"Modern engine focused on performance and durability; tasks and workflows as code; durable functions with guardrails and retries"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"Yes"}),u("td",{className:"px-4 py-3 align-top",children:"High-throughput background jobs and microservices."})]}),bt("tr",{children:[u("td",{className:"px-4 py-3 align-top",children:u("strong",{children:"Windmill"})}),u("td",{className:"px-4 py-3 align-top",children:"Multi-language scripts; auto-generates UI; integrated flow editor"}),u("td",{className:"px-4 py-3 align-top",children:"Yes (basic)"}),u("td",{className:"px-4 py-3 align-top",children:"RBAC & secrets only"}),u("td",{className:"px-4 py-3 align-top",children:"Yes"}),u("td",{className:"px-4 py-3 align-top",children:"Scripts into workflows and dashboards."})]})]})]})})]}),bt("div",{className:"space-y-3",children:[u("h2",{className:"font-bold text-2xl",children:"Why ContractSpec differs"}),bt("ul",{className:"space-y-2 text-muted-foreground",children:[bt("li",{children:[u("strong",{children:"Spec-first generation"})," – Instead of writing code, you define typed specs for capabilities, data views and workflows; the compiler outputs both back-end and front-end."]}),bt("li",{children:[u("strong",{children:"Policy engine"})," – Every render and mutate passes through an ABAC/PII policy decision point."]}),bt("li",{children:[u("strong",{children:"Personalisation"})," – Signed OverlaySpecs allow tenant/user-specific UI changes without touching code."]}),bt("li",{children:[u("strong",{children:"Unified runtime"})," – React/React-Native rendering ensures consistent experiences across web and mobile."]})]}),u("p",{className:"text-muted-foreground",children:"Workflow engines are excellent for orchestrating back-end tasks. ContractSpec builds on this by serving complete applications with runtime policy enforcement and user personalisation via TypeScript specs."})]})]})}import{CodeBlock as Dp}from"@contractspec/lib.design-system";import Cc from"@contractspec/lib.ui-link";import{ChevronRight as Ep}from"lucide-react";import{jsx as ia,jsxs as ni}from"react/jsx-runtime";function Op(){return ni("div",{className:"space-y-8",children:[ni("div",{className:"space-y-3",children:[ia("h1",{className:"font-bold text-4xl",children:"Integrations"}),ia("p",{className:"text-lg text-muted-foreground",children:"Reference integrations show how to extend ContractSpec with real-world adapters and generators."})]}),ni("div",{className:"card-subtle space-y-4 p-6",children:[ia("h2",{className:"font-bold text-2xl",children:"Reference plugin"}),ia("p",{className:"text-muted-foreground text-sm",children:"The example markdown generator plugin ships as a working reference implementation."}),ia(Dp,{language:"bash",filename:"install-example",code:`bun add @contractspec/lib.plugin.example-generator
|
|
670
|
+
};`}),ht("p",{className:"mt-2 text-muted-foreground",children:"This allows you to customize feature flags, integration connections, and knowledge sources per tenant without changing the application code."})]}),Gt("div",{className:"flex items-center gap-4 pt-4",children:[ht(Pc,{href:"/docs/architecture",className:"btn-ghost",children:"Back to Architecture"}),Gt(Pc,{href:"/docs/libraries/multi-tenancy",className:"btn-primary",children:["Multi-Tenancy Library ",ht(Ip,{size:16})]})]})]})}import Ii from"@contractspec/lib.ui-link";import{jsx as Ye,jsxs as oa}from"react/jsx-runtime";var Tp=[{title:"Contracts and schemas",body:"Explicit specs define the durable boundary for behavior, data, and governance."},{title:"Bindings and configuration",body:"Apps, tenants, integrations, and knowledge sources are wired through explicit configuration instead of hidden glue."},{title:"Runtimes and generators",body:"Serve or generate aligned surfaces for API, UI, workflows, docs, and agent-facing interfaces."},{title:"Operate and observe",body:"Carry auditability, policy, tracing, migrations, and tenant isolation through the same model."}];function Ap(){return oa("div",{className:"space-y-10",children:[oa("div",{className:"space-y-3",children:[Ye("p",{className:"editorial-kicker",children:"Build"}),Ye("h1",{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"The architecture keeps contracts, runtime behavior, and operations in the same system."}),Ye("p",{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:"ContractSpec is not a single runtime. It is a layered system that lets you define explicit boundaries, bind real-world configuration, and then serve or generate aligned surfaces without losing control of the output."})]}),Ye("div",{className:"grid gap-4 md:grid-cols-2",children:Tp.map((e)=>oa("article",{className:"editorial-panel space-y-3",children:[Ye("h2",{className:"font-semibold text-xl",children:e.title}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:e.body})]},e.title))}),oa("section",{className:"editorial-panel space-y-5",children:[oa("div",{className:"space-y-2",children:[Ye("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"UI composition belongs in the bundle runtime layer"}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:"When the system needs adaptive layouts, entity workbenches, assistant slots, and safe overlays, use module bundles as the layer between the contract model and the rendered surface."})]}),oa("div",{className:"grid gap-4 md:grid-cols-2",children:[oa(Ii,{href:"/docs/specs/module-bundles",className:"docs-footer-link",children:[Ye("h3",{className:"font-semibold text-lg",children:"Module bundles spec"}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:"See the typed bundle contract, resolved surface plan model, and bounded AI/runtime behavior."})]}),oa(Ii,{href:"/docs/guides/first-module-bundle",className:"docs-footer-link",children:[Ye("h3",{className:"font-semibold text-lg",children:"Build a first module bundle"}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:"Follow the route-to-plan-to-render path with one practical host example."})]})]})]}),oa("section",{className:"editorial-panel space-y-5",children:[oa("div",{className:"space-y-2",children:[Ye("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Follow the architecture by responsibility"}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:"Use the architecture pages when you need to understand how the pieces snap together in a real deployment."})]}),oa("div",{className:"grid gap-4 md:grid-cols-2",children:[oa(Ii,{href:"/docs/architecture/app-config",className:"docs-footer-link",children:[Ye("h3",{className:"font-semibold text-lg",children:"App configuration"}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:"How blueprint-level and tenant-level config stay explicit and merge safely."})]}),oa(Ii,{href:"/docs/architecture/integration-binding",className:"docs-footer-link",children:[Ye("h3",{className:"font-semibold text-lg",children:"Integration binding"}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:"How apps connect to tenant-owned integrations without leaking provider logic everywhere."})]}),oa(Ii,{href:"/docs/architecture/knowledge-binding",className:"docs-footer-link",children:[Ye("h3",{className:"font-semibold text-lg",children:"Knowledge binding"}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:"How trusted knowledge enters the system and stays isolated by context and tenant."})]}),oa(Ii,{href:"/docs/architecture/control-plane",className:"docs-footer-link",children:[Ye("h3",{className:"font-semibold text-lg",children:"Control plane runtime"}),Ye("p",{className:"text-muted-foreground text-sm leading-7",children:"How intent, policy, planning, and execution flow through the system runtime."})]})]})]})]})}import{jsx as U,jsxs as Ot}from"react/jsx-runtime";function Rp(){return Ot("div",{className:"space-y-8",children:[Ot("div",{className:"space-y-4",children:[U("h1",{className:"font-bold text-4xl",children:"Automation platforms"}),U("p",{className:"text-muted-foreground",children:"Automation platforms connect apps and automate tasks through triggers and actions. They serve operations and non-technical users well but stop short of generating full applications or enforcing fine-grained policies."})]}),Ot("div",{className:"space-y-4",children:[U("h2",{className:"font-bold text-2xl",children:"Feature comparison"}),U("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:Ot("table",{className:"w-full text-left text-sm",children:[U("thead",{className:"bg-card/50",children:Ot("tr",{className:"border-border/50 border-b",children:[U("th",{className:"px-4 py-3 font-semibold",children:"Feature"}),U("th",{className:"px-4 py-3 font-semibold",children:"Zapier"}),U("th",{className:"px-4 py-3 font-semibold",children:"Make (Integromat)"}),U("th",{className:"px-4 py-3 font-semibold",children:"n8n"}),U("th",{className:"px-4 py-3 font-semibold",children:"Pipedream"})]})}),Ot("tbody",{className:"divide-y divide-border/50",children:[Ot("tr",{children:[U("td",{className:"px-4 py-3 align-top font-semibold",children:"Workflow model"}),U("td",{className:"px-4 py-3 align-top",children:"Zaps: trigger + one or more actions"}),U("td",{className:"px-4 py-3 align-top",children:"Real-time visual orchestration for AI agents and automations"}),U("td",{className:"px-4 py-3 align-top",children:"Node-based workflow builder with drag-and-drop and code; build multi-step AI agents"}),U("td",{className:"px-4 py-3 align-top",children:"Workflows connect any API; Pipedream Connect SDK adds integrations quickly"})]}),Ot("tr",{children:[U("td",{className:"px-4 py-3 align-top font-semibold",children:"Visual builder?"}),U("td",{className:"px-4 py-3 align-top",children:"Yes (simple; web-based)."}),U("td",{className:"px-4 py-3 align-top",children:"Yes; AI-assisted editor"}),U("td",{className:"px-4 py-3 align-top",children:"Yes; visual canvas."}),U("td",{className:"px-4 py-3 align-top",children:"Code-centric editor; no visual UI builder"})]}),Ot("tr",{children:[U("td",{className:"px-4 py-3 align-top font-semibold",children:"Self-host?"}),U("td",{className:"px-4 py-3 align-top",children:"No (cloud only)."}),U("td",{className:"px-4 py-3 align-top",children:"Cloud only."}),U("td",{className:"px-4 py-3 align-top",children:"Yes (Docker, self-host)"}),U("td",{className:"px-4 py-3 align-top",children:"Cloud only (hosted)."})]}),Ot("tr",{children:[U("td",{className:"px-4 py-3 align-top font-semibold",children:"Integrations & AI"}),U("td",{className:"px-4 py-3 align-top",children:"Connects almost 8 000 apps; limited AI features."}),U("td",{className:"px-4 py-3 align-top",children:"3 000+ pre-built apps; supports GenAI tools; GDPR/SOC2 and SSO"}),U("td",{className:"px-4 py-3 align-top",children:"Integrates LLMs; allows JS or Python code and library imports; chatbots with Slack/Teams"}),U("td",{className:"px-4 py-3 align-top",children:"MCP servers add 3 000+ APIs and 10 000+ tools to agents; AI agent builder prompts and deploys agents; SOC 2/ HIPAA/GDPR compliant"})]}),Ot("tr",{children:[U("td",{className:"px-4 py-3 align-top font-semibold",children:"Policy & UI generation"}),U("td",{className:"px-4 py-3 align-top",children:"No policy engine; does not generate user interfaces."}),U("td",{className:"px-4 py-3 align-top",children:"No policy engine; does not generate UIs beyond a workflow dashboard."}),U("td",{className:"px-4 py-3 align-top",children:"No policy engine; no UI builder"}),U("td",{className:"px-4 py-3 align-top",children:"No policy engine; does not generate UI."})]})]})]})})]}),Ot("div",{className:"space-y-3",children:[U("h2",{className:"font-bold text-2xl",children:"Why ContractSpec differs"}),Ot("ul",{className:"space-y-2 text-muted-foreground",children:[Ot("li",{children:[U("strong",{children:"Full application generation"})," – ContractSpec compiles specs into back-end, events and user interfaces for both web and mobile."]}),Ot("li",{children:[U("strong",{children:"Policy enforcement"})," – A built-in policy engine governs PII access and mutations across the UI."]}),Ot("li",{children:[U("strong",{children:"Customisation via overlays"})," – Non-technical users can safely personalise layouts while respecting policies."]}),Ot("li",{children:[U("strong",{children:"Extensible capabilities"})," – Connect to external APIs and services via capability providers while maintaining type safety."]})]}),U("p",{className:"text-muted-foreground",children:"Automation tools simplify integrations and tasks; ContractSpec goes further by generating a complete, policy-safe application around your data and processes."})]})]})}import Lp from"@contractspec/lib.ui-link";import{jsx as Y,jsxs as yt}from"react/jsx-runtime";function Dp(){return yt("div",{className:"space-y-8",children:[yt("div",{className:"space-y-4",children:[Y("h1",{className:"font-bold text-4xl",children:"Enterprise orchestration platforms"}),Y("p",{className:"text-muted-foreground",children:"Enterprise orchestration platforms manage mission-critical workloads and integrate deeply with ERP systems. They prioritise governance, reliability and compliance, but they do not provide spec-driven app generation or per-user customisation."})]}),yt("div",{className:"space-y-4",children:[Y("h2",{className:"font-bold text-2xl",children:"Redwood RunMyJobs"}),yt("p",{className:"text-muted-foreground",children:[Y(Lp,{href:"https://www.redwood.com/workload-automation/",className:"underline decoration-dotted underline-offset-4 hover:text-foreground",target:"_blank",rel:"noreferrer",children:"RunMyJobs by Redwood"})," ","is a cloud-native service orchestration and automation platform. Key attributes include:"]}),yt("ul",{className:"space-y-2 text-muted-foreground",children:[yt("li",{children:[Y("strong",{children:"Self-service portal."})," Business users can run and customise workloads while IT ensures governance and compliance"]}),yt("li",{children:[Y("strong",{children:"Full-stack orchestration."})," Integrates with both SAP and non-SAP systems; Redwood is recognised as a Leader in Gartner’s Magic Quadrant for service orchestration"]}),yt("li",{children:[Y("strong",{children:"Observability and AI insights."})," Dashboards and AI-enhanced analytics identify bottlenecks and forecast issues"]}),yt("li",{children:[Y("strong",{children:"Deep SAP integration."})," Supports SAP’s latest technologies and orchestrates mission-critical business processes"]}),yt("li",{children:[Y("strong",{children:"Connectors & wizard."})," Provides pre-built connectors and a wizard to link on-prem and cloud systems"]})]})]}),yt("div",{className:"space-y-4",children:[Y("h3",{className:"font-semibold text-xl",children:"Comparison with ContractSpec"}),Y("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:yt("table",{className:"w-full text-left text-sm",children:[Y("thead",{className:"bg-card/50",children:yt("tr",{className:"border-border/50 border-b",children:[Y("th",{className:"px-4 py-3 font-semibold",children:"Aspect"}),Y("th",{className:"px-4 py-3 font-semibold",children:"RunMyJobs"}),Y("th",{className:"px-4 py-3 font-semibold",children:"ContractSpec"})]})}),yt("tbody",{className:"divide-y divide-border/50",children:[yt("tr",{children:[Y("td",{className:"px-4 py-3 align-top",children:Y("strong",{children:"Target user"})}),Y("td",{className:"px-4 py-3 align-top",children:"Enterprise IT and operations teams automating SAP and mission-critical workflows."}),Y("td",{className:"px-4 py-3 align-top",children:"Developers, product teams and SMBs wanting to generate policy-safe apps with customisable UIs."})]}),yt("tr",{children:[Y("td",{className:"px-4 py-3 align-top",children:Y("strong",{children:"Workload focus"})}),Y("td",{className:"px-4 py-3 align-top",children:"Service orchestration and job scheduling across ERP/legacy systems"}),Y("td",{className:"px-4 py-3 align-top",children:"End-to-end application generation with back-end, UI and policies."})]}),yt("tr",{children:[Y("td",{className:"px-4 py-3 align-top",children:Y("strong",{children:"User interface"})}),Y("td",{className:"px-4 py-3 align-top",children:"Self-service portal to run/monitor jobs; no custom UI generation for new apps."}),Y("td",{className:"px-4 py-3 align-top",children:"Generates React/React-Native UIs from specs; users can personalise layout via overlays."})]}),yt("tr",{children:[Y("td",{className:"px-4 py-3 align-top",children:Y("strong",{children:"Open source"})}),Y("td",{className:"px-4 py-3 align-top",children:"Proprietary SaaS; enterprise agreements."}),Y("td",{className:"px-4 py-3 align-top",children:"Core compiler is proprietary; SDK and certain modules may be open-source; offers hosted and on-prem options."})]}),yt("tr",{children:[Y("td",{className:"px-4 py-3 align-top",children:Y("strong",{children:"Policy & personalisation"})}),Y("td",{className:"px-4 py-3 align-top",children:"IT controls governance; no per-user overlay concept."}),Y("td",{className:"px-4 py-3 align-top",children:"Built-in policy engine and per-user overlays for safe personalisation."})]})]})]})}),Y("p",{className:"text-muted-foreground",children:"Redwood RunMyJobs is designed for orchestrating enterprise workloads and SAP processes. ContractSpec targets a different problem: generating complete applications from typed specs and letting end users adapt them safely."})]})]})}import{jsx as W,jsxs as Bt}from"react/jsx-runtime";function Ep(){return Bt("div",{className:"space-y-8",children:[Bt("div",{className:"space-y-4",children:[W("h1",{className:"font-bold text-4xl",children:"Internal-tool builders"}),W("p",{className:"text-muted-foreground",children:"Internal-tool builders let teams quickly assemble dashboards and admin panels. These platforms often provide drag-and-drop UIs and connectors to databases and APIs, but they rely on developers to write custom code for business logic and seldom enforce policies across surfaces."})]}),Bt("div",{className:"space-y-4",children:[W("h2",{className:"font-bold text-2xl",children:"Feature comparison"}),W("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:Bt("table",{className:"w-full text-left text-sm",children:[W("thead",{className:"bg-card/50",children:Bt("tr",{className:"border-border/50 border-b",children:[W("th",{className:"px-4 py-3 font-semibold",children:"Feature"}),W("th",{className:"px-4 py-3 font-semibold",children:"Retool"}),W("th",{className:"px-4 py-3 font-semibold",children:"Appsmith"}),W("th",{className:"px-4 py-3 font-semibold",children:"ToolJet"}),W("th",{className:"px-4 py-3 font-semibold",children:"Budibase"})]})}),Bt("tbody",{className:"divide-y divide-border/50",children:[Bt("tr",{children:[W("td",{className:"px-4 py-3 align-top font-semibold",children:"UI builder"}),W("td",{className:"px-4 py-3 align-top",children:"Drag-and-drop canvas; shape UI components easily"}),W("td",{className:"px-4 py-3 align-top",children:"Visual builder with drag-and-drop widgets"}),W("td",{className:"px-4 py-3 align-top",children:"Drag-and-drop UI widgets (tables, charts, forms)"}),W("td",{className:"px-4 py-3 align-top",children:"Pre-built components and templates for mobile/desktop"})]}),Bt("tr",{children:[W("td",{className:"px-4 py-3 align-top font-semibold",children:"Custom code & logic"}),W("td",{className:"px-4 py-3 align-top",children:"Full code insertion anywhere via IDE"}),W("td",{className:"px-4 py-3 align-top",children:"Logic via JavaScript or natural-language prompts in a central IDE"}),W("td",{className:"px-4 py-3 align-top",children:"Supports business logic in JavaScript or Python queries"}),W("td",{className:"px-4 py-3 align-top",children:"Custom logic via JavaScript; plugins and external embeds"})]}),Bt("tr",{children:[W("td",{className:"px-4 py-3 align-top font-semibold",children:"Data connectors"}),W("td",{className:"px-4 py-3 align-top",children:"Wide support for databases and APIs (PostgreSQL, MongoDB, GraphQL, etc.)."}),W("td",{className:"px-4 py-3 align-top",children:"Connects to LLMs and databases"}),W("td",{className:"px-4 py-3 align-top",children:"Built-in database; connects to PostgreSQL, MongoDB, APIs, GraphQL, SaaS"}),W("td",{className:"px-4 py-3 align-top",children:"Connects to external databases, REST, CSV or built-in DB"})]}),Bt("tr",{children:[W("td",{className:"px-4 py-3 align-top font-semibold",children:"Open source & self-host"}),W("td",{className:"px-4 py-3 align-top",children:"Proprietary; cloud or on-prem subscription."}),W("td",{className:"px-4 py-3 align-top",children:"Open source (Apache-2.0); self-host or cloud."}),W("td",{className:"px-4 py-3 align-top",children:"Open source; self-host via Docker or cloud."}),W("td",{className:"px-4 py-3 align-top",children:"Open source; self-host via Docker/Kubernetes"})]}),Bt("tr",{children:[W("td",{className:"px-4 py-3 align-top font-semibold",children:"Policy & personalisation"}),W("td",{className:"px-4 py-3 align-top",children:"No built-in policy engine; personalisation limited to user roles."}),W("td",{className:"px-4 py-3 align-top",children:"No typed policy engine; customisation depends on user roles."}),W("td",{className:"px-4 py-3 align-top",children:"No policy engine; personalisation via user roles."}),W("td",{className:"px-4 py-3 align-top",children:"No policy engine; personalisation via RBAC & SSO"})]})]})]})})]}),Bt("div",{className:"space-y-3",children:[W("h2",{className:"font-bold text-2xl",children:"ContractSpec’s differences"}),Bt("ul",{className:"space-y-2 text-muted-foreground",children:[Bt("li",{children:[W("strong",{children:"Typed specifications"})," produce both the API and UI. You define capabilities, data views and workflows, and the compiler generates code, forms and screens—no manual widget wiring."]}),Bt("li",{children:[W("strong",{children:"Policy enforcement"})," at run time ensures PII and ABAC rules across the entire app."]}),Bt("li",{children:[W("strong",{children:"Overlay personalisation"})," allows tenants and users to change layouts safely without code."]}),Bt("li",{children:[W("strong",{children:"Unified mobile/web runtime"})," means you don’t need separate builders for React Native vs web."]})]}),W("p",{className:"text-muted-foreground",children:"Internal-tool builders are useful for quick dashboards. ContractSpec extends this by generating the whole stack from specs and enforcing policies throughout."})]})]})}import{jsx as Q,jsxs as to}from"react/jsx-runtime";function Op(){return to("div",{className:"space-y-8",children:[to("div",{className:"space-y-4",children:[Q("h1",{className:"font-bold text-4xl",children:"Comparison overview"}),Q("p",{className:"text-muted-foreground",children:"ContractSpec sits at the intersection of several tool categories. To appreciate its unique offering—typed specifications for back-end, front-end, workflows and policies with a unified web/mobile runtime—this section compares it to related products."}),to("p",{className:"text-muted-foreground",children:["ContractSpec uses ",Q("strong",{children:"runtime adapters"})," to serve typed"," ",Q("strong",{children:"Operations"})," (Commands/Queries),"," ",Q("strong",{children:"DataViews"}),", ",Q("strong",{children:"Workflows"}),", and"," ",Q("strong",{children:"Policies"})," as REST/GraphQL/MCP endpoints. A"," ",Q("strong",{children:"policy decision point"})," governs every operation, and"," ",Q("strong",{children:"OverlaySpecs"})," allow non-technical users to personalise screens safely. Few competitors offer this combination of runtime type safety, policy enforcement, and end-user customisation."]})]}),to("div",{className:"space-y-4",children:[Q("h2",{className:"font-bold text-2xl",children:"Tool categories"}),Q("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:to("table",{className:"w-full text-left text-sm",children:[Q("thead",{className:"bg-card/50",children:to("tr",{className:"border-border/50 border-b",children:[Q("th",{className:"px-4 py-3 font-semibold",children:"Category"}),Q("th",{className:"px-4 py-3 font-semibold",children:"Examples"}),Q("th",{className:"px-4 py-3 font-semibold",children:"What they do"}),Q("th",{className:"px-4 py-3 font-semibold",children:"Limitations"})]})}),to("tbody",{className:"divide-y divide-border/50",children:[to("tr",{children:[Q("td",{className:"px-4 py-3 align-top",children:Q("strong",{children:"Workflow engines"})}),Q("td",{className:"px-4 py-3 align-top",children:"Prefect, Kestra, Temporal, Airflow, Dagster, Hatchet, Windmill"}),Q("td",{className:"px-4 py-3 align-top",children:"Orchestrate code or data pipelines; handle retries, scheduling and observability"}),Q("td",{className:"px-4 py-3 align-top",children:"Require writing code; no automatic UI generation or policy enforcement."})]}),to("tr",{children:[Q("td",{className:"px-4 py-3 align-top",children:Q("strong",{children:"Internal-tool builders"})}),Q("td",{className:"px-4 py-3 align-top",children:"Retool, Appsmith, ToolJet, Budibase"}),Q("td",{className:"px-4 py-3 align-top",children:"Drag-and-drop dashboards and admin panels; connect to databases/APIs"}),Q("td",{className:"px-4 py-3 align-top",children:"No typed back-end spec; limited enforcement of policies; custom code glues logic."})]}),to("tr",{children:[Q("td",{className:"px-4 py-3 align-top",children:Q("strong",{children:"Automation platforms"})}),Q("td",{className:"px-4 py-3 align-top",children:"Zapier, Make, n8n, Pipedream"}),Q("td",{className:"px-4 py-3 align-top",children:"Connect apps via triggers and actions; visual or low-code interfaces"}),Q("td",{className:"px-4 py-3 align-top",children:"Automate tasks but do not generate full apps or enforce per-field policies."})]}),to("tr",{children:[Q("td",{className:"px-4 py-3 align-top",children:Q("strong",{children:"Enterprise orchestrators"})}),Q("td",{className:"px-4 py-3 align-top",children:"Redwood RunMyJobs"}),Q("td",{className:"px-4 py-3 align-top",children:"Automate mission-critical workloads with self-service portals and SAP integrations"}),Q("td",{className:"px-4 py-3 align-top",children:"Focus on IT workloads; not built for custom app creation or per-user customisation."})]})]})]})}),Q("p",{className:"text-muted-foreground",children:"Use the pages below to explore each group in detail and see how ContractSpec compares."})]})]})}import{jsx as z,jsxs as Je}from"react/jsx-runtime";function Bp(){return Je("div",{className:"space-y-8",children:[Je("div",{className:"space-y-4",children:[z("h1",{className:"font-bold text-4xl",children:"Windmill"}),Je("p",{className:"text-muted-foreground",children:["Windmill is an open-source platform that turns"," ",z("strong",{children:"scripts"})," into endpoints, workflows and UIs. It seeks to remove boilerplate by generating interfaces and workflows around existing code"]})]}),Je("div",{className:"space-y-4",children:[z("h2",{className:"font-bold text-2xl",children:"Platform features"}),Je("ul",{className:"space-y-3 text-muted-foreground",children:[Je("li",{children:[z("strong",{children:"Script-driven model."})," Write scripts in TypeScript, Python, Go, PHP, Bash, C#, SQL or Rust; Windmill infers dependencies, creates lockfiles and JSON schemas, then serves minimal UIs automatically"]}),Je("li",{children:[z("strong",{children:"Visual flow editor."})," Compose scripts into workflows with retries, error handling, loops, branching, suspending flows and approval steps"]}),Je("li",{children:[z("strong",{children:"Low-code UI builder."})," Build dashboards and admin panels using inline scripts and trigger flows from the UI"]}),Je("li",{children:[z("strong",{children:"Enterprise readiness."})," Features include RBAC permissions, secret management, OAuth handling, CLI/git sync, scheduling and webhooks"]}),Je("li",{children:[z("strong",{children:"Use cases."})," Deploy scripts as webhooks or cron jobs; create “applicative workflows” combining external APIs; build ETLs and interactive dashboards"]}),Je("li",{children:[z("strong",{children:"Open source & self-hosting."})," Windmill emphasises an open-source codebase and self-hosting options"]})]})]}),Je("div",{className:"space-y-4",children:[z("h2",{className:"font-bold text-2xl",children:"Comparison with ContractSpec"}),z("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:Je("table",{className:"w-full text-left text-sm",children:[z("thead",{className:"bg-card/50",children:Je("tr",{className:"border-border/50 border-b",children:[z("th",{className:"px-4 py-3 font-semibold",children:"Feature"}),z("th",{className:"px-4 py-3 font-semibold",children:"Windmill"}),z("th",{className:"px-4 py-3 font-semibold",children:"ContractSpec"})]})}),Je("tbody",{className:"divide-y divide-border/50",children:[Je("tr",{children:[z("td",{className:"px-4 py-3 align-top",children:z("strong",{children:"Entry model"})}),z("td",{className:"px-4 py-3 align-top",children:"Write scripts; platform auto-generates UI and workflows"}),z("td",{className:"px-4 py-3 align-top",children:"Define typed specs (Capabilities, DataViews, Workflows, Policies); compiler outputs back-end, front-end and forms."})]}),Je("tr",{children:[z("td",{className:"px-4 py-3 align-top",children:z("strong",{children:"Language support"})}),z("td",{className:"px-4 py-3 align-top",children:"20+ languages via embedded runtimes"}),z("td",{className:"px-4 py-3 align-top",children:"Uses TypeScript/JavaScript for providers; supports other back-ends through capability providers."})]}),Je("tr",{children:[z("td",{className:"px-4 py-3 align-top",children:z("strong",{children:"UI generation"})}),z("td",{className:"px-4 py-3 align-top",children:"Minimal UI forms from script parameters; low-code app builder"}),z("td",{className:"px-4 py-3 align-top",children:"Generates full web and mobile UIs from specs; user layouts can be customised via signed overlays."})]}),Je("tr",{children:[z("td",{className:"px-4 py-3 align-top",children:z("strong",{children:"Policy & personalization"})}),z("td",{className:"px-4 py-3 align-top",children:"RBAC and secret management; no per-user overlay concept"}),z("td",{className:"px-4 py-3 align-top",children:"Built-in policy engine enforcing ABAC/PII on every render/mutate; overlays allow safe per-user customisation."})]}),Je("tr",{children:[z("td",{className:"px-4 py-3 align-top",children:z("strong",{children:"Open source"})}),z("td",{className:"px-4 py-3 align-top",children:"Fully open source and self-hostable"}),z("td",{className:"px-4 py-3 align-top",children:"Closed-source core (SDK is open); offers hosted and on-prem modes."})]}),Je("tr",{children:[z("td",{className:"px-4 py-3 align-top",children:z("strong",{children:"Ideal for"})}),z("td",{className:"px-4 py-3 align-top",children:"Teams wanting to expose scripts as APIs, workflows or dashboards without heavy infrastructure."}),z("td",{className:"px-4 py-3 align-top",children:"Teams needing a spec-driven platform that generates code and UI, enforces policies and lets non-technical users tailor the experience."})]})]})]})}),Je("p",{className:"text-muted-foreground",children:["Windmill excels at converting scripts into workflows and admin panels. ContractSpec takes a ",z("strong",{children:"spec-first"})," approach, generating the entire stack and enforcing policies, making it suitable for long-lived applications that must evolve safely."]})]})]})}import{jsx as u,jsxs as bt}from"react/jsx-runtime";function Mp(){return bt("div",{className:"space-y-8",children:[bt("div",{className:"space-y-4",children:[u("h1",{className:"font-bold text-4xl",children:"Workflow engines"}),u("p",{className:"text-muted-foreground",children:"Workflow engines orchestrate long-running tasks and data pipelines. They provide retries, scheduling and visibility, but most expect developers to write code and do not generate user interfaces. Here’s how the major engines compare to ContractSpec."})]}),bt("div",{className:"space-y-4",children:[u("h2",{className:"font-bold text-2xl",children:"Key differences summary"}),u("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:bt("table",{className:"w-full text-left text-sm",children:[u("thead",{className:"bg-card/50",children:bt("tr",{className:"border-border/50 border-b",children:[u("th",{className:"px-4 py-3 font-semibold",children:"Engine"}),u("th",{className:"px-4 py-3 font-semibold",children:"Core strengths"}),u("th",{className:"px-4 py-3 font-semibold",children:"UI generation?"}),u("th",{className:"px-4 py-3 font-semibold",children:"Policy/PII enforcement?"}),u("th",{className:"px-4 py-3 font-semibold",children:"Self-host?"}),u("th",{className:"px-4 py-3 font-semibold",children:"Primary use"})]})}),bt("tbody",{className:"divide-y divide-border/50",children:[bt("tr",{children:[u("td",{className:"px-4 py-3 align-top",children:u("strong",{children:"Prefect"})}),u("td",{className:"px-4 py-3 align-top",children:"Python-native; dynamic DAGs adapt to change; annotate code without rewriting; strong observability and audit logs"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"Yes"}),u("td",{className:"px-4 py-3 align-top",children:"Data pipelines and dynamic workflows."})]}),bt("tr",{children:[u("td",{className:"px-4 py-3 align-top",children:u("strong",{children:"Kestra"})}),u("td",{className:"px-4 py-3 align-top",children:"Declarative YAML; event-driven triggers; mix of code and no-code; write logic in Python/R/Java/Julia/Ruby; deploy anywhere"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"Yes"}),u("td",{className:"px-4 py-3 align-top",children:"Data pipelines and hybrid orchestration."})]}),bt("tr",{children:[u("td",{className:"px-4 py-3 align-top",children:u("strong",{children:"Temporal"})}),u("td",{className:"px-4 py-3 align-top",children:"Durable execution; workflows never lose state; multi-language SDKs; automatic retries"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"Yes"}),u("td",{className:"px-4 py-3 align-top",children:"Durable microservice and business workflows."})]}),bt("tr",{children:[u("td",{className:"px-4 py-3 align-top",children:u("strong",{children:"Airflow"})}),u("td",{className:"px-4 py-3 align-top",children:"Open-source; define workflows as Python code; schedule and monitor via UI; extensible via custom operators"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"Yes"}),u("td",{className:"px-4 py-3 align-top",children:"Data ETL pipelines."})]}),bt("tr",{children:[u("td",{className:"px-4 py-3 align-top",children:u("strong",{children:"Dagster"})}),u("td",{className:"px-4 py-3 align-top",children:"Data-asset model; local testing and reusable components; built-in data quality and catalog; orchestrates AI/data pipelines across multiple tools"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"Yes"}),u("td",{className:"px-4 py-3 align-top",children:"Data/AI pipelines with strong observability."})]}),bt("tr",{children:[u("td",{className:"px-4 py-3 align-top",children:u("strong",{children:"Hatchet"})}),u("td",{className:"px-4 py-3 align-top",children:"Modern engine focused on performance and durability; tasks and workflows as code; durable functions with guardrails and retries"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"No"}),u("td",{className:"px-4 py-3 align-top",children:"Yes"}),u("td",{className:"px-4 py-3 align-top",children:"High-throughput background jobs and microservices."})]}),bt("tr",{children:[u("td",{className:"px-4 py-3 align-top",children:u("strong",{children:"Windmill"})}),u("td",{className:"px-4 py-3 align-top",children:"Multi-language scripts; auto-generates UI; integrated flow editor"}),u("td",{className:"px-4 py-3 align-top",children:"Yes (basic)"}),u("td",{className:"px-4 py-3 align-top",children:"RBAC & secrets only"}),u("td",{className:"px-4 py-3 align-top",children:"Yes"}),u("td",{className:"px-4 py-3 align-top",children:"Scripts into workflows and dashboards."})]})]})]})})]}),bt("div",{className:"space-y-3",children:[u("h2",{className:"font-bold text-2xl",children:"Why ContractSpec differs"}),bt("ul",{className:"space-y-2 text-muted-foreground",children:[bt("li",{children:[u("strong",{children:"Spec-first generation"})," – Instead of writing code, you define typed specs for capabilities, data views and workflows; the compiler outputs both back-end and front-end."]}),bt("li",{children:[u("strong",{children:"Policy engine"})," – Every render and mutate passes through an ABAC/PII policy decision point."]}),bt("li",{children:[u("strong",{children:"Personalisation"})," – Signed OverlaySpecs allow tenant/user-specific UI changes without touching code."]}),bt("li",{children:[u("strong",{children:"Unified runtime"})," – React/React-Native rendering ensures consistent experiences across web and mobile."]})]}),u("p",{className:"text-muted-foreground",children:"Workflow engines are excellent for orchestrating back-end tasks. ContractSpec builds on this by serving complete applications with runtime policy enforcement and user personalisation via TypeScript specs."})]})]})}import{CodeBlock as Up}from"@contractspec/lib.design-system";import Tc from"@contractspec/lib.ui-link";import{ChevronRight as Wp}from"lucide-react";import{jsx as ia,jsxs as ni}from"react/jsx-runtime";function _p(){return ni("div",{className:"space-y-8",children:[ni("div",{className:"space-y-3",children:[ia("h1",{className:"font-bold text-4xl",children:"Integrations"}),ia("p",{className:"text-lg text-muted-foreground",children:"Reference integrations show how to extend ContractSpec with real-world adapters and generators."})]}),ni("div",{className:"card-subtle space-y-4 p-6",children:[ia("h2",{className:"font-bold text-2xl",children:"Reference plugin"}),ia("p",{className:"text-muted-foreground text-sm",children:"The example markdown generator plugin ships as a working reference implementation."}),ia(Up,{language:"bash",filename:"install-example",code:`bun add @contractspec/lib.plugin.example-generator
|
|
671
671
|
|
|
672
672
|
# Or in a workspace
|
|
673
|
-
bun add -D @contractspec/lib.plugin.example-generator`})]}),ni("div",{className:"card-subtle space-y-4 p-6",children:[ia("h2",{className:"font-bold text-2xl",children:"Providers and adapters"}),ni("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[ia("li",{children:"Payments: Stripe"}),ia("li",{children:"Email: Postmark, Gmail"}),ia("li",{children:"AI: OpenAI, Mistral"}),ia("li",{children:"Voice: ElevenLabs, Mistral"}),ia("li",{children:"Vector DB: Qdrant"}),ia("li",{children:"Storage: GCS"})]}),ia("p",{className:"text-muted-foreground text-sm",children:"Use provider modules as inspiration for adapter plugins."})]}),ni("div",{className:"flex items-center gap-4 pt-4",children:[ni(
|
|
673
|
+
bun add -D @contractspec/lib.plugin.example-generator`})]}),ni("div",{className:"card-subtle space-y-4 p-6",children:[ia("h2",{className:"font-bold text-2xl",children:"Providers and adapters"}),ni("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[ia("li",{children:"Payments: Stripe"}),ia("li",{children:"Email: Postmark, Gmail"}),ia("li",{children:"AI: OpenAI, Mistral"}),ia("li",{children:"Voice: ElevenLabs, Mistral"}),ia("li",{children:"Vector DB: Qdrant"}),ia("li",{children:"Storage: GCS"})]}),ia("p",{className:"text-muted-foreground text-sm",children:"Use provider modules as inspiration for adapter plugins."})]}),ni("div",{className:"flex items-center gap-4 pt-4",children:[ni(Tc,{href:"/docs/ecosystem/registry",className:"btn-primary",children:["Marketplace manifest ",ia(Wp,{size:16})]}),ia(Tc,{href:"/docs/ecosystem/templates",className:"btn-ghost",children:"Authoring templates"})]})]})}import{CodeBlock as Vr}from"@contractspec/lib.design-system";import Ac from"@contractspec/lib.ui-link";import{ChevronRight as zp}from"lucide-react";import{jsx as _e,jsxs as ra}from"react/jsx-runtime";function Gp(){return ra("div",{className:"space-y-8",children:[ra("div",{className:"space-y-3",children:[_e("h1",{className:"font-bold text-4xl",children:"Cursor marketplace plugins"}),_e("p",{className:"text-lg text-muted-foreground",children:"ContractSpec ships a focused Cursor marketplace catalog for the product and key libraries."})]}),ra("div",{className:"card-subtle space-y-4 p-6",children:[_e("h2",{className:"font-bold text-2xl",children:"Catalog at a glance"}),ra("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[ra("li",{children:[_e("code",{children:"contractspec"})," - Product-level workflow and release guardrails."]}),ra("li",{children:[_e("code",{children:"contractspec-contracts-spec"})," -",_e("code",{children:"@contractspec/lib.contracts-spec"})," governance."]}),ra("li",{children:[_e("code",{children:"contractspec-contracts-integrations"})," -",_e("code",{children:"@contractspec/lib.contracts-integrations"})," governance."]}),ra("li",{children:[_e("code",{children:"contractspec-ai-agent"})," -",_e("code",{children:"@contractspec/lib.ai-agent"})," orchestration guardrails."]})]})]}),ra("div",{className:"space-y-6",children:[ra("div",{className:"space-y-3",children:[_e("h2",{className:"font-bold text-2xl",children:"Where plugin sources live"}),_e("p",{className:"text-muted-foreground text-sm",children:"Marketplace plugin artifacts are kept in a dedicated package, while the canonical reusable source lives in agentpacks under `packs/`."}),_e(Vr,{language:"text",filename:"catalog-layout",code:`packages/apps-registry/cursor-marketplace/
|
|
674
674
|
.cursor-plugin/marketplace.json
|
|
675
675
|
plugins/
|
|
676
676
|
contractspec/
|
|
@@ -679,7 +679,7 @@ bun add -D @contractspec/lib.plugin.example-generator`})]}),ni("div",{className:
|
|
|
679
679
|
contractspec-ai-agent/
|
|
680
680
|
|
|
681
681
|
packs/
|
|
682
|
-
contractspec-contracts-spec/`})]}),ra("div",{className:"space-y-3",children:[_e("h2",{className:"font-bold text-2xl",children:"Root marketplace manifest"}),_e("p",{className:"text-muted-foreground text-sm",children:"Cursor submission reads the catalog manifest inside the marketplace package and resolves plugin paths relative to that package."}),_e(
|
|
682
|
+
contractspec-contracts-spec/`})]}),ra("div",{className:"space-y-3",children:[_e("h2",{className:"font-bold text-2xl",children:"Root marketplace manifest"}),_e("p",{className:"text-muted-foreground text-sm",children:"Cursor submission reads the catalog manifest inside the marketplace package and resolves plugin paths relative to that package."}),_e(Vr,{language:"json",filename:"packages/apps-registry/cursor-marketplace/.cursor-plugin/marketplace.json",code:`{
|
|
683
683
|
"name": "contractspec-marketplace",
|
|
684
684
|
"owner": { "name": "ContractSpec Team" },
|
|
685
685
|
"plugins": [
|
|
@@ -700,10 +700,10 @@ packs/
|
|
|
700
700
|
"source": "plugins/contractspec-ai-agent"
|
|
701
701
|
}
|
|
702
702
|
]
|
|
703
|
-
}`})]}),ra("div",{className:"space-y-3",children:[_e("h2",{className:"font-bold text-2xl",children:"Generated multi-host system"}),_e("p",{className:"text-muted-foreground text-sm",children:"The Cursor plugin is publishable metadata only. Customer-facing Cursor, Claude Code, and Codex outputs are generated from the same pack source with hook and MCP delivery."})]}),ra("div",{className:"space-y-3",children:[_e("h2",{className:"font-bold text-2xl",children:"Validation gate"}),_e("p",{className:"text-muted-foreground text-sm",children:"Validate all marketplace plugins before publishing."}),_e(
|
|
703
|
+
}`})]}),ra("div",{className:"space-y-3",children:[_e("h2",{className:"font-bold text-2xl",children:"Generated multi-host system"}),_e("p",{className:"text-muted-foreground text-sm",children:"The Cursor plugin is publishable metadata only. Customer-facing Cursor, Claude Code, and Codex outputs are generated from the same pack source with hook and MCP delivery."})]}),ra("div",{className:"space-y-3",children:[_e("h2",{className:"font-bold text-2xl",children:"Validation gate"}),_e("p",{className:"text-muted-foreground text-sm",children:"Validate all marketplace plugins before publishing."}),_e(Vr,{language:"bash",filename:"validate-marketplace",code:`bun run plugin:contractspec:validate
|
|
704
704
|
|
|
705
705
|
# Optional when offline
|
|
706
|
-
SKIP_PLUGIN_NETWORK_CHECK=1 bun run plugin:contractspec:validate`})]})]}),ra("div",{className:"flex items-center gap-4 pt-4",children:[ra(
|
|
706
|
+
SKIP_PLUGIN_NETWORK_CHECK=1 bun run plugin:contractspec:validate`})]})]}),ra("div",{className:"flex items-center gap-4 pt-4",children:[ra(Ac,{href:"/docs/ecosystem/templates",className:"btn-primary",children:["Author a plugin ",_e(zp,{size:16})]}),_e(Ac,{href:"/docs/ecosystem/registry",className:"btn-ghost",children:"Manifest details"})]})]})}import{CodeBlock as Fr}from"@contractspec/lib.design-system";import Rc from"@contractspec/lib.ui-link";import{ChevronRight as qp}from"lucide-react";import{jsx as ao,jsxs as ci}from"react/jsx-runtime";function Hp(){return ci("div",{className:"space-y-8",children:[ci("div",{className:"space-y-3",children:[ao("h1",{className:"font-bold text-4xl",children:"Marketplace manifest"}),ao("p",{className:"text-lg text-muted-foreground",children:"ContractSpec publishes a multi-plugin Cursor marketplace catalog from a single root manifest."})]}),ci("div",{className:"card-subtle space-y-4 p-6",children:[ao("h2",{className:"font-bold text-2xl",children:"Root manifest shape"}),ci("p",{className:"text-muted-foreground text-sm",children:["Cursor reads"," ",ao("code",{children:"packages/apps-registry/cursor-marketplace/.cursor-plugin/marketplace.json"})," ","for the catalog and resolves each plugin source path from there."]}),ao(Fr,{language:"json",filename:"packages/apps-registry/cursor-marketplace/.cursor-plugin/marketplace.json",code:`{
|
|
707
707
|
"name": "contractspec-marketplace",
|
|
708
708
|
"owner": { "name": "ContractSpec Team" },
|
|
709
709
|
"plugins": [
|
|
@@ -716,16 +716,16 @@ SKIP_PLUGIN_NETWORK_CHECK=1 bun run plugin:contractspec:validate`})]})]}),ra("di
|
|
|
716
716
|
"source": "plugins/contractspec-contracts-spec"
|
|
717
717
|
}
|
|
718
718
|
]
|
|
719
|
-
}`})]}),ci("div",{className:"card-subtle space-y-4 p-6",children:[ao("h2",{className:"font-bold text-2xl",children:"Per-plugin contract"}),ao("p",{className:"text-muted-foreground text-sm",children:"Each plugin source must include a Cursor plugin manifest and composable assets. The publishable plugin is derived from a reusable pack and then validated here."}),ao(
|
|
719
|
+
}`})]}),ci("div",{className:"card-subtle space-y-4 p-6",children:[ao("h2",{className:"font-bold text-2xl",children:"Per-plugin contract"}),ao("p",{className:"text-muted-foreground text-sm",children:"Each plugin source must include a Cursor plugin manifest and composable assets. The publishable plugin is derived from a reusable pack and then validated here."}),ao(Fr,{language:"text",filename:"plugin-layout",code:`plugins/<plugin-name>/
|
|
720
720
|
.cursor-plugin/plugin.json
|
|
721
721
|
rules/
|
|
722
722
|
commands/
|
|
723
723
|
agents/
|
|
724
724
|
skills/
|
|
725
|
-
.mcp.json`}),ao(
|
|
725
|
+
.mcp.json`}),ao(Fr,{language:"bash",filename:"validate-catalog",code:`bun run plugin:contractspec:validate
|
|
726
726
|
|
|
727
727
|
# Optional in offline environments
|
|
728
|
-
SKIP_PLUGIN_NETWORK_CHECK=1 bun run plugin:contractspec:validate`})]}),ci("div",{className:"flex items-center gap-4 pt-4",children:[ci(
|
|
728
|
+
SKIP_PLUGIN_NETWORK_CHECK=1 bun run plugin:contractspec:validate`})]}),ci("div",{className:"flex items-center gap-4 pt-4",children:[ci(Rc,{href:"/docs/ecosystem/integrations",className:"btn-primary",children:["Integrations ",ao(qp,{size:16})]}),ao(Rc,{href:"/docs/ecosystem/templates",className:"btn-ghost",children:"Plugin authoring templates"})]})]})}import Vp from"@contractspec/lib.ui-link";import{jsx as Kr,jsxs as Fp}from"react/jsx-runtime";function qt({title:e="Need the operating layer on top of OSS ContractSpec?",body:t="ContractSpec Studio helps teams turn evidence into proposed spec changes, governed delivery loops, and execution-ready task packs while keeping the open contract system as the source of truth.",ctaLabel:a="See what Studio adds",href:r="https://www.contractspec.studio/docs"}){return Fp("div",{className:"card-subtle space-y-3 p-6",children:[Kr("h3",{className:"font-semibold text-lg",children:e}),Kr("p",{className:"text-muted-foreground text-sm",children:t}),Kr(Vp,{href:r,className:"btn-primary",children:a})]})}import{CodeBlock as Lc}from"@contractspec/lib.design-system";import Dc from"@contractspec/lib.ui-link";import{ChevronRight as Kp}from"lucide-react";import{jsx as na,jsxs as Ko}from"react/jsx-runtime";function Qp(){return Ko("div",{className:"space-y-8",children:[Ko("div",{className:"space-y-3",children:[na("h1",{className:"font-bold text-4xl",children:"Plugin authoring templates"}),na("p",{className:"text-lg text-muted-foreground",children:"Scaffold focused Cursor plugins for ContractSpec product and core libraries."})]}),Ko("div",{className:"card-subtle space-y-4 p-6",children:[na("h2",{className:"font-bold text-2xl",children:"Create a focused plugin"}),na("p",{className:"text-muted-foreground text-sm",children:"Start from a scoped domain and keep each plugin aligned to one product or library surface."}),na(Lc,{language:"bash",filename:"catalog-authoring-layout",code:`packages/apps-registry/cursor-marketplace/
|
|
729
729
|
plugins/
|
|
730
730
|
<plugin-name>/
|
|
731
731
|
.cursor-plugin/plugin.json
|
|
@@ -733,14 +733,14 @@ SKIP_PLUGIN_NETWORK_CHECK=1 bun run plugin:contractspec:validate`})]}),ci("div",
|
|
|
733
733
|
commands/
|
|
734
734
|
agents/
|
|
735
735
|
skills/
|
|
736
|
-
.mcp.json`})]}),Ko("div",{className:"card-subtle space-y-4 p-6",children:[na("h2",{className:"font-bold text-2xl",children:"Template outputs"}),Ko("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[na("li",{children:".cursor-plugin/plugin.json with plugin metadata and paths"}),na("li",{children:"rules/, commands/, agents/, and skills/ content directories"}),na("li",{children:".mcp.json with all MCP server declarations used by the plugin"}),na("li",{children:"README.md describing scope and governance boundaries"})]})]}),Ko("div",{className:"card-subtle space-y-4 p-6",children:[na("h2",{className:"font-bold text-2xl",children:"Validate before submission"}),na(
|
|
736
|
+
.mcp.json`})]}),Ko("div",{className:"card-subtle space-y-4 p-6",children:[na("h2",{className:"font-bold text-2xl",children:"Template outputs"}),Ko("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[na("li",{children:".cursor-plugin/plugin.json with plugin metadata and paths"}),na("li",{children:"rules/, commands/, agents/, and skills/ content directories"}),na("li",{children:".mcp.json with all MCP server declarations used by the plugin"}),na("li",{children:"README.md describing scope and governance boundaries"})]})]}),Ko("div",{className:"card-subtle space-y-4 p-6",children:[na("h2",{className:"font-bold text-2xl",children:"Validate before submission"}),na(Lc,{language:"bash",filename:"validate-marketplace-catalog",code:`# Validate all plugins referenced by root marketplace manifest
|
|
737
737
|
bun run plugin:contractspec:validate
|
|
738
738
|
|
|
739
739
|
# Optional in offline environments
|
|
740
|
-
SKIP_PLUGIN_NETWORK_CHECK=1 bun run plugin:contractspec:validate`})]}),na(qt,{title:"Need evidence-backed template iteration?",body:"Studio helps teams prioritize template changes from real product signals and export implementation-ready task packs."}),Ko("div",{className:"flex items-center gap-4 pt-4",children:[Ko(
|
|
740
|
+
SKIP_PLUGIN_NETWORK_CHECK=1 bun run plugin:contractspec:validate`})]}),na(qt,{title:"Need evidence-backed template iteration?",body:"Studio helps teams prioritize template changes from real product signals and export implementation-ready task packs."}),Ko("div",{className:"flex items-center gap-4 pt-4",children:[Ko(Dc,{href:"/docs/ecosystem/plugins",className:"btn-primary",children:["Marketplace plugins ",na(Kp,{size:16})]}),na(Dc,{href:"/docs/ecosystem/registry",className:"btn-ghost",children:"Marketplace manifest"})]})]})}import{registerDocBlocks as Yp}from"@contractspec/lib.contracts-spec/docs";var Jp=[{id:"docs.ecosystem.plugins",title:"Marketplace plugins",summary:"Focused Cursor marketplace plugins for product and core libraries.",kind:"usage",visibility:"public",route:"/docs/ecosystem/plugins",tags:["ecosystem","plugins","extensions"],body:"# Marketplace plugins\n\nContractSpec ships a focused Cursor marketplace catalog with plugins for the product and key libraries. Plugin sources live in `packages/apps-registry/cursor-marketplace/plugins/*`, while the root manifest at `.cursor-plugin/marketplace.json` drives submission."},{id:"docs.ecosystem.integrations",title:"Integrations",summary:"Reference plugins and integrations you can extend.",kind:"usage",visibility:"public",route:"/docs/ecosystem/integrations",tags:["ecosystem","integrations"],body:`# Integrations
|
|
741
741
|
|
|
742
|
-
Reference integrations demonstrate how to extend ContractSpec with real-world plugins. Use them as starting points for your own adapters and generators.`},{id:"docs.ecosystem.templates",title:"Plugin authoring templates",summary:"Author focused plugins with a consistent marketplace-ready layout.",kind:"usage",visibility:"public",route:"/docs/ecosystem/templates",tags:["ecosystem","templates"],body:"# Plugin authoring templates\n\nCreate each plugin under `packages/apps-registry/cursor-marketplace/plugins/<plugin-name>/` and include `.cursor-plugin/plugin.json`, `rules/`, `commands/`, `agents/`, `skills/`, and `.mcp.json`."},{id:"docs.ecosystem.registry",title:"Marketplace manifest",summary:"Manage and validate root marketplace entries for all plugins.",kind:"usage",visibility:"public",route:"/docs/ecosystem/registry",tags:["ecosystem","registry"],body:"# Marketplace manifest\n\nKeep all plugin entries in `.cursor-plugin/marketplace.json` and validate them with `bun run plugin:contractspec:validate` before submission."}];
|
|
743
|
-
`)}import{ButtonLink as Pi,CodeBlock as
|
|
742
|
+
Reference integrations demonstrate how to extend ContractSpec with real-world plugins. Use them as starting points for your own adapters and generators.`},{id:"docs.ecosystem.templates",title:"Plugin authoring templates",summary:"Author focused plugins with a consistent marketplace-ready layout.",kind:"usage",visibility:"public",route:"/docs/ecosystem/templates",tags:["ecosystem","templates"],body:"# Plugin authoring templates\n\nCreate each plugin under `packages/apps-registry/cursor-marketplace/plugins/<plugin-name>/` and include `.cursor-plugin/plugin.json`, `rules/`, `commands/`, `agents/`, `skills/`, and `.mcp.json`."},{id:"docs.ecosystem.registry",title:"Marketplace manifest",summary:"Manage and validate root marketplace entries for all plugins.",kind:"usage",visibility:"public",route:"/docs/ecosystem/registry",tags:["ecosystem","registry"],body:"# Marketplace manifest\n\nKeep all plugin entries in `.cursor-plugin/marketplace.json` and validate them with `bun run plugin:contractspec:validate` before submission."}];Yp(Jp);import{ExampleCatalogDataView as Ec}from"@contractspec/lib.contracts-spec/docs";import{ButtonLink as Oc,DataViewList as Zp,StatusChip as $p}from"@contractspec/lib.design-system";import{HStack as Xp,VStack as Bc}from"@contractspec/lib.ui-kit-web/ui/stack";import{H1 as xp,Muted as Mc}from"@contractspec/lib.ui-kit-web/ui/typography";import{buildExampleDocsHref as jp,listDiscoverableExamples as em}from"@contractspec/module.examples/catalog";import{jsx as li,jsxs as Qr}from"react/jsx-runtime";function tm(){let e=em().map((a)=>{let r=a.meta.title??a.meta.key;return{id:a.meta.key,title:r,summary:a.meta.summary??a.meta.description,route:jp(a.meta.key),tags:a.meta.tags,sandboxEnabled:a.surfaces.sandbox.enabled}}).sort((a,r)=>a.title.localeCompare(r.title)),t={...Ec,view:{...Ec.view,kind:"list"}};return Qr(Bc,{gap:"xl",children:[Qr(Bc,{gap:"sm",children:[li(xp,{children:"Examples"}),li(Mc,{children:"Reference implementations for real ContractSpec surfaces. Use them to study adoption patterns, inspect generated artifacts, and validate the OSS workflow against runnable systems."})]}),li(Zp,{spec:t,items:e,emptyState:li(Mc,{children:"No examples available."}),renderActions:(a)=>{return Qr(Xp,{gap:"xs",justify:"end",children:[a.sandboxEnabled?li(Oc,{href:`/sandbox?template=${a.id}`,size:"sm",variant:"outline",children:"Sandbox"}):null,li(Oc,{href:a.route,size:"sm",children:"Reference"}),a.tags?.[0]?li($p,{size:"sm",label:a.tags[0]}):null]})}})]})}import{buildExampleDocsHref as am,buildExampleReferenceHref as om,getDiscoverableExample as im,getExamplePreviewHref as rm}from"@contractspec/module.examples/catalog";var nm={"agent-console":"Primary meetup path for autonomous agents: typed tools, agent configs, run history, and execution logs in one regenerable surface.","ai-chat-assistant":"Secondary meetup path for MCP-aware assistants: reasoning, sources, suggestions, and a minimal contract-backed search tool.","data-grid-showcase":"Canonical table example for the full ContractSpec stack: declarative DataView contract, shared controller, raw web primitive, native-first primitive, and the composed design-system wrapper.","messaging-agent-actions":"Live messaging lane for the meetup: inbound Slack, WhatsApp, or Telegram messages route through fixed intents, allowlisted actions, and deterministic confirmations."},cm={"agent-console":"/docs/reference/agent-console/agent-console","ai-chat-assistant":"/docs/reference/ai-chat-assistant/assistant.search","data-grid-showcase":"/docs/reference/data-grid-showcase/data-grid-showcase","messaging-agent-actions":"/docs/reference/messaging-agent-actions/messaging.agentActions.process"};function Uc(e){let t=im(e);if(!t)return;let a=t.entrypoints.packageName.replace("@contractspec/example.",""),r=am(e),l=rm(e);return{key:e,lead:nm[e]??t.meta.summary??t.meta.description??"Public ContractSpec reference example.",sandboxHref:l,referenceHref:cm[e]??om(e),llmsHref:`/llms/${t.entrypoints.packageName.replace("@contractspec/","")}`,repoHref:`https://github.com/lssm-tech/contractspec/tree/main/packages/examples/${a}`,localCommands:lm(a,r,l)}}function lm(e,t,a){let r=[`bun run --cwd packages/examples/${e} build`,"bun run --cwd packages/apps/web-landing dev","","# Open in the browser",`# http://localhost:3000${t}`];if(a)r.push(`# http://localhost:3000${a}`);return r.join(`
|
|
743
|
+
`)}import{ButtonLink as Pi,CodeBlock as dm}from"@contractspec/lib.design-system";import sm from"@contractspec/lib.ui-link";import{getExample as pm}from"@contractspec/module.examples/catalog";import{FileCode2 as mm,Play as um,TerminalSquare as gm}from"lucide-react";import{jsx as Ne,jsxs as ka}from"react/jsx-runtime";function fm({exampleKey:e}){let t=Uc(e),a=pm(e);if(!t||!a)return null;let r=a.meta.title??a.meta.key,l=a.meta.summary??a.meta.description??"",b=a.entrypoints.packageName;return ka("div",{className:"space-y-10",children:[ka("section",{className:"space-y-5",children:[Ne("p",{className:"editorial-kicker",children:"Meetup-ready example"}),Ne("h1",{className:"editorial-title max-w-5xl",children:r}),Ne("p",{className:"editorial-subtitle",children:t.lead}),Ne("p",{className:"editorial-copy max-w-4xl",children:l}),ka("div",{className:"flex flex-wrap gap-3",children:[t.sandboxHref?Ne(Pi,{href:t.sandboxHref,children:"Open sandbox"}):null,Ne(Pi,{href:t.referenceHref,variant:"outline",children:"Generated reference"})]})]}),ka("section",{className:"grid gap-5 lg:grid-cols-3",children:[t.sandboxHref?ka("article",{className:"editorial-panel space-y-4",children:[ka("div",{className:"flex items-center gap-3",children:[Ne("div",{className:"rounded-full border border-border/80 bg-background/85 p-2",children:Ne(um,{size:18})}),Ne("h2",{className:"font-semibold text-xl",children:"Sandbox preview"})]}),Ne("p",{className:"editorial-copy text-sm",children:"Load the same public browser surface used for the prepared live demo."}),Ne(Pi,{href:t.sandboxHref,size:"sm",children:"Open preview"})]}):null,ka("article",{className:"editorial-panel space-y-4",children:[ka("div",{className:"flex items-center gap-3",children:[Ne("div",{className:"rounded-full border border-border/80 bg-background/85 p-2",children:Ne(mm,{size:18})}),Ne("h2",{className:"font-semibold text-xl",children:"Reference docs"})]}),Ne("p",{className:"editorial-copy text-sm",children:"Inspect the generated contract-facing material instead of relying on marketing summaries."}),Ne(Pi,{href:t.referenceHref,size:"sm",variant:"outline",children:"Open reference"})]}),ka("article",{className:"editorial-panel space-y-4",children:[ka("div",{className:"flex items-center gap-3",children:[Ne("div",{className:"rounded-full border border-border/80 bg-background/85 p-2",children:Ne(gm,{size:18})}),Ne("h2",{className:"font-semibold text-xl",children:"Package context"})]}),Ne("p",{className:"editorial-copy text-sm",children:"Use the agent-facing package page for fast repo orientation, then jump to the source directory."}),Ne("p",{className:"rounded-[18px] border border-border/70 bg-background/75 px-4 py-3 font-mono text-sm",children:b}),ka("div",{className:"flex flex-wrap gap-2",children:[Ne(Pi,{href:t.llmsHref,size:"sm",variant:"outline",children:"LLMS page"}),Ne(Pi,{href:t.repoHref,size:"sm",variant:"outline",children:"GitHub source"})]})]})]}),ka("section",{className:"editorial-panel space-y-5",children:[ka("div",{className:"space-y-2",children:[Ne("p",{className:"editorial-kicker",children:"Talk commands"}),Ne("h2",{className:"editorial-panel-title",children:"Exact local commands for the meetup lane"}),Ne("p",{className:"editorial-copy text-sm",children:"Build the example package, then launch the web shell and open the prepared docs or sandbox route."})]}),Ne(dm,{language:"bash",filename:`${e}-meetup-runbook`,code:t.localCommands}),ka("p",{className:"text-muted-foreground text-sm",children:["For the full fallback order and safe live-edit workflow, use"," ",Ne(sm,{href:"https://github.com/lssm-tech/contractspec/blob/main/docs/meetup-agent-examples-runbook.md",children:"the meetup runbook"}),"."]})]})]})}async function w2(){let{getDocsIndexManifest:e}=await Promise.resolve().then(() => (gr(),ur));return e()}async function Gc(){let{listGeneratedDocs:e}=await Promise.resolve().then(() => (gr(),ur));return e()}async function k2(e){let{getGeneratedDocById:t}=await Promise.resolve().then(() => (gr(),ur));return t(e)}import{CodeBlock as fr,InstallCommand as Cm}from"@contractspec/lib.design-system";import qc from"@contractspec/lib.ui-link";import{ChevronRight as Im}from"lucide-react";import{jsx as ge,jsxs as St}from"react/jsx-runtime";function Pm(){return St("div",{className:"space-y-8",children:[St("div",{className:"space-y-2",children:[ge("h1",{className:"font-bold text-4xl",children:"ContractSpec CLI"}),ge("p",{className:"text-lg text-muted-foreground",children:"Command-line interface for creating, building, and validating contract specifications with AI-powered code generation."})]}),St("div",{className:"space-y-6",children:[St("div",{className:"space-y-3",children:[ge("h2",{className:"font-bold text-2xl",children:"Installation"}),ge(Cm,{package:"contractspec",dev:!0})]}),St("div",{className:"space-y-3",children:[ge("h2",{className:"font-bold text-2xl",children:"Quick Start"}),ge(fr,{language:"bash",code:`# Initialize project
|
|
744
744
|
contractspec onboard
|
|
745
745
|
bunx contractspec init
|
|
746
746
|
|
|
@@ -765,7 +765,7 @@ contractspec validate`})]}),St("div",{className:"space-y-4",children:[ge("h2",{c
|
|
|
765
765
|
"operations": "interactions/commands|queries",
|
|
766
766
|
"events": "events"
|
|
767
767
|
}
|
|
768
|
-
}`})]})]}),St("div",{className:"flex items-center gap-4 pt-4",children:[St(
|
|
768
|
+
}`})]})]}),St("div",{className:"flex items-center gap-4 pt-4",children:[St(qc,{href:"/docs/getting-started/tools/vscode",className:"btn-primary",children:["Next: VS Code Extension ",ge(Im,{size:16})]}),ge(qc,{href:"/docs/getting-started/tools",className:"btn-ghost",children:"Back to Tools"})]})]})}import hr from"@contractspec/lib.ui-link";import{ChevronRight as Tm}from"lucide-react";import{jsx as Ce,jsxs as Mt}from"react/jsx-runtime";function Am(){return Mt("div",{className:"space-y-8",children:[Mt("div",{className:"space-y-2",children:[Ce("h1",{className:"font-bold text-4xl",children:"Compatibility"}),Ce("p",{className:"text-lg text-muted-foreground",children:"Supported runtimes, frameworks, and agent modes for ContractSpec."})]}),Mt("div",{className:"space-y-6",children:[Mt("div",{className:"card-subtle space-y-3 p-6",children:[Ce("h2",{className:"font-bold text-2xl",children:"Runtimes"}),Mt("ul",{className:"space-y-2 text-muted-foreground",children:[Ce("li",{children:"Node.js 20+"}),Ce("li",{children:"Bun 1.0+"})]})]}),Mt("div",{className:"card-subtle space-y-3 p-6",children:[Ce("h2",{className:"font-bold text-2xl",children:"Frameworks"}),Mt("ul",{className:"space-y-2 text-muted-foreground",children:[Ce("li",{children:"Next.js 14+ (App Router preferred)"}),Ce("li",{children:"Bun + Elysia or compatible HTTP servers"})]})]}),Mt("div",{className:"card-subtle space-y-3 p-6",children:[Ce("h2",{className:"font-bold text-2xl",children:"Package managers"}),Mt("ul",{className:"space-y-2 text-muted-foreground",children:[Ce("li",{children:"bun (recommended)"}),Ce("li",{children:"npm"}),Ce("li",{children:"pnpm"})]})]}),Mt("div",{className:"card-subtle space-y-3 p-6",children:[Ce("h2",{className:"font-bold text-2xl",children:"AI agent modes"}),Mt("ul",{className:"space-y-2 text-muted-foreground",children:[Ce("li",{children:"claude-code"}),Ce("li",{children:"openai-codex"}),Ce("li",{children:"cursor"}),Ce("li",{children:"opencode"}),Ce("li",{children:"simple (direct LLM)"})]})]}),Mt("div",{className:"card-subtle space-y-3 p-6",children:[Ce("h2",{className:"font-bold text-2xl",children:"Datastores"}),Ce("p",{className:"text-muted-foreground",children:"ContractSpec ships with Prisma-friendly defaults and can integrate with custom adapters for other databases."}),Mt("ul",{className:"space-y-2 text-muted-foreground",children:[Ce("li",{children:"PostgreSQL via Prisma"}),Ce("li",{children:"Custom adapters for other SQL/NoSQL stores"})]})]}),Mt("div",{className:"card-subtle space-y-3 p-6",children:[Ce("h2",{className:"font-bold text-2xl",children:"Cross-platform UI architecture"}),Mt("p",{className:"text-muted-foreground",children:["Need the React and React Native component compatibility story? Read"," ",Ce(hr,{href:"/docs/libraries/cross-platform-ui",className:"text-[color:var(--rust)] underline underline-offset-4",children:"Cross-platform UI"})," ","for the runtime and UI-layer split."]})]})]}),Mt("div",{className:"flex flex-wrap items-center gap-3 pt-2",children:[Ce(hr,{href:"/docs/getting-started/start-here",className:"btn-ghost",children:"Start here"}),Ce(hr,{href:"/docs/getting-started/troubleshooting",className:"btn-ghost",children:"Troubleshooting"}),Mt(hr,{href:"/docs/getting-started/installation",className:"btn-primary",children:["Next: Installation ",Ce(Tm,{size:16})]})]})]})}import{CodeBlock as Xr}from"@contractspec/lib.design-system";import xr from"@contractspec/lib.ui-link";import{ChevronRight as Rm}from"lucide-react";import{jsx as it,jsxs as uo}from"react/jsx-runtime";var Lm=`import { defineDataView } from '@contractspec/lib.contracts-spec/data-views';
|
|
769
769
|
import { ListTransactions } from './list-transactions';
|
|
770
770
|
|
|
771
771
|
export const TransactionHistory = defineDataView({
|
|
@@ -811,7 +811,7 @@ export const TransactionHistory = defineDataView({
|
|
|
811
811
|
{ key: 'notes', label: 'Notes', dataPath: 'notes' },
|
|
812
812
|
],
|
|
813
813
|
},
|
|
814
|
-
});`;function
|
|
814
|
+
});`;function Dm(){return uo("div",{className:"space-y-8",children:[uo("div",{className:"space-y-4",children:[it("h1",{className:"font-bold text-4xl",children:"Display Data with DataViews"}),it("p",{className:"text-lg text-muted-foreground",children:"Define a filterable, sortable transaction history view that works across web and mobile without duplicating UI code."})]}),uo("div",{className:"space-y-4",children:[it("h2",{className:"font-bold text-2xl",children:"1. Define the underlying query"}),it("p",{className:"text-muted-foreground",children:"First, create a query operation to fetch the data:"}),it(Xr,{language:"typescript",filename:"lib/specs/billing/list-transactions.ts",code:`import { defineQuery } from '@contractspec/lib.contracts-spec';
|
|
815
815
|
|
|
816
816
|
export const ListTransactions = defineQuery({
|
|
817
817
|
meta: {
|
|
@@ -824,7 +824,7 @@ export const ListTransactions = defineQuery({
|
|
|
824
824
|
output: /* array of transactions */,
|
|
825
825
|
},
|
|
826
826
|
policy: { auth: 'user' },
|
|
827
|
-
});`})]}),uo("div",{className:"space-y-4",children:[it("h2",{className:"font-bold text-2xl",children:"2. Define the DataView spec"}),it("p",{className:"text-muted-foreground",children:"Wrap your query with presentation metadata:"}),it(
|
|
827
|
+
});`})]}),uo("div",{className:"space-y-4",children:[it("h2",{className:"font-bold text-2xl",children:"2. Define the DataView spec"}),it("p",{className:"text-muted-foreground",children:"Wrap your query with presentation metadata:"}),it(Xr,{language:"typescript",filename:"lib/specs/billing/transaction-history.data-view.ts",code:Lm}),uo("p",{className:"text-muted-foreground text-sm",children:["The live version of this pattern is available in the canonical"," ",it(xr,{href:"/docs/examples/data-grid-showcase",className:"text-[color:var(--rust)] underline underline-offset-4",children:"Data Grid Showcase"}),"."]})]}),uo("div",{className:"space-y-4",children:[it("h2",{className:"font-bold text-2xl",children:"3. Render on the frontend"}),it("p",{className:"text-muted-foreground",children:"Use the runtime renderer in your React or React Native app:"}),it(Xr,{language:"tsx",filename:"app/dashboard/transactions/page.tsx",code:`'use client';
|
|
828
828
|
|
|
829
829
|
import { DataViewRenderer } from '@contractspec/lib.design-system';
|
|
830
830
|
import { TransactionHistory } from '@/lib/specs/billing/transaction-history.data-view';
|
|
@@ -849,7 +849,7 @@ export function TransactionsPage() {
|
|
|
849
849
|
/>
|
|
850
850
|
</div>
|
|
851
851
|
);
|
|
852
|
-
}`})]}),uo("div",{className:"card-subtle space-y-4 p-6",children:[it("h3",{className:"font-bold",children:"Why DataViews?"}),uo("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[it("li",{children:"Same spec renders on web (React) and mobile (React Native)"}),it("li",{children:"Filters, sorting, and pagination handled automatically"}),it("li",{children:"Column visibility, pinning, resizing, and row expansion stay contract-driven"}),it("li",{children:"Format rules (currency, dates, badges) applied consistently"}),it("li",{children:"Export to CSV/PDF using the same spec"}),it("li",{children:"A/B test different layouts without touching the backend"})]})]}),uo("div",{className:"flex items-center gap-4 pt-4",children:[uo(
|
|
852
|
+
}`})]}),uo("div",{className:"card-subtle space-y-4 p-6",children:[it("h3",{className:"font-bold",children:"Why DataViews?"}),uo("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[it("li",{children:"Same spec renders on web (React) and mobile (React Native)"}),it("li",{children:"Filters, sorting, and pagination handled automatically"}),it("li",{children:"Column visibility, pinning, resizing, and row expansion stay contract-driven"}),it("li",{children:"Format rules (currency, dates, badges) applied consistently"}),it("li",{children:"Export to CSV/PDF using the same spec"}),it("li",{children:"A/B test different layouts without touching the backend"})]})]}),uo("div",{className:"flex items-center gap-4 pt-4",children:[uo(xr,{href:"/docs/libraries/data-views",className:"btn-primary",children:["DataView API Reference ",it(Rm,{size:16})]}),it(xr,{href:"/docs/specs/workflows",className:"btn-ghost",children:"Next: Workflows"})]})]})}import{CodeBlock as Em,InstallCommand as Om}from"@contractspec/lib.design-system";import jr from"@contractspec/lib.ui-link";import{ChevronRight as Hc,Code2 as Bm,Cpu as Mm,Layers as Um,Terminal as Wm}from"lucide-react";import{jsx as Ct,jsxs as Ga}from"react/jsx-runtime";function q2(){return Ga("div",{className:"space-y-8",children:[Ga("div",{className:"space-y-2",children:[Ct("h1",{className:"font-bold text-4xl",children:"Developer Tools"}),Ct("p",{className:"text-lg text-muted-foreground",children:"Use the OSS toolchain to define contracts, validate changes, inspect generated surfaces, and adopt the system incrementally across different environments."})]}),Ct("div",{className:"grid gap-6 md:grid-cols-2",children:[{name:"CLI",href:"/docs/getting-started/tools/cli",description:"Command-line interface for spec creation, building, validation, and CI/CD integration.",icon:Wm,status:"available",highlights:["AI-powered code generation","Multiple agent modes","SARIF/JSON output"]},{name:"VS Code Extension",href:"/docs/getting-started/tools/vscode",description:"Real-time validation, scaffolding, and navigation directly in your editor.",icon:Bm,status:"available",highlights:["Specs Explorer sidebar","Watch mode","Interactive walkthroughs"]},{name:"ContractSpec Studio",href:"https://www.contractspec.studio",description:"The operating layer on top of OSS ContractSpec for teams that want evidence-backed decisions, workflow automation, and managed delivery loops.",icon:Um,status:"available",highlights:["Evidence-to-decision loop","Compiled spec diffs and task packs","Exports to Linear, Jira, Notion, and GitHub"]},{name:"JetBrains Plugin",href:"#",description:"Full ContractSpec support for IntelliJ, WebStorm, and other JetBrains IDEs.",icon:Mm,status:"coming-soon",highlights:["Code navigation","Inline validation","Refactoring support"]}].map((t)=>{let a=t.icon,r=t.status==="coming-soon";return Ga("div",{className:`card-subtle relative space-y-4 p-6 ${r?"opacity-75":""}`,children:[r&&Ct("span",{className:"absolute -top-2 right-4 rounded-full bg-violet-500/20 px-2 py-0.5 font-medium text-violet-400 text-xs",children:"Coming Soon"}),Ga("div",{className:"flex items-center gap-3",children:[Ct("div",{className:"flex h-10 w-10 items-center justify-center rounded-lg bg-violet-500/10",children:Ct(a,{className:"h-5 w-5 text-violet-400"})}),Ct("h3",{className:"font-bold text-lg",children:t.name})]}),Ct("p",{className:"text-muted-foreground text-sm",children:t.description}),Ct("ul",{className:"space-y-1",children:t.highlights.map((l)=>Ga("li",{className:"flex items-center gap-2 text-muted-foreground text-sm",children:[Ct("span",{className:"text-violet-400",children:"-"}),l]},l))}),!r&&Ga(jr,{href:t.href,className:"btn-ghost inline-flex items-center gap-1 text-sm",children:["Learn more ",Ct(Hc,{size:14})]})]},t.name)})}),Ga("div",{className:"card-subtle space-y-4 p-6",children:[Ct("h3",{className:"font-bold",children:"Quick Install"}),Ga("div",{className:"space-y-3",children:[Ga("div",{children:[Ct("p",{className:"mb-2 font-medium text-muted-foreground text-xs",children:"CLI"}),Ct(Om,{package:"contractspec",dev:!0})]}),Ga("div",{children:[Ct("p",{className:"mb-2 font-medium text-muted-foreground text-xs",children:"VS Code Extension"}),Ct(Em,{language:"bash",code:"code --install-extension lssm.vscode-contractspec"})]})]})]}),Ga("div",{className:"flex items-center gap-4 pt-4",children:[Ga(jr,{href:"/docs/getting-started/tools/cli",className:"btn-primary",children:["Get Started with CLI ",Ct(Hc,{size:16})]}),Ct(jr,{href:"/docs/getting-started/tools/vscode",className:"btn-ghost",children:"VS Code Extension"})]})]})}import{CodeBlock as yr}from"@contractspec/lib.design-system";import _m from"@contractspec/lib.ui-link";import{ChevronRight as zm}from"lucide-react";import{jsx as De,jsxs as Sa}from"react/jsx-runtime";function Gm(){return Sa("div",{className:"space-y-8",children:[Sa("div",{className:"space-y-2",children:[De("h1",{className:"font-bold text-4xl",children:"Your First Operation"}),De("p",{className:"text-lg text-muted-foreground",children:"Build a payment capture operation with policy enforcement in under 10 minutes."})]}),Sa("div",{className:"space-y-6",children:[Sa("div",{className:"space-y-3",children:[De("h2",{className:"font-bold text-2xl",children:"What you'll build"}),De("p",{className:"text-muted-foreground",children:"A real-world payment processing operation that validates input, enforces business rules, integrates with Stripe, and audits every transaction. This is production-ready code, not a toy example."})]}),Sa("div",{className:"space-y-3",children:[De("h2",{className:"font-bold text-2xl",children:"1. Define the operation spec"}),Sa("p",{className:"text-muted-foreground",children:["Create ",De("code",{children:"lib/specs/billing/capture-payment.ts"}),":"]}),De(yr,{language:"typescript",filename:"lib/specs/billing/capture-payment.ts",code:`import { defineCommand } from '@contractspec/lib.contracts-spec';
|
|
853
853
|
import { SchemaModel, ScalarTypeEnum } from '@contractspec/lib.schema';
|
|
854
854
|
|
|
855
855
|
const CapturePaymentInput = new SchemaModel({
|
|
@@ -943,16 +943,16 @@ const handler = makeNextAppHandler(registry, async (req) => {
|
|
|
943
943
|
return { actor: 'user', userId: session.userId, tenantId: session.tenantId };
|
|
944
944
|
});
|
|
945
945
|
|
|
946
|
-
export { handler as GET, handler as POST };`})]}),Sa("div",{className:"card-subtle space-y-4 p-6",children:[De("h3",{className:"font-bold",children:"What you just built:"}),Sa("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[Sa("li",{children:["Type-safe API endpoint at"," ",De("code",{children:"/api/ops/billing.capturePayment"})]}),De("li",{children:"Automatic input validation (amount must be positive, IDs required)"}),De("li",{children:"Policy enforcement—only invoice owner can pay"}),De("li",{children:"Stripe integration with error handling"}),De("li",{children:"Database transaction with audit trail"}),De("li",{children:"Same spec works with GraphQL, MCP, or webhooks"})]})]}),De("div",{className:"flex items-center gap-4 pt-4",children:Sa(
|
|
947
|
-
# Follow the interactive prompts to configure your project`})]}),oo("div",{className:"space-y-3",children:[rt("h2",{className:"font-bold text-2xl",children:"Initialize the database"}),rt("p",{className:"text-muted-foreground",children:"If using Prisma, set up your schema and generate the client:"}),rt(
|
|
946
|
+
export { handler as GET, handler as POST };`})]}),Sa("div",{className:"card-subtle space-y-4 p-6",children:[De("h3",{className:"font-bold",children:"What you just built:"}),Sa("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[Sa("li",{children:["Type-safe API endpoint at"," ",De("code",{children:"/api/ops/billing.capturePayment"})]}),De("li",{children:"Automatic input validation (amount must be positive, IDs required)"}),De("li",{children:"Policy enforcement—only invoice owner can pay"}),De("li",{children:"Stripe integration with error handling"}),De("li",{children:"Database transaction with audit trail"}),De("li",{children:"Same spec works with GraphQL, MCP, or webhooks"})]})]}),De("div",{className:"flex items-center gap-4 pt-4",children:Sa(_m,{href:"/docs/getting-started/dataviews",className:"btn-primary",children:["Next: Display Data with DataViews ",De(zm,{size:16})]})})]})]})}import{CodeBlock as Vc,InstallCommand as en}from"@contractspec/lib.design-system";import qm from"@contractspec/lib.ui-link";import{ChevronRight as Hm}from"lucide-react";import{jsx as rt,jsxs as oo}from"react/jsx-runtime";function Vm(){return oo("div",{className:"space-y-8",children:[oo("div",{className:"space-y-2",children:[rt("h1",{className:"font-bold text-4xl",children:"Installation"}),rt("p",{className:"text-lg text-muted-foreground",children:"Add ContractSpec to your existing Next.js or Bun project, or start fresh."})]}),oo("div",{className:"space-y-6",children:[oo("div",{className:"space-y-3",children:[rt("h2",{className:"font-bold text-2xl",children:"Prerequisites"}),oo("ul",{className:"space-y-2 text-muted-foreground",children:[rt("li",{children:"Node.js 20+ (or Bun 1.0+)"}),rt("li",{children:"Existing Next.js app or Bun HTTP server"}),rt("li",{children:"PostgreSQL database (for persistence)"})]})]}),oo("div",{className:"space-y-3",children:[rt("h2",{className:"font-bold text-2xl",children:"Install Core Libraries"}),rt("p",{className:"text-muted-foreground",children:"Add the contracts runtime and your choice of adapter:"}),rt(en,{package:["@contractspec/lib.contracts-spec","@contractspec/lib.schema"]})]}),oo("div",{className:"space-y-3",children:[rt("h2",{className:"font-bold text-2xl",children:"For Next.js projects"}),rt(en,{package:"@contractspec/lib.contracts-spec"})]}),oo("div",{className:"space-y-3",children:[rt("h2",{className:"font-bold text-2xl",children:"For database models"}),rt(en,{package:["@contractspec/app.cli-database","prisma","@prisma/client"]})]}),oo("div",{className:"space-y-3",children:[rt("h2",{className:"font-bold text-2xl",children:"Set up your project"}),rt("p",{className:"text-muted-foreground",children:"Initialize a new ContractSpec project structure:"}),rt(Vc,{language:"bash",filename:"installation-init",code:`bunx contractspec init
|
|
947
|
+
# Follow the interactive prompts to configure your project`})]}),oo("div",{className:"space-y-3",children:[rt("h2",{className:"font-bold text-2xl",children:"Initialize the database"}),rt("p",{className:"text-muted-foreground",children:"If using Prisma, set up your schema and generate the client:"}),rt(Vc,{language:"bash",filename:"installation-prisma",code:`bunx prisma init
|
|
948
948
|
# Edit prisma/schema.prisma with your models
|
|
949
949
|
bunx prisma generate
|
|
950
|
-
bunx prisma migrate dev --name init`})]}),rt("div",{className:"flex items-center gap-4 pt-4",children:oo(
|
|
950
|
+
bunx prisma migrate dev --name init`})]}),rt("div",{className:"flex items-center gap-4 pt-4",children:oo(qm,{href:"/docs/getting-started/hello-world",className:"btn-primary",children:["Next: First Operation ",rt(Hm,{size:16})]})})]})]})}import{CodeBlock as br,InstallCommand as Fm}from"@contractspec/lib.design-system";import tn from"@contractspec/lib.ui-link";import{ChevronRight as Km}from"lucide-react";import{jsx as ca,jsxs as go}from"react/jsx-runtime";function Qm(){return go("div",{className:"space-y-8",children:[go("div",{className:"space-y-2",children:[ca("h1",{className:"font-bold text-4xl",children:"Start here"}),ca("p",{className:"text-lg text-muted-foreground",children:"A fast onboarding path from install to your first generated contract."})]}),go("div",{className:"space-y-6",children:[go("div",{className:"space-y-3",children:[ca("h2",{className:"font-bold text-2xl",children:"Install the CLI"}),ca(Fm,{package:"contractspec",dev:!0})]}),go("div",{className:"space-y-3",children:[ca("h2",{className:"font-bold text-2xl",children:"Generate repo-local guidance"}),ca(br,{language:"bash",filename:"start-here-onboard",code:`contractspec onboard
|
|
951
951
|
# optional focused track
|
|
952
952
|
contractspec onboard knowledge --example knowledge-canon`})]}),go("div",{className:"space-y-3",children:[ca("h2",{className:"font-bold text-2xl",children:"Initialize your project"}),ca(br,{language:"bash",filename:"start-here-init",code:"bunx contractspec init"})]}),go("div",{className:"space-y-3",children:[ca("h2",{className:"font-bold text-2xl",children:"Author your first contract"}),ca(br,{language:"bash",filename:"start-here-create",code:"contractspec create --type operation"})]}),go("div",{className:"space-y-3",children:[ca("h2",{className:"font-bold text-2xl",children:"Generate implementation"}),ca(br,{language:"bash",filename:"start-here-build",code:`contractspec generate
|
|
953
|
-
contractspec validate`})]})]}),go("div",{className:"flex flex-wrap items-center gap-3 pt-2",children:[go(
|
|
953
|
+
contractspec validate`})]})]}),go("div",{className:"flex flex-wrap items-center gap-3 pt-2",children:[go(tn,{href:"/docs/getting-started/hello-world",className:"btn-primary",children:["Next: Hello World ",ca(Km,{size:16})]}),ca(tn,{href:"/docs/getting-started/troubleshooting",className:"btn-ghost",children:"Troubleshooting"}),ca(tn,{href:"/docs/getting-started/compatibility",className:"btn-ghost",children:"Compatibility"})]})]})}import{CodeBlock as Ym}from"@contractspec/lib.design-system";import an from"@contractspec/lib.ui-link";import{ChevronRight as Jm}from"lucide-react";import{jsx as st,jsxs as Ht}from"react/jsx-runtime";function Zm(){return Ht("div",{className:"space-y-8",children:[Ht("div",{className:"space-y-2",children:[st("h1",{className:"font-bold text-4xl",children:"Troubleshooting"}),st("p",{className:"text-lg text-muted-foreground",children:"Common issues and fixes when installing or generating with ContractSpec."})]}),Ht("div",{className:"space-y-6",children:[Ht("div",{className:"card-subtle space-y-3 p-6",children:[st("h2",{className:"font-bold text-2xl",children:"Command not found"}),Ht("ul",{className:"space-y-2 text-muted-foreground",children:[st("li",{children:"Reinstall the CLI and ensure it is in your PATH."}),st("li",{children:"Confirm Node.js 20+ or Bun 1.0+ is installed."})]})]}),Ht("div",{className:"card-subtle space-y-3 p-6",children:[st("h2",{className:"font-bold text-2xl",children:"Specs not discovered"}),Ht("ul",{className:"space-y-2 text-muted-foreground",children:[Ht("li",{children:["Run ",st("code",{children:"contractspec list"})," to see discovered specs."]}),st("li",{children:"Verify your spec path conventions in .contractsrc.json."})]})]}),Ht("div",{className:"card-subtle space-y-3 p-6",children:[st("h2",{className:"font-bold text-2xl",children:"Build or validate fails"}),Ht("ul",{className:"space-y-2 text-muted-foreground",children:[Ht("li",{children:["Run ",st("code",{children:"contractspec validate"})," to surface schema errors."]}),st("li",{children:"Check that generated files were not manually edited."})]})]}),Ht("div",{className:"space-y-3",children:[st("h2",{className:"font-bold text-2xl",children:"Diagnostics"}),st(Ym,{language:"bash",filename:"troubleshooting-diagnostics",code:`contractspec --version
|
|
954
954
|
contractspec list
|
|
955
|
-
contractspec validate src/contracts/mySpec.ts`})]}),Ht("div",{className:"card-subtle space-y-3 p-6",children:[st("h2",{className:"font-bold text-2xl",children:"Still blocked?"}),Ht("ul",{className:"space-y-2 text-muted-foreground",children:[st("li",{children:"Confirm compatibility requirements for runtime and framework."}),st("li",{children:"Re-run builds on a clean branch to isolate changes."}),st("li",{children:"Use a new spec and minimal adapter to validate setup."})]})]})]}),Ht("div",{className:"flex flex-wrap items-center gap-3 pt-2",children:[st(
|
|
955
|
+
contractspec validate src/contracts/mySpec.ts`})]}),Ht("div",{className:"card-subtle space-y-3 p-6",children:[st("h2",{className:"font-bold text-2xl",children:"Still blocked?"}),Ht("ul",{className:"space-y-2 text-muted-foreground",children:[st("li",{children:"Confirm compatibility requirements for runtime and framework."}),st("li",{children:"Re-run builds on a clean branch to isolate changes."}),st("li",{children:"Use a new spec and minimal adapter to validate setup."})]})]})]}),Ht("div",{className:"flex flex-wrap items-center gap-3 pt-2",children:[st(an,{href:"/docs/getting-started/start-here",className:"btn-ghost",children:"Start here"}),st(an,{href:"/docs/getting-started/compatibility",className:"btn-ghost",children:"Compatibility"}),Ht(an,{href:"/docs/getting-started/installation",className:"btn-primary",children:["Next: Installation ",st(Jm,{size:16})]})]})]})}import{CodeBlock as $m}from"@contractspec/lib.design-system";import Fc from"@contractspec/lib.ui-link";import{ChevronRight as Xm,ExternalLink as xm}from"lucide-react";import{jsx as k,jsxs as re}from"react/jsx-runtime";function uS(){let e=[{category:"Core Functionality",items:["Real-time validation with instant feedback on spec errors","Build/Scaffold handlers and components from specs","Interactive spec creation wizard","Watch mode for auto-rebuild on changes","Sync all specs in workspace with one command"]},{category:"Visual Navigation",items:["Specs Explorer sidebar with organized tree view","Dependencies view to visualize spec relationships","Build Results tracking with history","Circular dependency detection"]},{category:"Comparison & Export",items:["Semantic and text diff between specs","Git comparison with baseline branches","OpenAPI 3.1 specification export"]}],t=[{name:"Create New Spec",description:"Interactive wizard to create specs"},{name:"Validate Current Spec",description:"Validate the currently open spec"},{name:"Build/Scaffold from Current Spec",description:"Generate handler/component"},{name:"Toggle Watch Mode",description:"Auto-rebuild on changes"},{name:"Sync All Specs",description:"Build all specs in workspace"},{name:"Analyze Spec Dependencies",description:"Visualize spec dependencies"},{name:"Compare Specs",description:"Semantic or text diff between specs"},{name:"Export to OpenAPI",description:"Generate OpenAPI specification"}];return re("div",{className:"space-y-8",children:[re("div",{className:"space-y-2",children:[k("h1",{className:"font-bold text-4xl",children:"VS Code Extension"}),k("p",{className:"text-lg text-muted-foreground",children:"Spec-first development directly in VS Code. Validate, scaffold, and explore your contract specifications with real-time feedback."})]}),re("div",{className:"flex flex-wrap gap-3",children:[re("a",{href:"https://marketplace.visualstudio.com/items?itemName=lssm.vscode-contractspec",target:"_blank",rel:"noopener noreferrer",className:"btn-primary inline-flex items-center gap-2",children:["Install Extension ",k(xm,{size:16})]}),k("a",{href:"vscode:extension/lssm.vscode-contractspec",className:"btn-ghost inline-flex items-center gap-2",children:"Open in VS Code"})]}),re("div",{className:"space-y-6",children:[re("div",{className:"space-y-3",children:[k("h2",{className:"font-bold text-2xl",children:"Installation"}),re("div",{className:"space-y-2",children:[re("p",{className:"text-muted-foreground text-sm",children:[k("strong",{children:"Option 1:"})," Install from VS Code Marketplace"]}),k($m,{language:"bash",code:"code --install-extension lssm.vscode-contractspec"}),re("p",{className:"mt-4 text-muted-foreground text-sm",children:[k("strong",{children:"Option 2:"}),' Search for "ContractSpec" in VS Code Extensions (Ctrl/Cmd+Shift+X)']})]})]}),re("div",{className:"space-y-4",children:[k("h2",{className:"font-bold text-2xl",children:"Features"}),k("div",{className:"grid gap-4 md:grid-cols-3",children:e.map((a)=>re("div",{className:"card-subtle space-y-3 p-4",children:[k("h3",{className:"font-bold text-violet-400",children:a.category}),k("ul",{className:"space-y-2",children:a.items.map((r)=>re("li",{className:"flex items-start gap-2 text-muted-foreground text-sm",children:[k("span",{className:"mt-1 text-violet-400",children:"-"}),k("span",{children:r})]},r))})]},a.category))})]}),re("div",{className:"space-y-4",children:[k("h2",{className:"font-bold text-2xl",children:"Commands"}),re("p",{className:"text-muted-foreground",children:["Access commands via Command Palette (Ctrl/Cmd+Shift+P) with prefix"," ",k("code",{children:"ContractSpec:"})]}),k("div",{className:"grid gap-3 md:grid-cols-2",children:t.map((a)=>k("div",{className:"card-subtle flex items-center gap-3 p-3",children:re("div",{className:"flex-1",children:[k("p",{className:"font-medium font-mono text-sm",children:a.name}),k("p",{className:"text-muted-foreground text-xs",children:a.description})]})},a.name))})]}),re("div",{className:"space-y-3",children:[k("h2",{className:"font-bold text-2xl",children:"Sidebar Views"}),k("p",{className:"text-muted-foreground",children:"The extension adds a ContractSpec activity bar (icon in sidebar) with three views:"}),re("div",{className:"grid gap-4 md:grid-cols-3",children:[re("div",{className:"card-subtle space-y-2 p-4",children:[k("h4",{className:"font-bold",children:"Specs Explorer"}),k("p",{className:"text-muted-foreground text-sm",children:"Browse all specs organized by type. Shows name, version, and stability. Click to open, right-click for actions."})]}),re("div",{className:"card-subtle space-y-2 p-4",children:[k("h4",{className:"font-bold",children:"Dependencies"}),k("p",{className:"text-muted-foreground text-sm",children:"Visualize spec relationships. Detect circular dependencies. Navigate to referenced specs."})]}),re("div",{className:"card-subtle space-y-2 p-4",children:[k("h4",{className:"font-bold",children:"Build Results"}),k("p",{className:"text-muted-foreground text-sm",children:"Track build history (last 20). Success/failure indicators. Click to open generated files."})]})]})]}),re("div",{className:"space-y-3",children:[k("h2",{className:"font-bold text-2xl",children:"Getting Started"}),re("ol",{className:"list-inside list-decimal space-y-2 text-muted-foreground",children:[k("li",{children:"Install the extension from VS Code Marketplace"}),k("li",{children:"Open a workspace with ContractSpec files (or create one)"}),k("li",{children:"Start the walkthrough: Help - Welcome - ContractSpec"}),re("li",{children:["Create your first spec: Click ",k("strong",{children:"+"})," in Specs Explorer or run ",k("code",{children:"ContractSpec: Create New Spec"})]}),k("li",{children:"Build from it: Click the build icon in the editor title bar"})]})]}),re("div",{className:"card-subtle space-y-4 p-6",children:[k("h3",{className:"font-bold",children:"Configuration"}),k("p",{className:"text-muted-foreground text-sm",children:"Configure the extension in VS Code Settings:"}),k("div",{className:"overflow-x-auto",children:re("table",{className:"w-full text-muted-foreground text-sm",children:[k("thead",{children:re("tr",{className:"border-border border-b",children:[k("th",{className:"p-2 text-left font-medium",children:"Setting"}),k("th",{className:"p-2 text-left font-medium",children:"Description"}),k("th",{className:"p-2 text-left font-medium",children:"Default"})]})}),re("tbody",{children:[re("tr",{className:"border-border border-b",children:[k("td",{className:"p-2 font-mono text-xs",children:"validation.onSave"}),k("td",{className:"p-2",children:"Run validation on save"}),k("td",{className:"p-2",children:"true"})]}),re("tr",{className:"border-border border-b",children:[k("td",{className:"p-2 font-mono text-xs",children:"validation.onOpen"}),k("td",{className:"p-2",children:"Run validation on open"}),k("td",{className:"p-2",children:"true"})]}),re("tr",{className:"border-border border-b",children:[k("td",{className:"p-2 font-mono text-xs",children:"api.baseUrl"}),k("td",{className:"p-2",children:"Base URL for ContractSpec API"}),k("td",{className:"p-2",children:"(empty)"})]})]})]})})]})]}),re("div",{className:"flex items-center gap-4 pt-4",children:[k(Fc,{href:"/docs/getting-started/tools/cli",className:"btn-ghost",children:"Back: CLI"}),re(Fc,{href:"/docs/specs",className:"btn-primary",children:["Next: Core Concepts ",k(Xm,{size:16})]})]})]})}import{registerDocBlocks as jm}from"@contractspec/lib.contracts-spec/docs";var eu=[{id:"docs.getting-started.start-here",title:"Start here",summary:"Fast onboarding path from install to first generated contract.",kind:"usage",visibility:"public",route:"/docs/getting-started/start-here",tags:["getting-started","onboarding"],body:`# Start Here
|
|
956
956
|
|
|
957
957
|
Get ContractSpec running quickly and generate your first contract-backed code.
|
|
958
958
|
|
|
@@ -1051,9 +1051,9 @@ ContractSpec supports modern TypeScript stacks with spec-first workflows.
|
|
|
1051
1051
|
|
|
1052
1052
|
- PostgreSQL via Prisma
|
|
1053
1053
|
- Bring your own adapter for other databases
|
|
1054
|
-
`}];
|
|
1054
|
+
`}];jm(eu);import{CodeBlock as vr}from"@contractspec/lib.design-system";import Kc from"@contractspec/lib.ui-link";import{ChevronRight as tu}from"lucide-react";import{jsx as ze,jsxs as qa}from"react/jsx-runtime";function au(){return qa("div",{className:"space-y-8",children:[qa("div",{className:"space-y-3",children:[ze("h1",{className:"font-bold text-4xl",children:"CI gating with deterministic diffs"}),ze("p",{className:"text-lg text-muted-foreground",children:"Add ContractSpec CI checks that validate specs, detect drift, and gate breaking changes before merge."})]}),qa("div",{className:"card-subtle space-y-4 p-6",children:[ze("h2",{className:"font-bold text-2xl",children:"What you'll build"}),qa("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[ze("li",{children:"CI workflow running ContractSpec validation and drift checks."}),ze("li",{children:"Machine-readable output for PR annotations."}),ze("li",{children:"Deterministic contract diffs in review."})]})]}),qa("div",{className:"space-y-6",children:[qa("div",{className:"space-y-3",children:[ze("h2",{className:"font-bold text-2xl",children:"1) Add the CI workflow"}),ze("p",{className:"text-muted-foreground text-sm",children:"Copy the template from the CLI package."}),ze(vr,{language:"bash",filename:"ci-copy",code:"cp node_modules/@contractspec/app.cli-contractspec/templates/github-action.yml .github/workflows/contractspec.yml"}),qa("p",{className:"text-muted-foreground text-sm",children:["Expected output: new workflow file in ",ze("code",{children:".github/workflows"}),"."]})]}),qa("div",{className:"space-y-3",children:[ze("h2",{className:"font-bold text-2xl",children:"2) Run CI locally"}),ze(vr,{language:"bash",filename:"ci-local",code:"contractspec ci --format json --check-drift"}),ze("p",{className:"text-muted-foreground text-sm",children:"Expected output: JSON summary including pass/fail counts and drift status (if configured)."})]}),qa("div",{className:"space-y-3",children:[ze("h2",{className:"font-bold text-2xl",children:"3) Add a diff check"}),ze("p",{className:"text-muted-foreground text-sm",children:"Use the diff command to inspect breaking changes in PRs."}),ze(vr,{language:"bash",filename:"ci-diff",code:"contractspec diff src/contracts/spec-v1.ts src/contracts/spec-v2.ts --breaking"}),ze("p",{className:"text-muted-foreground text-sm",children:"Expected output: deterministic diff with breaking change hints."})]}),qa("div",{className:"card-subtle space-y-3 p-6",children:[ze("h3",{className:"font-semibold text-lg",children:"Example package"}),ze("p",{className:"text-muted-foreground text-sm",children:"The CRM pipeline example is already wired in the quickstart smoke test. Use it as a CI-ready template."}),ze(vr,{language:"bash",filename:"crm-ci",code:`cd packages/examples/crm-pipeline
|
|
1055
1055
|
bun run build
|
|
1056
|
-
bun run validate`})]}),ze(qt,{title:"Need continuous checks tied to outcomes?",body:"Studio closes the loop with post-change verification and learning dividends that improve future decisions."})]}),qa("div",{className:"flex items-center gap-4 pt-4",children:[qa(
|
|
1056
|
+
bun run validate`})]}),ze(qt,{title:"Need continuous checks tied to outcomes?",body:"Studio closes the loop with post-change verification and learning dividends that improve future decisions."})]}),qa("div",{className:"flex items-center gap-4 pt-4",children:[qa(Kc,{href:"/docs/guides",className:"btn-primary",children:["Back to guides ",ze(tu,{size:16})]}),ze(Kc,{href:"/docs",className:"btn-ghost",children:"Docs home"})]})]})}import{CodeBlock as Ti}from"@contractspec/lib.design-system";import Qc from"@contractspec/lib.ui-link";import{ChevronRight as ou}from"lucide-react";import{jsx as x,jsxs as Ca}from"react/jsx-runtime";var iu=[".contractspec/connect/context-pack.json",".contractspec/connect/plan-packet.json",".contractspec/connect/patch-verdict.json",".contractspec/connect/audit.ndjson",".contractspec/connect/decisions/<decisionId>/",".contractspec/adoption/catalog.json",".contractspec/adoption/overrides.json"];function ru(){return Ca("div",{className:"space-y-8",children:[Ca("div",{className:"space-y-3",children:[x("h1",{className:"font-bold text-4xl",children:"Use Connect in a repo"}),x("p",{className:"text-lg text-muted-foreground",children:"Put coding-agent edits and shell commands behind task-scoped context, plan compilation, verification, and local review evidence without introducing a second control plane."})]}),Ca("div",{className:"card-subtle space-y-4 p-6",children:[x("h2",{className:"font-bold text-2xl",children:"What you'll build"}),Ca("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[x("li",{children:"A workspace-level Connect config in `.contractsrc.json`."}),x("li",{children:"A reuse-first adoption check before new implementation work."}),x("li",{children:"A context and plan flow for one task."}),x("li",{children:"Verified file and shell mutations with local review/replay evidence."})]})]}),Ca("div",{className:"space-y-6",children:[Ca("div",{className:"space-y-3",children:[x("h2",{className:"font-bold text-2xl",children:"1) Enable Connect"}),x("p",{className:"text-muted-foreground text-sm",children:"Start by making the safety policy explicit. Protected paths, generated paths, review thresholds, and command rules live in the workspace config, not in editor-specific hooks."}),x(Ti,{language:"json",filename:".contractsrc.json",code:`{
|
|
1057
1057
|
"connect": {
|
|
1058
1058
|
"enabled": true,
|
|
1059
1059
|
"storage": {
|
|
@@ -1115,12 +1115,12 @@ printf '{"objective":"Document the control-plane contract surface","commands":["
|
|
|
1115
1115
|
contractspec connect verify --task docs-connect --tool acp.fs.access --stdin --json
|
|
1116
1116
|
|
|
1117
1117
|
printf 'bun run typecheck' | \\
|
|
1118
|
-
contractspec connect verify --task docs-connect --tool acp.terminal.exec --stdin --json`}),x("p",{className:"text-muted-foreground text-sm",children:"Expected output: a `PatchVerdict` with `permit`, `rewrite`, `require_review`, or `deny`, plus a runtime-linked control-plane state when that linkage is available."})]}),Ca("div",{className:"card-subtle space-y-3 p-6",children:[x("h3",{className:"font-semibold text-lg",children:"Artifacts to inspect"}),x("ul",{className:"space-y-2 text-muted-foreground text-sm",children:
|
|
1118
|
+
contractspec connect verify --task docs-connect --tool acp.terminal.exec --stdin --json`}),x("p",{className:"text-muted-foreground text-sm",children:"Expected output: a `PatchVerdict` with `permit`, `rewrite`, `require_review`, or `deny`, plus a runtime-linked control-plane state when that linkage is available."})]}),Ca("div",{className:"card-subtle space-y-3 p-6",children:[x("h3",{className:"font-semibold text-lg",children:"Artifacts to inspect"}),x("ul",{className:"space-y-2 text-muted-foreground text-sm",children:iu.map((e)=>x("li",{children:x("code",{children:e})},e))})]}),Ca("div",{className:"space-y-3",children:[x("h2",{className:"font-bold text-2xl",children:"6) Review, replay, and optional Studio sync"}),x(Ti,{language:"bash",filename:"connect-review-replay",code:`contractspec connect review list --json
|
|
1119
1119
|
contractspec connect replay <decisionId> --json
|
|
1120
1120
|
contractspec connect eval <decisionId> --registry ./harness-registry.ts --scenario connect.safe-refactor --json
|
|
1121
1121
|
|
|
1122
1122
|
# Optional when Studio review-bridge mode is enabled
|
|
1123
|
-
contractspec connect review sync --decision <decisionId> --json`}),x("p",{className:"text-muted-foreground text-sm",children:"Local review packets remain authoritative. Studio sync is an operator convenience layer, not a requirement for baseline OSS safety."})]})]}),Ca("div",{className:"flex items-center gap-4 pt-4",children:[Ca(
|
|
1123
|
+
contractspec connect review sync --decision <decisionId> --json`}),x("p",{className:"text-muted-foreground text-sm",children:"Local review packets remain authoritative. Studio sync is an operator convenience layer, not a requirement for baseline OSS safety."})]})]}),Ca("div",{className:"flex items-center gap-4 pt-4",children:[Ca(Qc,{href:"/docs/specs/connect",className:"btn-primary",children:["Back to Connect spec ",x(ou,{size:16})]}),x(Qc,{href:"/docs/architecture/control-plane",className:"btn-ghost",children:"Control-plane runtime"})]})]})}import{CodeBlock as Fi}from"@contractspec/lib.design-system";import Yc from"@contractspec/lib.ui-link";import{ChevronRight as nu,Globe as cu,Layers as lu,Shield as du,Zap as su}from"lucide-react";import{jsx as s,jsxs as j}from"react/jsx-runtime";var pu=[{name:"Operations",factory:"defineCommand / defineQuery",description:"API endpoints with input/output schemas, validation, and policy.",icon:su,color:"text-blue-400"},{name:"Events",factory:"defineEvent",description:"Domain events with typed payloads and PII handling.",icon:lu,color:"text-green-400"},{name:"Capabilities",factory:"defineCapability",description:"Feature groupings that link operations, events, and UIs.",icon:du,color:"text-purple-400"},{name:"Presentations",factory:"definePresentation",description:"UI specifications for rendering data and handling interactions.",icon:cu,color:"text-orange-400"}];function mu(){return j("div",{className:"space-y-8",children:[j("div",{className:"space-y-3",children:[s("h1",{className:"font-bold text-4xl",children:"Contract Types Overview"}),s("p",{className:"text-lg text-muted-foreground",children:"Learn about the different contract types in ContractSpec and when to use each one when you are making the system boundary explicit."})]}),j("div",{className:"card-subtle space-y-4 p-6",children:[s("h2",{className:"font-bold text-2xl",children:"Core Contract Types"}),s("div",{className:"grid gap-3 md:grid-cols-2",children:pu.map((e)=>j("div",{className:"flex items-start gap-3 rounded-lg border border-white/10 p-4",children:[s(e.icon,{className:e.color,size:20}),j("div",{className:"space-y-1",children:[s("h3",{className:"font-semibold",children:e.name}),s("p",{className:"text-muted-foreground text-xs",children:e.description}),s("code",{className:"text-violet-400 text-xs",children:e.factory})]})]},e.name))})]}),j("div",{className:"space-y-6",children:[j("div",{className:"space-y-3",children:[s("h2",{className:"font-bold text-2xl",children:"1) Operations (Commands & Queries)"}),s("p",{className:"text-muted-foreground text-sm",children:"Operations are the backbone of your API. Commands mutate state, queries read state. Both have typed input/output schemas."}),s(Fi,{language:"typescript",filename:"src/contracts/user.operation.ts",code:`import { defineCommand, defineQuery } from "@contractspec/lib.contracts-spec";
|
|
1124
1124
|
import { SchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
|
|
1125
1125
|
|
|
1126
1126
|
// Command: Mutates state (creates a user)
|
|
@@ -1322,9 +1322,9 @@ installOp(operationRegistry, GetUserQuery, async (input) => {
|
|
|
1322
1322
|
|
|
1323
1323
|
// Register events and capabilities
|
|
1324
1324
|
eventRegistry.register(UserCreatedEvent);
|
|
1325
|
-
capabilityRegistry.register(UserManagementCapability);`})]}),j("div",{className:"card-subtle space-y-3 p-6",children:[s("h3",{className:"font-semibold text-lg",children:"Contract Type Decision Guide"}),j("table",{className:"w-full text-sm",children:[s("thead",{children:j("tr",{className:"border-white/10 border-b",children:[s("th",{className:"py-2 text-left",children:"When you need..."}),s("th",{className:"py-2 text-left",children:"Use this contract"})]})}),j("tbody",{className:"text-muted-foreground",children:[j("tr",{className:"border-white/5 border-b",children:[s("td",{className:"py-2",children:"An API endpoint that changes data"}),s("td",{className:"py-2",children:s("code",{children:"defineCommand"})})]}),j("tr",{className:"border-white/5 border-b",children:[s("td",{className:"py-2",children:"An API endpoint that reads data"}),s("td",{className:"py-2",children:s("code",{children:"defineQuery"})})]}),j("tr",{className:"border-white/5 border-b",children:[s("td",{className:"py-2",children:"Async notification of something that happened"}),s("td",{className:"py-2",children:s("code",{children:"defineEvent"})})]}),j("tr",{className:"border-white/5 border-b",children:[s("td",{className:"py-2",children:"Group related specs under a feature"}),s("td",{className:"py-2",children:s("code",{children:"defineCapability"})})]}),j("tr",{className:"border-white/5 border-b",children:[s("td",{className:"py-2",children:"Define UI rendering specifications"}),s("td",{className:"py-2",children:s("code",{children:"definePresentation"})})]}),j("tr",{className:"border-white/5 border-b",children:[s("td",{className:"py-2",children:"Access control and rate limiting"}),s("td",{className:"py-2",children:s("code",{children:"definePolicy"})})]}),j("tr",{children:[s("td",{className:"py-2",children:"Multi-step business processes"}),s("td",{className:"py-2",children:s("code",{children:"defineWorkflow"})})]})]})]})]}),s(qt,{title:"Need to decide which contract should change next?",body:"Studio uses evidence and focus constraints to generate decision briefs, patch intents, and execution-ready task packs."})]}),j("div",{className:"flex items-center gap-4 pt-4",children:[j(
|
|
1325
|
+
capabilityRegistry.register(UserManagementCapability);`})]}),j("div",{className:"card-subtle space-y-3 p-6",children:[s("h3",{className:"font-semibold text-lg",children:"Contract Type Decision Guide"}),j("table",{className:"w-full text-sm",children:[s("thead",{children:j("tr",{className:"border-white/10 border-b",children:[s("th",{className:"py-2 text-left",children:"When you need..."}),s("th",{className:"py-2 text-left",children:"Use this contract"})]})}),j("tbody",{className:"text-muted-foreground",children:[j("tr",{className:"border-white/5 border-b",children:[s("td",{className:"py-2",children:"An API endpoint that changes data"}),s("td",{className:"py-2",children:s("code",{children:"defineCommand"})})]}),j("tr",{className:"border-white/5 border-b",children:[s("td",{className:"py-2",children:"An API endpoint that reads data"}),s("td",{className:"py-2",children:s("code",{children:"defineQuery"})})]}),j("tr",{className:"border-white/5 border-b",children:[s("td",{className:"py-2",children:"Async notification of something that happened"}),s("td",{className:"py-2",children:s("code",{children:"defineEvent"})})]}),j("tr",{className:"border-white/5 border-b",children:[s("td",{className:"py-2",children:"Group related specs under a feature"}),s("td",{className:"py-2",children:s("code",{children:"defineCapability"})})]}),j("tr",{className:"border-white/5 border-b",children:[s("td",{className:"py-2",children:"Define UI rendering specifications"}),s("td",{className:"py-2",children:s("code",{children:"definePresentation"})})]}),j("tr",{className:"border-white/5 border-b",children:[s("td",{className:"py-2",children:"Access control and rate limiting"}),s("td",{className:"py-2",children:s("code",{children:"definePolicy"})})]}),j("tr",{children:[s("td",{className:"py-2",children:"Multi-step business processes"}),s("td",{className:"py-2",children:s("code",{children:"defineWorkflow"})})]})]})]})]}),s(qt,{title:"Need to decide which contract should change next?",body:"Studio uses evidence and focus constraints to generate decision briefs, patch intents, and execution-ready task packs."})]}),j("div",{className:"flex items-center gap-4 pt-4",children:[j(Yc,{href:"/docs/guides/nextjs-one-endpoint",className:"btn-primary",children:["Next: Add your first endpoint ",s(nu,{size:16})]}),s(Yc,{href:"/docs/guides",className:"btn-ghost",children:"Back to guides"})]})]})}import{CodeBlock as on}from"@contractspec/lib.design-system";import Jc from"@contractspec/lib.ui-link";import{ChevronRight as uu}from"lucide-react";import{jsx as nt,jsxs as la}from"react/jsx-runtime";function gu(){return la("div",{className:"space-y-8",children:[la("div",{className:"space-y-3",children:[nt("h1",{className:"font-bold text-4xl",children:"Build the docs pipeline"}),nt("p",{className:"text-lg text-muted-foreground",children:"Generate reference docs, chunk the index, and wire the docs pages the same way this repo does."})]}),la("div",{className:"card-subtle space-y-4 p-6",children:[nt("h2",{className:"font-bold text-2xl",children:"What you'll build"}),la("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[nt("li",{children:"Generated Markdown and a chunked index manifest."}),nt("li",{children:"Reference routes powered by the docs loader."}),nt("li",{children:"Versioned outputs you can publish per release."})]})]}),la("div",{className:"space-y-6",children:[la("div",{className:"space-y-3",children:[nt("h2",{className:"font-bold text-2xl",children:"1) Generate contract docs"}),nt(on,{language:"bash",filename:"generate-contract-docs",code:"contractspec generate"}),la("p",{className:"text-muted-foreground text-sm",children:["Expected output: Markdown in ",nt("code",{children:"generated/docs"}),"."]})]}),la("div",{className:"space-y-3",children:[nt("h2",{className:"font-bold text-2xl",children:"2) Build the docs index"}),nt(on,{language:"bash",filename:"docs-generate",code:`bun docs:generate
|
|
1326
1326
|
# versioned output
|
|
1327
|
-
bun docs:generate -- --version v1.0.0`}),la("p",{className:"text-muted-foreground text-sm",children:["This writes ",nt("code",{children:"docs-index.manifest.json"})," and chunked",nt("code",{children:"docs-index.*.json"})," files in the generated docs bundle."]})]}),la("div",{className:"space-y-3",children:[nt("h2",{className:"font-bold text-2xl",children:"3) Wire reference routes"}),nt(
|
|
1327
|
+
bun docs:generate -- --version v1.0.0`}),la("p",{className:"text-muted-foreground text-sm",children:["This writes ",nt("code",{children:"docs-index.manifest.json"})," and chunked",nt("code",{children:"docs-index.*.json"})," files in the generated docs bundle."]})]}),la("div",{className:"space-y-3",children:[nt("h2",{className:"font-bold text-2xl",children:"3) Wire reference routes"}),nt(on,{language:"tsx",filename:"docs-reference-route",code:`import { notFound } from "next/navigation";
|
|
1328
1328
|
import {
|
|
1329
1329
|
DocsReferenceIndexPage,
|
|
1330
1330
|
DocsReferencePage,
|
|
@@ -1342,7 +1342,7 @@ export default async function Page({ params }: { params: { slug?: string[] } })
|
|
|
1342
1342
|
const doc = await getGeneratedDocById(slug);
|
|
1343
1343
|
if (!doc) notFound();
|
|
1344
1344
|
return <DocsReferencePage entry={doc.entry} content={doc.content} />;
|
|
1345
|
-
}`}),la("p",{className:"text-muted-foreground text-sm",children:["Use the index page on ",nt("code",{children:"/docs/reference"})," to render the searchable list."]})]}),la("div",{className:"card-subtle space-y-3 p-6",children:[nt("h3",{className:"font-semibold text-lg",children:"Repo reference"}),la("p",{className:"text-muted-foreground text-sm",children:["This repo wires docs under"," ",nt("code",{children:"packages/apps/web-landing/src/app/docs/reference"}),"."]})]}),nt(qt,{title:"Need decision-to-export automation?",body:"Studio exports evidence-backed spec changes and task packs to Linear, Jira, Notion, and GitHub."})]}),la("div",{className:"flex items-center gap-4 pt-4",children:[la(
|
|
1345
|
+
}`}),la("p",{className:"text-muted-foreground text-sm",children:["Use the index page on ",nt("code",{children:"/docs/reference"})," to render the searchable list."]})]}),la("div",{className:"card-subtle space-y-3 p-6",children:[nt("h3",{className:"font-semibold text-lg",children:"Repo reference"}),la("p",{className:"text-muted-foreground text-sm",children:["This repo wires docs under"," ",nt("code",{children:"packages/apps/web-landing/src/app/docs/reference"}),"."]})]}),nt(qt,{title:"Need decision-to-export automation?",body:"Studio exports evidence-backed spec changes and task packs to Linear, Jira, Notion, and GitHub."})]}),la("div",{className:"flex items-center gap-4 pt-4",children:[la(Jc,{href:"/docs/guides/ci-contract-diff-gating",className:"btn-primary",children:["Next: CI gating ",nt(uu,{size:16})]}),nt(Jc,{href:"/docs/guides",className:"btn-ghost",children:"Back to guides"})]})]})}import{CodeBlock as rn}from"@contractspec/lib.design-system";import Zc from"@contractspec/lib.ui-link";import{ChevronRight as fu}from"lucide-react";import{jsx as Te,jsxs as Ha}from"react/jsx-runtime";function hu(){return Ha("div",{className:"space-y-8",children:[Ha("div",{className:"space-y-3",children:[Te("h1",{className:"font-bold text-4xl",children:"Build a first module bundle"}),Te("p",{className:"text-lg text-muted-foreground",children:"Define one bundle spec, resolve it for a real route and preference profile, then render the resulting surface plan through the React host layer."})]}),Ha("div",{className:"card-subtle space-y-4 p-6",children:[Te("h2",{className:"font-bold text-2xl",children:"What you'll build"}),Ha("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[Te("li",{children:"One `ModuleBundleSpec` with a route and workbench surface."}),Te("li",{children:"One `ResolvedSurfacePlan` from `resolveBundle`."}),Te("li",{children:"One React host using `BundleProvider` and `BundleRenderer`."})]})]}),Ha("div",{className:"space-y-6",children:[Ha("div",{className:"space-y-3",children:[Te("h2",{className:"font-bold text-2xl",children:"1) Define the bundle spec"}),Te("p",{className:"text-muted-foreground text-sm",children:"The bundle spec is the durable contract. It owns route selection, surface shape, layouts, data recipes, and verification coverage for all seven preference dimensions."}),Te(rn,{language:"typescript",filename:"src/bundles/support.workbench.bundle.ts",code:`import { defineModuleBundle } from "@contractspec/lib.surface-runtime/spec/define-module-bundle";
|
|
1346
1346
|
|
|
1347
1347
|
export const SupportWorkbenchBundle = defineModuleBundle({
|
|
1348
1348
|
meta: {
|
|
@@ -1384,7 +1384,7 @@ export const SupportWorkbenchBundle = defineModuleBundle({
|
|
|
1384
1384
|
},
|
|
1385
1385
|
},
|
|
1386
1386
|
},
|
|
1387
|
-
});`}),Te("p",{className:"text-muted-foreground text-sm",children:"Expected output: `defineModuleBundle` validates the route, surface, and verification dimensions at runtime."})]}),Ha("div",{className:"space-y-3",children:[Te("h2",{className:"font-bold text-2xl",children:"2) Resolve the plan"}),Te("p",{className:"text-muted-foreground text-sm",children:"Resolve against a real route, device, and preference profile. This is where the runtime chooses the surface, layout, bindings, and audit reasons."}),Te(
|
|
1387
|
+
});`}),Te("p",{className:"text-muted-foreground text-sm",children:"Expected output: `defineModuleBundle` validates the route, surface, and verification dimensions at runtime."})]}),Ha("div",{className:"space-y-3",children:[Te("h2",{className:"font-bold text-2xl",children:"2) Resolve the plan"}),Te("p",{className:"text-muted-foreground text-sm",children:"Resolve against a real route, device, and preference profile. This is where the runtime chooses the surface, layout, bindings, and audit reasons."}),Te(rn,{language:"typescript",filename:"src/runtime/resolve-support-workbench.ts",code:`import { resolveBundle } from "@contractspec/lib.surface-runtime/runtime/resolve-bundle";
|
|
1388
1388
|
|
|
1389
1389
|
export const supportWorkbenchPlan = await resolveBundle(
|
|
1390
1390
|
SupportWorkbenchBundle,
|
|
@@ -1408,7 +1408,7 @@ export const supportWorkbenchPlan = await resolveBundle(
|
|
|
1408
1408
|
},
|
|
1409
1409
|
capabilities: ["tickets.read", "tickets.update"],
|
|
1410
1410
|
}
|
|
1411
|
-
);`}),Te("p",{className:"text-muted-foreground text-sm",children:"Expected output: a `ResolvedSurfacePlan` with `bundleKey`, `surfaceId`, `layoutId`, `bindings`, `adaptation`, and audit reasons."})]}),Ha("div",{className:"space-y-3",children:[Te("h2",{className:"font-bold text-2xl",children:"3) Render the plan"}),Te("p",{className:"text-muted-foreground text-sm",children:"The host app renders the resolved plan, not the raw spec. That keeps layout selection, overlays, and AI proposals downstream of the declared bundle contract."}),Te(
|
|
1411
|
+
);`}),Te("p",{className:"text-muted-foreground text-sm",children:"Expected output: a `ResolvedSurfacePlan` with `bundleKey`, `surfaceId`, `layoutId`, `bindings`, `adaptation`, and audit reasons."})]}),Ha("div",{className:"space-y-3",children:[Te("h2",{className:"font-bold text-2xl",children:"3) Render the plan"}),Te("p",{className:"text-muted-foreground text-sm",children:"The host app renders the resolved plan, not the raw spec. That keeps layout selection, overlays, and AI proposals downstream of the declared bundle contract."}),Te(rn,{language:"tsx",filename:"src/app/support/SurfaceHost.tsx",code:`import { BundleProvider, BundleRenderer } from "@contractspec/lib.surface-runtime/react";
|
|
1412
1412
|
|
|
1413
1413
|
export function SurfaceHost() {
|
|
1414
1414
|
return (
|
|
@@ -1416,10 +1416,10 @@ export function SurfaceHost() {
|
|
|
1416
1416
|
<BundleRenderer assistantSlotId="assistant" />
|
|
1417
1417
|
</BundleProvider>
|
|
1418
1418
|
);
|
|
1419
|
-
}`}),Te("p",{className:"text-muted-foreground text-sm",children:"Expected output: the route renders according to the resolved layout root and slot plan instead of bespoke page assembly."})]}),Ha("div",{className:"card-subtle space-y-3 p-6",children:[Te("h3",{className:"font-semibold text-lg",children:"Verification checks"}),Ha("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[Te("li",{children:"The resolved `surfaceId` matches the route you expected."}),Te("li",{children:"The `layoutId` is stable for the active view and preferences."}),Te("li",{children:"The plan carries audit reasons and all seven adaptation dimensions."}),Te("li",{children:"Assistant or overlay work stays within declared slots."})]})]})]}),Ha("div",{className:"flex items-center gap-4 pt-4",children:[Ha(
|
|
1419
|
+
}`}),Te("p",{className:"text-muted-foreground text-sm",children:"Expected output: the route renders according to the resolved layout root and slot plan instead of bespoke page assembly."})]}),Ha("div",{className:"card-subtle space-y-3 p-6",children:[Te("h3",{className:"font-semibold text-lg",children:"Verification checks"}),Ha("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[Te("li",{children:"The resolved `surfaceId` matches the route you expected."}),Te("li",{children:"The `layoutId` is stable for the active view and preferences."}),Te("li",{children:"The plan carries audit reasons and all seven adaptation dimensions."}),Te("li",{children:"Assistant or overlay work stays within declared slots."})]})]})]}),Ha("div",{className:"flex items-center gap-4 pt-4",children:[Ha(Zc,{href:"/docs/specs/module-bundles",className:"btn-primary",children:["Back to module bundles ",Te(fu,{size:16})]}),Te(Zc,{href:"/docs/specs/overlays",className:"btn-ghost",children:"Next: overlays"})]})]})}import{CodeBlock as Nr}from"@contractspec/lib.design-system";import $c from"@contractspec/lib.ui-link";import{ChevronRight as yu}from"lucide-react";import{jsx as Ge,jsxs as Ia}from"react/jsx-runtime";function bu(){return Ia("div",{className:"space-y-8",children:[Ia("div",{className:"space-y-3",children:[Ge("h1",{className:"font-bold text-4xl",children:"Generate docs + client schemas"}),Ge("p",{className:"text-lg text-muted-foreground",children:"Generate docs and OpenAPI output from ContractSpec operations to power SDKs, docs sites, and tooling."})]}),Ia("div",{className:"card-subtle space-y-4 p-6",children:[Ge("h2",{className:"font-bold text-2xl",children:"What you'll build"}),Ia("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[Ge("li",{children:"Export docs from your specs."}),Ge("li",{children:"Emit OpenAPI 3.1 for client SDK generation."}),Ge("li",{children:"Keep outputs deterministic with CI validation."})]})]}),Ia("div",{className:"space-y-6",children:[Ia("div",{className:"space-y-3",children:[Ge("h2",{className:"font-bold text-2xl",children:"1) Generate docs"}),Ge("p",{className:"text-muted-foreground text-sm",children:"Use the generator to emit docs from your contracts."}),Ge(Nr,{language:"bash",filename:"generate-docs",code:"contractspec generate"}),Ia("p",{className:"text-muted-foreground text-sm",children:["Expected output: ",Ge("code",{children:"Generate X doc files in generated/docs"}),"."]})]}),Ia("div",{className:"space-y-3",children:[Ge("h2",{className:"font-bold text-2xl",children:"2) Export OpenAPI"}),Ge("p",{className:"text-muted-foreground text-sm",children:"Export an OpenAPI document from your registry module."}),Ge(Nr,{language:"bash",filename:"openapi-export",code:"contractspec openapi export --registry ./src/contracts/registry.ts --out ./generated/openapi.json"}),Ia("p",{className:"text-muted-foreground text-sm",children:["Expected output:"," ",Ge("code",{children:"OpenAPI written to .../generated/openapi.json"}),"."]})]}),Ia("div",{className:"space-y-3",children:[Ge("h2",{className:"font-bold text-2xl",children:"3) Validate specs"}),Ge(Nr,{language:"bash",filename:"validate-specs",code:"contractspec validate"}),Ia("p",{className:"text-muted-foreground text-sm",children:["Expected output: ",Ge("code",{children:"Validation passed"}),"."]})]}),Ia("div",{className:"card-subtle space-y-3 p-6",children:[Ge("h3",{className:"font-semibold text-lg",children:"Example package"}),Ge("p",{className:"text-muted-foreground text-sm",children:"The Integration Hub example provides a full registry of operations and is a good source for OpenAPI exports."}),Ge(Nr,{language:"bash",filename:"integration-hub-example",code:`contractspec examples show integration-hub
|
|
1420
1420
|
|
|
1421
1421
|
# openapi export against your registry module
|
|
1422
|
-
contractspec openapi export --registry ./src/contracts/registry.ts --out ./generated/openapi.json`})]}),Ge(qt,{title:"Want exports tied to product decisions?",body:"Studio compiles approved changes into deliverables and pushes them to your execution stack with full evidence context."})]}),Ia("div",{className:"flex items-center gap-4 pt-4",children:[Ia(
|
|
1422
|
+
contractspec openapi export --registry ./src/contracts/registry.ts --out ./generated/openapi.json`})]}),Ge(qt,{title:"Want exports tied to product decisions?",body:"Studio compiles approved changes into deliverables and pushes them to your execution stack with full evidence context."})]}),Ia("div",{className:"flex items-center gap-4 pt-4",children:[Ia($c,{href:"/docs/guides/docs-generation-pipeline",className:"btn-primary",children:["Next: Docs pipeline ",Ge(yu,{size:16})]}),Ge($c,{href:"/docs/guides",className:"btn-ghost",children:"Back to guides"})]})]})}import{CodeBlock as di}from"@contractspec/lib.design-system";import Xc from"@contractspec/lib.ui-link";import{ChevronRight as vu}from"lucide-react";import{jsx as q,jsxs as Vt}from"react/jsx-runtime";var Nu=["builder.workspace.bootstrap","builder.channel.receiveInbound","builder.blueprint.generate","builder.plan.compile","builder.preview.create","builder.preview.runHarness","builder.export.prepare","builder.export.approve","builder.export.execute"],wu=["local runtime trust and lease details","channel-action posture for mobile/operator follow-up","comparison posture and export readiness from the shared snapshot"];function ku(){return Vt("div",{className:"space-y-8",children:[Vt("div",{className:"space-y-3",children:[q("h1",{className:"font-bold text-4xl",children:"Host the Builder workbench"}),q("p",{className:"text-lg text-muted-foreground",children:"Use the reusable Builder workbench as the desktop control surface for snapshot loading, guided authoring, preview, readiness, export, and mobile review handoff."})]}),Vt("div",{className:"card-subtle space-y-4 p-6",children:[q("h2",{className:"font-bold text-2xl",children:"What you'll build"}),Vt("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[q("li",{children:"A workspace snapshot fetch path."}),q("li",{children:"A `BuilderWorkbench` host with action callbacks."}),q("li",{children:"Runtime-mode aware preview/export controls plus mobile review links."})]})]}),Vt("div",{className:"space-y-6",children:[Vt("div",{className:"space-y-3",children:[q("h2",{className:"font-bold text-2xl",children:"1) Fetch the workspace snapshot"}),q("p",{className:"text-muted-foreground text-sm",children:"The web shell already exposes a query path for the current Builder workspace snapshot. Your host should load it first, then refresh it after each successful command."}),q(di,{language:"typescript",filename:"builder-workbench-controller.ts",code:`export async function fetchBuilderSnapshot(workspaceId: string) {
|
|
1423
1423
|
const response = await fetch(
|
|
1424
1424
|
\`/api/operate/builder/queries/builder.workspace.snapshot?workspaceId=\${encodeURIComponent(workspaceId)}\`,
|
|
1425
1425
|
{ cache: "no-store" }
|
|
@@ -1488,7 +1488,7 @@ async function runAction(commandKey: string, payload?: Record<string, unknown>)
|
|
|
1488
1488
|
preset: "managed_mvp",
|
|
1489
1489
|
includeLocalHelperProvider: true,
|
|
1490
1490
|
},
|
|
1491
|
-
});`})]}),Vt("div",{className:"card-subtle space-y-3 p-6",children:[q("h3",{className:"font-semibold text-lg",children:"Common command keys"}),q("ul",{className:"space-y-2 text-muted-foreground text-sm",children:
|
|
1491
|
+
});`})]}),Vt("div",{className:"card-subtle space-y-3 p-6",children:[q("h3",{className:"font-semibold text-lg",children:"Common command keys"}),q("ul",{className:"space-y-2 text-muted-foreground text-sm",children:Nu.map((e)=>q("li",{children:q("code",{children:e})},e))})]}),Vt("div",{className:"card-subtle space-y-3 p-6",children:[q("h3",{className:"font-semibold text-lg",children:"Snapshot-backed operator details"}),q("ul",{className:"space-y-2 text-muted-foreground text-sm",children:wu.map((e)=>q("li",{children:e},e))})]}),Vt("div",{className:"space-y-3",children:[q("h2",{className:"font-bold text-2xl",children:"5) Keep runtime mode explicit"}),q("p",{className:"text-muted-foreground text-sm",children:"Preview and export flows are runtime-mode aware. The host chooses between `managed`, `local`, and `hybrid` and passes that choice into preview or export commands instead of hiding it behind provider selection heuristics."}),q(di,{language:"typescript",filename:"runtime-mode",code:`const [selectedExportRuntimeMode, setSelectedExportRuntimeMode] =
|
|
1492
1492
|
React.useState(resolveBuilderExportRuntimeMode(initialSnapshot));
|
|
1493
1493
|
|
|
1494
1494
|
await executeBuilderCommand({
|
|
@@ -1502,14 +1502,14 @@ await executeBuilderCommand({
|
|
|
1502
1502
|
cardId: string
|
|
1503
1503
|
) {
|
|
1504
1504
|
return \`/operate/builder/workspaces/\${encodeURIComponent(workspaceId)}/mobile-review/\${encodeURIComponent(cardId)}\`;
|
|
1505
|
-
}`}),q("p",{className:"text-muted-foreground text-sm",children:"Expected output: the same Builder workspace state stays visible from desktop workbench and mobile review surfaces."})]}),Vt("div",{className:"space-y-3",children:[q("h2",{className:"font-bold text-2xl",children:"7) Keep Connect adjacent, not embedded"}),q("p",{className:"text-muted-foreground text-sm",children:"Builder owns the authoring control plane. When Builder delegates into coding repositories, enable Connect in those target workspaces for context packs, mutation verification, replay, and review packets, but do not replace Builder contracts with Connect artifacts."}),q(di,{language:"bash",filename:"connect-init.sh",code:"contractspec connect init --scope workspace"})]})]}),Vt("div",{className:"flex items-center gap-4 pt-4",children:[Vt(
|
|
1505
|
+
}`}),q("p",{className:"text-muted-foreground text-sm",children:"Expected output: the same Builder workspace state stays visible from desktop workbench and mobile review surfaces."})]}),Vt("div",{className:"space-y-3",children:[q("h2",{className:"font-bold text-2xl",children:"7) Keep Connect adjacent, not embedded"}),q("p",{className:"text-muted-foreground text-sm",children:"Builder owns the authoring control plane. When Builder delegates into coding repositories, enable Connect in those target workspaces for context packs, mutation verification, replay, and review packets, but do not replace Builder contracts with Connect artifacts."}),q(di,{language:"bash",filename:"connect-init.sh",code:"contractspec connect init --scope workspace"})]})]}),Vt("div",{className:"flex items-center gap-4 pt-4",children:[Vt(Xc,{href:"/docs/specs/builder-control-plane",className:"btn-primary",children:["Back to Builder control plane ",q(vu,{size:16})]}),q(Xc,{href:"/docs/studio",className:"btn-ghost",children:"Studio overview"})]})]})}import{CodeBlock as si}from"@contractspec/lib.design-system";import xc from"@contractspec/lib.ui-link";import{AlertCircle as Su,ChevronRight as Cu,FileCode as Iu,Scan as nn,Settings as Pu}from"lucide-react";import{jsx as c,jsxs as S}from"react/jsx-runtime";var Tu=[{name:"NestJS",flag:"nestjs",description:"Controllers, decorators, DTOs"},{name:"Express",flag:"express",description:"Router methods, middleware"},{name:"Fastify",flag:"fastify",description:"Route definitions, schemas"},{name:"Hono",flag:"hono",description:"Route handlers, validators"},{name:"Elysia",flag:"elysia",description:"Type-safe routes, schemas"},{name:"tRPC",flag:"trpc",description:"Procedure definitions"},{name:"Next.js",flag:"next-api",description:"API routes (app/api, pages/api)"}];function Au(){return S("div",{className:"space-y-8",children:[S("div",{className:"space-y-3",children:[c("h1",{className:"font-bold text-4xl",children:"Import Existing Codebases"}),c("p",{className:"text-lg text-muted-foreground",children:"Convert your existing API endpoints into ContractSpec contracts. Auto-detect frameworks, extract schemas, and generate explicit contract definitions from your code."})]}),S("div",{className:"card-subtle space-y-4 p-6",children:[c("h2",{className:"font-bold text-2xl",children:"What you'll learn"}),S("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[c("li",{children:"How to import existing API endpoints as ContractSpec contracts."}),c("li",{children:"Framework-specific patterns and auto-detection."}),c("li",{children:"Customizing imports with scopes, dry-run, and output options."}),c("li",{children:"Registering imported contracts and adding handlers."})]})]}),S("div",{className:"space-y-6",children:[S("div",{className:"space-y-3",children:[c("h2",{className:"font-bold text-2xl",children:"Why import existing code?"}),c("p",{className:"text-muted-foreground text-sm",children:"Instead of writing contracts from scratch, the import command extracts endpoint patterns from your existing codebase. This gives you:"}),S("ul",{className:"list-disc space-y-1 pl-5 text-muted-foreground text-sm",children:[c("li",{children:"Instant spec coverage for existing APIs"}),c("li",{children:"Type-safe schemas derived from your existing types"}),c("li",{children:"A foundation to iterate and refine contracts"}),c("li",{children:"Gradual adoption without rewriting code"})]})]}),S("div",{className:"space-y-3",children:[c("h2",{className:"font-bold text-2xl",children:"Supported frameworks"}),c("div",{className:"grid gap-3 md:grid-cols-2 lg:grid-cols-3",children:Tu.map((e)=>S("div",{className:"flex items-start gap-3 rounded-lg border border-white/10 p-4",children:[c(Iu,{className:"text-violet-400",size:18}),S("div",{className:"space-y-1",children:[c("h3",{className:"font-semibold",children:e.name}),c("p",{className:"text-muted-foreground text-xs",children:e.description}),S("code",{className:"text-violet-400 text-xs",children:["--framework ",e.flag]})]})]},e.flag))})]}),S("div",{className:"space-y-3",children:[c("h2",{className:"font-bold text-2xl",children:"1) Quick start"}),c("p",{className:"text-muted-foreground text-sm",children:"Run the import command to auto-detect your framework and extract endpoints:"}),c(si,{language:"bash",filename:"import-quickstart",code:`# Auto-detect framework and import all endpoints
|
|
1506
1506
|
contractspec import ./src
|
|
1507
1507
|
|
|
1508
1508
|
# Preview what would be imported (dry-run)
|
|
1509
1509
|
contractspec import ./src --dry-run
|
|
1510
1510
|
|
|
1511
1511
|
# Force a specific framework
|
|
1512
|
-
contractspec import ./src --framework nestjs`}),c("p",{className:"text-muted-foreground text-sm",children:"Expected output: A summary of endpoints found, schemas extracted, and files generated."})]}),S("div",{className:"space-y-3",children:[c("h2",{className:"font-bold text-2xl",children:"2) Framework-specific patterns"}),c("p",{className:"text-muted-foreground text-sm",children:"The import command recognizes these patterns in each framework:"})]}),S("div",{className:"space-y-3",children:[S("h3",{className:"flex items-center gap-2 font-semibold text-xl",children:[c(
|
|
1512
|
+
contractspec import ./src --framework nestjs`}),c("p",{className:"text-muted-foreground text-sm",children:"Expected output: A summary of endpoints found, schemas extracted, and files generated."})]}),S("div",{className:"space-y-3",children:[c("h2",{className:"font-bold text-2xl",children:"2) Framework-specific patterns"}),c("p",{className:"text-muted-foreground text-sm",children:"The import command recognizes these patterns in each framework:"})]}),S("div",{className:"space-y-3",children:[S("h3",{className:"flex items-center gap-2 font-semibold text-xl",children:[c(nn,{size:18,className:"text-blue-400"}),"NestJS"]}),c(si,{language:"typescript",filename:"src/users/users.controller.ts (before)",code:`@Controller('users')
|
|
1513
1513
|
export class UsersController {
|
|
1514
1514
|
@Get(':id')
|
|
1515
1515
|
async getUser(@Param('id') id: string): Promise<UserDto> {
|
|
@@ -1521,7 +1521,7 @@ export class UsersController {
|
|
|
1521
1521
|
async createUser(@Body() dto: CreateUserDto): Promise<UserDto> {
|
|
1522
1522
|
return this.usersService.create(dto);
|
|
1523
1523
|
}
|
|
1524
|
-
}`}),S("p",{className:"text-muted-foreground text-sm",children:["Detected: ",c("code",{children:"@Controller"}),", ",c("code",{children:"@Get"}),","," ",c("code",{children:"@Post"}),", ",c("code",{children:"@Body"}),", ",c("code",{children:"@Param"}),","," ",c("code",{children:"@UseGuards"})," decorators."]})]}),S("div",{className:"space-y-3",children:[S("h3",{className:"flex items-center gap-2 font-semibold text-xl",children:[c(
|
|
1524
|
+
}`}),S("p",{className:"text-muted-foreground text-sm",children:["Detected: ",c("code",{children:"@Controller"}),", ",c("code",{children:"@Get"}),","," ",c("code",{children:"@Post"}),", ",c("code",{children:"@Body"}),", ",c("code",{children:"@Param"}),","," ",c("code",{children:"@UseGuards"})," decorators."]})]}),S("div",{className:"space-y-3",children:[S("h3",{className:"flex items-center gap-2 font-semibold text-xl",children:[c(nn,{size:18,className:"text-green-400"}),"Express"]}),c(si,{language:"typescript",filename:"src/routes/users.ts (before)",code:`const router = express.Router();
|
|
1525
1525
|
|
|
1526
1526
|
router.get('/users/:id', async (req, res) => {
|
|
1527
1527
|
const user = await getUserById(req.params.id);
|
|
@@ -1531,7 +1531,7 @@ router.get('/users/:id', async (req, res) => {
|
|
|
1531
1531
|
router.post('/users', validateBody(CreateUserSchema), async (req, res) => {
|
|
1532
1532
|
const user = await createUser(req.body);
|
|
1533
1533
|
res.status(201).json(user);
|
|
1534
|
-
});`}),S("p",{className:"text-muted-foreground text-sm",children:["Detected: ",c("code",{children:"router.get"}),", ",c("code",{children:"router.post"}),", validation middleware, Zod schemas."]})]}),S("div",{className:"space-y-3",children:[S("h3",{className:"flex items-center gap-2 font-semibold text-xl",children:[c(
|
|
1534
|
+
});`}),S("p",{className:"text-muted-foreground text-sm",children:["Detected: ",c("code",{children:"router.get"}),", ",c("code",{children:"router.post"}),", validation middleware, Zod schemas."]})]}),S("div",{className:"space-y-3",children:[S("h3",{className:"flex items-center gap-2 font-semibold text-xl",children:[c(nn,{size:18,className:"text-purple-400"}),"Next.js API Routes"]}),c(si,{language:"typescript",filename:"app/api/users/[id]/route.ts (before)",code:`export async function GET(
|
|
1535
1535
|
request: Request,
|
|
1536
1536
|
{ params }: { params: { id: string } }
|
|
1537
1537
|
) {
|
|
@@ -1603,7 +1603,7 @@ export const CreateUserCommand = defineCommand({
|
|
|
1603
1603
|
transport: {
|
|
1604
1604
|
rest: { method: "POST", path: "/users" },
|
|
1605
1605
|
},
|
|
1606
|
-
});`})]}),S("div",{className:"space-y-3",children:[c("h2",{className:"font-bold text-2xl",children:"4) Customizing imports"}),S("div",{className:"flex items-center gap-2",children:[c(
|
|
1606
|
+
});`})]}),S("div",{className:"space-y-3",children:[c("h2",{className:"font-bold text-2xl",children:"4) Customizing imports"}),S("div",{className:"flex items-center gap-2",children:[c(Pu,{size:18,className:"text-violet-400"}),c("h3",{className:"font-semibold text-lg",children:"Available options"})]}),c("div",{className:"overflow-x-auto",children:S("table",{className:"w-full text-sm",children:[c("thead",{children:S("tr",{className:"border-white/10 border-b",children:[c("th",{className:"py-2 pr-4 text-left",children:"Option"}),c("th",{className:"py-2 pr-4 text-left",children:"Description"}),c("th",{className:"py-2 text-left",children:"Example"})]})}),S("tbody",{className:"text-muted-foreground",children:[S("tr",{className:"border-white/5 border-b",children:[c("td",{className:"py-2 pr-4",children:c("code",{children:"--scope"})}),c("td",{className:"py-2 pr-4",children:"Limit to specific directories"}),c("td",{className:"py-2",children:c("code",{children:"--scope src/users src/auth"})})]}),S("tr",{className:"border-white/5 border-b",children:[c("td",{className:"py-2 pr-4",children:c("code",{children:"--framework"})}),c("td",{className:"py-2 pr-4",children:"Force a specific framework"}),c("td",{className:"py-2",children:c("code",{children:"--framework express"})})]}),S("tr",{className:"border-white/5 border-b",children:[c("td",{className:"py-2 pr-4",children:c("code",{children:"--output"})}),c("td",{className:"py-2 pr-4",children:"Output directory"}),c("td",{className:"py-2",children:c("code",{children:"--output ./contracts"})})]}),S("tr",{className:"border-white/5 border-b",children:[c("td",{className:"py-2 pr-4",children:c("code",{children:"--dry-run"})}),c("td",{className:"py-2 pr-4",children:"Preview without writing files"}),c("td",{className:"py-2",children:c("code",{children:"--dry-run"})})]}),S("tr",{className:"border-white/5 border-b",children:[c("td",{className:"py-2 pr-4",children:c("code",{children:"--analyze"})}),c("td",{className:"py-2 pr-4",children:"Analysis only, no code generation"}),c("td",{className:"py-2",children:c("code",{children:"--analyze"})})]}),S("tr",{children:[c("td",{className:"py-2 pr-4",children:c("code",{children:"--json"})}),c("td",{className:"py-2 pr-4",children:"Output as JSON for scripting"}),c("td",{className:"py-2",children:c("code",{children:"--json"})})]})]})]})}),c(si,{language:"bash",filename:"import-options",code:`# Import only specific modules
|
|
1607
1607
|
contractspec import ./src --scope src/users src/orders
|
|
1608
1608
|
|
|
1609
1609
|
# Preview with analysis
|
|
@@ -1633,7 +1633,7 @@ installOp(registry, GetUserQuery, async (input) => {
|
|
|
1633
1633
|
installOp(registry, CreateUserCommand, async (input) => {
|
|
1634
1634
|
const user = await db.user.create({ data: input });
|
|
1635
1635
|
return { id: user.id };
|
|
1636
|
-
});`})]}),S("div",{className:"space-y-3",children:[c("h2",{className:"font-bold text-2xl",children:"6) After importing"}),S("ol",{className:"list-decimal space-y-2 pl-5 text-muted-foreground text-sm",children:[S("li",{children:[c("strong",{children:"Review generated contracts"})," — Check the TODO placeholders and fill in descriptions, owners, and tags."]}),S("li",{children:[c("strong",{children:"Refine schemas"})," — Add proper types, validation rules, and error definitions."]}),S("li",{children:[c("strong",{children:"Run validation"})," —"," ",c("code",{children:"contractspec validate"})," to ensure contracts are valid."]}),S("li",{children:[c("strong",{children:"Register and wire handlers"})," — Connect contracts to your existing business logic."]}),S("li",{children:[c("strong",{children:"Iterate"})," — The imported contracts are a starting point. Refine them as your spec matures."]})]})]}),S("div",{className:"space-y-3",children:[S("h2",{className:"flex items-center gap-2 font-bold text-2xl",children:[c(
|
|
1636
|
+
});`})]}),S("div",{className:"space-y-3",children:[c("h2",{className:"font-bold text-2xl",children:"6) After importing"}),S("ol",{className:"list-decimal space-y-2 pl-5 text-muted-foreground text-sm",children:[S("li",{children:[c("strong",{children:"Review generated contracts"})," — Check the TODO placeholders and fill in descriptions, owners, and tags."]}),S("li",{children:[c("strong",{children:"Refine schemas"})," — Add proper types, validation rules, and error definitions."]}),S("li",{children:[c("strong",{children:"Run validation"})," —"," ",c("code",{children:"contractspec validate"})," to ensure contracts are valid."]}),S("li",{children:[c("strong",{children:"Register and wire handlers"})," — Connect contracts to your existing business logic."]}),S("li",{children:[c("strong",{children:"Iterate"})," — The imported contracts are a starting point. Refine them as your spec matures."]})]})]}),S("div",{className:"space-y-3",children:[S("h2",{className:"flex items-center gap-2 font-bold text-2xl",children:[c(Su,{size:20,className:"text-yellow-400"}),"Troubleshooting"]}),S("div",{className:"space-y-4",children:[S("div",{className:"card-subtle space-y-2 p-4",children:[c("h3",{className:"font-semibold",children:"Framework not detected"}),S("p",{className:"text-muted-foreground text-sm",children:["Use ",c("code",{children:"--framework <name>"})," to force a specific framework. Check that your entry files follow standard patterns."]})]}),S("div",{className:"card-subtle space-y-2 p-4",children:[c("h3",{className:"font-semibold",children:"Missing schemas"}),S("p",{className:"text-muted-foreground text-sm",children:["Schema inference works best with explicit types. If using"," ",c("code",{children:"any"})," or dynamic types, you'll see TODO placeholders. Fill them in manually."]})]}),S("div",{className:"card-subtle space-y-2 p-4",children:[c("h3",{className:"font-semibold",children:"Partial imports"}),S("p",{className:"text-muted-foreground text-sm",children:["Some endpoints may not be detected if they use unconventional patterns. Use ",c("code",{children:"--analyze"})," to see what was found, then add missing contracts manually."]})]})]})]}),c(qt,{title:"Want evidence-driven migration priorities?",body:"Studio clusters product signals into scored patterns, then proposes contract changes and execution-ready work for the highest-impact areas."})]}),S("div",{className:"flex items-center gap-4 pt-4",children:[S(xc,{href:"/docs/guides/spec-validation-and-typing",className:"btn-primary",children:["Next: Spec validation + typing ",c(Cu,{size:16})]}),c(xc,{href:"/docs/guides",className:"btn-ghost",children:"Back to guides"})]})]})}import{CodeBlock as Ai}from"@contractspec/lib.design-system";import jc from"@contractspec/lib.ui-link";import{ChevronRight as Ru}from"lucide-react";import{jsx as we,jsxs as pt}from"react/jsx-runtime";function Lu(){return pt("div",{className:"space-y-8",children:[pt("div",{className:"space-y-3",children:[we("h1",{className:"font-bold text-4xl",children:"Next.js: add one endpoint"}),we("p",{className:"text-lg text-muted-foreground",children:"Add ContractSpec to an existing Next.js App Router project by wiring a single operation end-to-end with validation and types."})]}),pt("div",{className:"card-subtle space-y-4 p-6",children:[we("h2",{className:"font-bold text-2xl",children:"What you'll build"}),pt("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[we("li",{children:"One OperationSpec with SchemaModel validation."}),we("li",{children:"A registry wiring the operation to its handler."}),we("li",{children:"A Next.js route handler that exposes the operation."})]})]}),pt("div",{className:"space-y-6",children:[pt("div",{className:"space-y-3",children:[we("h2",{className:"font-bold text-2xl",children:"1) Install core packages"}),we(Ai,{language:"bash",filename:"nextjs-install",code:`bun add -D contractspec
|
|
1637
1637
|
bun add @contractspec/lib.contracts-spec @contractspec/lib.contracts-runtime-server-rest @contractspec/lib.schema`}),pt("p",{className:"text-muted-foreground text-sm",children:["Expected output: ",we("code",{children:"added 3 packages"})," and a lockfile update."]})]}),pt("div",{className:"space-y-3",children:[we("h2",{className:"font-bold text-2xl",children:"2) Define the operation spec"}),pt("p",{className:"text-muted-foreground text-sm",children:["Create ",we("code",{children:"src/contracts/healthcheck.operation.ts"}),":"]}),we(Ai,{language:"typescript",filename:"src/contracts/healthcheck.operation.ts",code:`import { defineQuery } from "@contractspec/lib.contracts-spec/operations";
|
|
1638
1638
|
import { SchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
|
|
1639
1639
|
|
|
@@ -1688,7 +1688,7 @@ export { handler as GET, handler as POST };`}),pt("p",{className:"text-muted-for
|
|
|
1688
1688
|
contractspec examples show lifecycle-dashboard
|
|
1689
1689
|
|
|
1690
1690
|
# Validate all example manifests in this repo
|
|
1691
|
-
contractspec examples validate --repo-root .`})]}),we(qt,{title:"Want real product evidence behind endpoint changes?",body:"Studio correlates meetings, support, analytics, and code signals before compiling endpoint decisions into spec diffs."})]}),pt("div",{className:"flex items-center gap-4 pt-4",children:[pt(
|
|
1691
|
+
contractspec examples validate --repo-root .`})]}),we(qt,{title:"Want real product evidence behind endpoint changes?",body:"Studio correlates meetings, support, analytics, and code signals before compiling endpoint decisions into spec diffs."})]}),pt("div",{className:"flex items-center gap-4 pt-4",children:[pt(jc,{href:"/docs/guides/spec-validation-and-typing",className:"btn-primary",children:["Next: Spec validation + typing ",we(Ru,{size:16})]}),we(jc,{href:"/docs/guides",className:"btn-ghost",children:"Back to guides"})]})]})}import{CodeBlock as wr}from"@contractspec/lib.design-system";import el from"@contractspec/lib.ui-link";import{ChevronRight as Du}from"lucide-react";import{jsx as Ee,jsxs as Pa}from"react/jsx-runtime";var Eu=["root `README.md` and generated root `AGENTS.md` inputs when contributor or operator workflow changes","the nearest package `README.md` and `AGENTS.md` for any touched public package surface","website docs and `/llms*` summaries when the release changes how users or contributors should work"];function Ou(){return Pa("div",{className:"space-y-8",children:[Pa("div",{className:"space-y-3",children:[Ee("h1",{className:"font-bold text-4xl",children:"Author release capsules"}),Ee("p",{className:"text-lg text-muted-foreground",children:"Pair each publishable changeset with a structured release capsule so changelog, upgrade, and docs surfaces all read from the same release source of truth."})]}),Pa("div",{className:"card-subtle space-y-4 p-6",children:[Ee("h2",{className:"font-bold text-2xl",children:"What you'll build"}),Pa("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[Pa("li",{children:["A ",Ee("code",{children:".changeset/<slug>.md"})," file for package/version intent."]}),Pa("li",{children:["A ",Ee("code",{children:".changeset/<slug>.release.yaml"})," companion for audiences, migrations, validation, and evidence."]}),Ee("li",{children:"Generated release artifacts that the website changelog and upgrade flows can consume safely."})]})]}),Pa("div",{className:"space-y-6",children:[Pa("div",{className:"space-y-3",children:[Ee("h2",{className:"font-bold text-2xl",children:"1) Create the paired changeset files"}),Ee("p",{className:"text-muted-foreground text-sm",children:"The Markdown file states the package bumps and reader-facing change intent. The YAML file carries the structured release metadata."}),Ee(wr,{language:"yaml",filename:".changeset/contract-dx-first-slice.release.yaml",code:`schemaVersion: "1"
|
|
1692
1692
|
slug: contract-dx-first-slice
|
|
1693
1693
|
summary: Improve app-config, theme, and feature authoring with explicit validation and shared setup alignment.
|
|
1694
1694
|
isBreaking: false
|
|
@@ -1702,7 +1702,7 @@ validation:
|
|
|
1702
1702
|
- "Package-level validation entrypoints now back setup, docs, and CLI authoring flows."`}),Ee("p",{className:"text-muted-foreground text-sm",children:"Expected output: every publishable slug has both the human-facing changeset and the structured release capsule beside it."})]}),Pa("div",{className:"space-y-3",children:[Ee("h2",{className:"font-bold text-2xl",children:"2) Use the release authoring commands instead of raw drift-prone edits"}),Ee(wr,{language:"bash",filename:"release-authoring",code:`contractspec release init --summary "Improve app-config, theme, and feature authoring"
|
|
1703
1703
|
|
|
1704
1704
|
# Or revise an existing capsule with the guided flow
|
|
1705
|
-
contractspec release edit contract-dx-first-slice`}),Ee("p",{className:"text-muted-foreground text-sm",children:"Expected output: the CLI scaffolds or revises the paired files with the current release schema instead of leaving maintainers to hand-roll YAML structure."})]}),Pa("div",{className:"space-y-3",children:[Ee("h2",{className:"font-bold text-2xl",children:"3) Build the generated release artifacts before consuming them"}),Ee(wr,{language:"bash",filename:"release-build",code:"contractspec release build"}),Ee("p",{className:"text-muted-foreground text-sm",children:"Expected output: `generated/releases/manifest.json`, `generated/releases/upgrade-manifest.json`, and the related customer/maintainer guidance files are refreshed from the release capsules."})]}),Pa("div",{className:"space-y-3",children:[Ee("h2",{className:"font-bold text-2xl",children:"4) Enforce completeness before publishing or building the changelog"}),Ee(wr,{language:"bash",filename:"release-check",code:"contractspec release check --strict"}),Ee("p",{className:"text-muted-foreground text-sm",children:"Expected output: missing capsules, incomplete migration guidance, or stale generated release artifacts are flagged before the website changelog or publish workflow treats the release data as canonical."})]}),Pa("div",{className:"card-subtle space-y-3 p-6",children:[Ee("h3",{className:"font-semibold text-lg",children:"5) Sync the public docs if workflow expectations changed"}),Ee("ul",{className:"space-y-2 text-muted-foreground text-sm",children:
|
|
1705
|
+
contractspec release edit contract-dx-first-slice`}),Ee("p",{className:"text-muted-foreground text-sm",children:"Expected output: the CLI scaffolds or revises the paired files with the current release schema instead of leaving maintainers to hand-roll YAML structure."})]}),Pa("div",{className:"space-y-3",children:[Ee("h2",{className:"font-bold text-2xl",children:"3) Build the generated release artifacts before consuming them"}),Ee(wr,{language:"bash",filename:"release-build",code:"contractspec release build"}),Ee("p",{className:"text-muted-foreground text-sm",children:"Expected output: `generated/releases/manifest.json`, `generated/releases/upgrade-manifest.json`, and the related customer/maintainer guidance files are refreshed from the release capsules."})]}),Pa("div",{className:"space-y-3",children:[Ee("h2",{className:"font-bold text-2xl",children:"4) Enforce completeness before publishing or building the changelog"}),Ee(wr,{language:"bash",filename:"release-check",code:"contractspec release check --strict"}),Ee("p",{className:"text-muted-foreground text-sm",children:"Expected output: missing capsules, incomplete migration guidance, or stale generated release artifacts are flagged before the website changelog or publish workflow treats the release data as canonical."})]}),Pa("div",{className:"card-subtle space-y-3 p-6",children:[Ee("h3",{className:"font-semibold text-lg",children:"5) Sync the public docs if workflow expectations changed"}),Ee("ul",{className:"space-y-2 text-muted-foreground text-sm",children:Eu.map((e)=>Ee("li",{children:e},e))})]})]}),Pa("div",{className:"flex items-center gap-4 pt-4",children:[Pa(el,{href:"/docs/guides/connect-in-a-repo",className:"btn-primary",children:["Connect guide ",Ee(Du,{size:16})]}),Ee(el,{href:"/changelog",className:"btn-ghost",children:"Website changelog"})]})]})}import{CodeBlock as kr}from"@contractspec/lib.design-system";import tl from"@contractspec/lib.ui-link";import{ChevronRight as Bu}from"lucide-react";import{jsx as ct,jsxs as Oa}from"react/jsx-runtime";function Mu(){return Oa("div",{className:"space-y-8",children:[Oa("div",{className:"space-y-3",children:[ct("h1",{className:"font-bold text-4xl",children:"Spec-driven validation + typing"}),ct("p",{className:"text-lg text-muted-foreground",children:"Define a single operation with SchemaModel, generate validation, and keep your existing handler logic."})]}),Oa("div",{className:"card-subtle space-y-4 p-6",children:[ct("h2",{className:"font-bold text-2xl",children:"What you'll build"}),Oa("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[ct("li",{children:"One command spec with explicit input/output models."}),ct("li",{children:"Validation + typing without rewriting your service layer."}),ct("li",{children:"Clear acceptance scenarios for regression safety."})]})]}),Oa("div",{className:"space-y-6",children:[Oa("div",{className:"space-y-3",children:[ct("h2",{className:"font-bold text-2xl",children:"1) Define the spec"}),Oa("p",{className:"text-muted-foreground text-sm",children:["Create ",ct("code",{children:"src/contracts/contact-create.operation.ts"}),":"]}),ct(kr,{language:"typescript",filename:"src/contracts/contact-create.operation.ts",code:`import { defineCommand } from "@contractspec/lib.contracts-spec/operations";
|
|
1706
1706
|
import { SchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
|
|
1707
1707
|
|
|
1708
1708
|
const ContactInput = new SchemaModel({
|
|
@@ -1764,11 +1764,11 @@ export const ContactCreateCommand = defineCommand({
|
|
|
1764
1764
|
cd packages/examples/crm-pipeline
|
|
1765
1765
|
bun install
|
|
1766
1766
|
bun run build
|
|
1767
|
-
bun run validate`})]}),ct(qt,{title:"Need validation tied to real outcomes?",body:"Studio links checks to evidence, focus decisions, and post-release verification so specs evolve with product truth."})]}),Oa("div",{className:"flex items-center gap-4 pt-4",children:[Oa(
|
|
1767
|
+
bun run validate`})]}),ct(qt,{title:"Need validation tied to real outcomes?",body:"Studio links checks to evidence, focus decisions, and post-release verification so specs evolve with product truth."})]}),Oa("div",{className:"flex items-center gap-4 pt-4",children:[Oa(tl,{href:"/docs/guides/generate-docs-clients-schemas",className:"btn-primary",children:["Next: Generate docs + clients ",ct(Bu,{size:16})]}),ct(tl,{href:"/docs/guides",className:"btn-ghost",children:"Back to guides"})]})]})}import{CodeBlock as Uu}from"@contractspec/lib.design-system";import Wu from"@contractspec/lib.ui-link";import{ArrowRight as _u,CheckCircle2 as zu,GitBranch as Gu}from"lucide-react";import{jsx as Ft,jsxs as Ba}from"react/jsx-runtime";var qu=[{title:"Adopt one endpoint in Next.js",description:"Start inside a live app with one operation, one generated surface, and one clearly bounded change.",href:"/docs/guides/nextjs-one-endpoint",time:"25 min"},{title:"Import an existing codebase",description:"Stabilize what already exists instead of treating adoption as a rewrite project.",href:"/docs/guides/import-existing-codebases",time:"20 min"},{title:"Validation and typing",description:"Keep runtime validation and TypeScript behavior aligned from the same source definitions.",href:"/docs/guides/spec-validation-and-typing",time:"20 min"},{title:"Generate docs and clients",description:"Publish stable docs, schemas, and client-facing artifacts from the contract layer.",href:"/docs/guides/generate-docs-clients-schemas",time:"20 min"},{title:"Docs pipeline",description:"Feed generated reference material into the docs site without confusing ownership.",href:"/docs/guides/docs-generation-pipeline",time:"20 min"},{title:"Build a first module bundle",description:"Define one bundle spec, resolve a surface plan, and render it through the React host layer.",href:"/docs/guides/first-module-bundle",time:"20 min"},{title:"Host the Builder workbench",description:"Wire a Builder workspace snapshot, common commands, runtime modes, and mobile review links into the reusable host.",href:"/docs/guides/host-builder-workbench",time:"20 min"},{title:"Use Connect in a repo",description:"Enable Connect, verify agent actions locally, and inspect the resulting review and replay artifacts.",href:"/docs/guides/connect-in-a-repo",time:"15 min"},{title:"Author release capsules",description:"Pair changesets with structured release capsules and generate the artifacts that changelog and upgrade flows consume.",href:"/docs/guides/release-capsules",time:"15 min"},{title:"CI diff gating",description:"Use deterministic checks to catch drift and risky changes before they ship.",href:"/docs/guides/ci-contract-diff-gating",time:"15 min"}];function Hu(){return Ba("div",{className:"space-y-10",children:[Ba("div",{className:"space-y-3",children:[Ft("p",{className:"editorial-kicker",children:"Build"}),Ft("h1",{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"Adoption guides for teams that want to keep their code."}),Ft("p",{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:"These guides assume you are introducing ContractSpec into a real code base. Start with a narrow surface, verify the generated outputs, and expand only after the contract loop feels trustworthy."})]}),Ft("div",{className:"grid gap-4 md:grid-cols-2",children:qu.map((e)=>Ba(Wu,{href:e.href,className:"editorial-panel",children:[Ba("div",{className:"flex items-start justify-between gap-4",children:[Ba("div",{children:[Ft("h2",{className:"font-semibold text-xl",children:e.title}),Ft("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:e.description})]}),Ft(_u,{className:"mt-1 shrink-0",size:18})]}),Ba("div",{className:"mt-4 flex items-center gap-2 text-muted-foreground text-xs",children:[Ft(zu,{size:14}),Ba("span",{children:["Target time: ",e.time]})]})]},e.href))}),Ba("div",{className:"editorial-panel space-y-4",children:[Ba("div",{className:"flex items-center gap-2 font-semibold text-[color:var(--rust)] text-sm uppercase tracking-[0.2em]",children:[Ft(Gu,{size:16}),"Working style"]}),Ba("ul",{className:"editorial-list",children:[Ba("li",{children:[Ft("span",{className:"editorial-list-marker"}),Ft("span",{children:"Run each guide in a branch or sandboxed workspace."})]}),Ba("li",{children:[Ft("span",{className:"editorial-list-marker"}),Ft("span",{children:"Prefer one bounded surface at a time: one endpoint, one workflow, one integration, one unsafe module."})]}),Ba("li",{children:[Ft("span",{className:"editorial-list-marker"}),Ft("span",{children:"Use the example and reference outputs to verify what changed, not just the narrative page."})]})]}),Ft(Uu,{language:"bash",filename:"guides-quickstart",code:`# list example systems
|
|
1768
1768
|
contractspec examples list
|
|
1769
1769
|
|
|
1770
1770
|
# validate the examples in this workspace
|
|
1771
|
-
contractspec examples validate --repo-root .`})]})]})}import{registerDocBlocks as
|
|
1771
|
+
contractspec examples validate --repo-root .`})]})]})}import{registerDocBlocks as Vu}from"@contractspec/lib.contracts-spec/docs";var Fu=[{id:"docs.guides.index",title:"Guides",summary:"Hands-on guides for adopting ContractSpec in real workflows.",kind:"goal",visibility:"public",route:"/docs/guides",tags:["guides","adoption"],body:`# Guides
|
|
1772
1772
|
|
|
1773
1773
|
Hands-on, runnable guides that map to real adoption scenarios. Each guide includes commands, expected output, and a CI-verified example package.`},{id:"docs.guides.nextjs-one-endpoint",title:"Next.js one endpoint",summary:"Add ContractSpec to an existing Next.js app with one endpoint.",kind:"usage",visibility:"public",route:"/docs/guides/nextjs-one-endpoint",tags:["guides","nextjs","operations"],body:`# Add ContractSpec to a Next.js app (one endpoint)
|
|
1774
1774
|
|
|
@@ -1814,7 +1814,7 @@ bun docs:generate -- --version v1.0.0
|
|
|
1814
1814
|
|
|
1815
1815
|
Use the generated manifest and chunks under \`docs-index.manifest.json\` and \`docs-index.*.json\` to load the index at runtime.`},{id:"docs.guides.ci-contract-diff-gating",title:"CI gating for contract diffs",summary:"Gate changes with deterministic diffs and CI checks.",kind:"usage",visibility:"public",route:"/docs/guides/ci-contract-diff-gating",tags:["guides","ci","diff"],body:`# CI gating with deterministic diffs
|
|
1816
1816
|
|
|
1817
|
-
Run ContractSpec CI checks to detect drift and breaking changes before merge.`}];
|
|
1817
|
+
Run ContractSpec CI checks to detect drift and breaking changes before merge.`}];Vu(Fu);import{jsx as Ki,jsxs as cn}from"react/jsx-runtime";function Ku(){return cn("div",{className:"space-y-8",children:[cn("div",{className:"space-y-4",children:[Ki("h1",{className:"font-bold text-4xl",children:"Integration Circuit Breakers"}),Ki("p",{className:"text-lg text-muted-foreground",children:"External APIs are the most common source of instability. Wrap every integration call in a circuit breaker to protect your system."})]}),cn("div",{className:"space-y-4",children:[Ki("h2",{className:"font-bold text-2xl",children:"Pattern"}),Ki("p",{children:"Create a dedicated circuit breaker instance for each external service. This ensures that a failure in Stripe doesn't trigger the circuit breaker for Twilio."}),Ki("pre",{className:"rounded-lg border bg-muted p-4 text-sm",children:`// integrations/stripe.ts
|
|
1818
1818
|
import { CircuitBreaker } from '@contractspec/lib.resilience/circuit-breaker';
|
|
1819
1819
|
|
|
1820
1820
|
const stripeBreaker = new CircuitBreaker({
|
|
@@ -1824,7 +1824,7 @@ const stripeBreaker = new CircuitBreaker({
|
|
|
1824
1824
|
|
|
1825
1825
|
export async function createCharge(amount: number) {
|
|
1826
1826
|
return stripeBreaker.execute(() => stripe.charges.create({ amount }));
|
|
1827
|
-
}`})]})]})}import
|
|
1827
|
+
}`})]})]})}import al from"@contractspec/lib.ui-link";import{ChevronRight as Qu}from"lucide-react";import{jsx as da,jsxs as Yo}from"react/jsx-runtime";function Yu(){return Yo("div",{className:"space-y-8",children:[Yo("div",{className:"space-y-4",children:[da("h1",{className:"font-bold text-4xl",children:"ElevenLabs"}),da("p",{className:"text-muted-foreground",children:"ElevenLabs provides state-of-the-art text-to-speech and voice cloning technology. Create natural-sounding voiceovers, audiobooks, and voice assistants."})]}),Yo("div",{className:"space-y-4",children:[da("h2",{className:"font-bold text-2xl",children:"Setup"}),da("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:da("pre",{children:`# .env
|
|
1828
1828
|
ELEVENLABS_API_KEY=...`})})]}),Yo("div",{className:"space-y-4",children:[da("h2",{className:"font-bold text-2xl",children:"Text-to-Speech"}),da("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:da("pre",{children:`capabilityId: elevenlabs-tts
|
|
1829
1829
|
provider:
|
|
1830
1830
|
type: elevenlabs
|
|
@@ -1844,7 +1844,7 @@ outputs:
|
|
|
1844
1844
|
audioUrl:
|
|
1845
1845
|
type: string
|
|
1846
1846
|
audioData:
|
|
1847
|
-
type: buffer`})})]}),Yo("div",{className:"space-y-4",children:[da("h2",{className:"font-bold text-2xl",children:"Use cases"}),Yo("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[da("li",{children:"Generate voiceovers for videos"}),da("li",{children:"Create audio versions of articles"}),da("li",{children:"Build voice assistants"}),da("li",{children:"Produce audiobooks"})]})]}),Yo("div",{className:"flex items-center gap-4 pt-4",children:[da(
|
|
1847
|
+
type: buffer`})})]}),Yo("div",{className:"space-y-4",children:[da("h2",{className:"font-bold text-2xl",children:"Use cases"}),Yo("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[da("li",{children:"Generate voiceovers for videos"}),da("li",{children:"Create audio versions of articles"}),da("li",{children:"Build voice assistants"}),da("li",{children:"Produce audiobooks"})]})]}),Yo("div",{className:"flex items-center gap-4 pt-4",children:[da(al,{href:"/docs/integrations/mistral",className:"btn-ghost",children:"Previous: Mistral"}),Yo(al,{href:"/docs/integrations/qdrant",className:"btn-primary",children:["Next: Qdrant ",da(Qu,{size:16})]})]})]})}import ol from"@contractspec/lib.ui-link";import{ChevronRight as Ju}from"lucide-react";import{jsx as It,jsxs as Va}from"react/jsx-runtime";function Zu(){return Va("div",{className:"space-y-8",children:[Va("div",{className:"space-y-4",children:[It("h1",{className:"font-bold text-4xl",children:"GitHub Messaging"}),It("p",{className:"text-muted-foreground",children:"Use GitHub issue and pull request comments as an AI-native messaging channel with webhook verification, policy checks, and reliable outbound dispatch."})]}),Va("div",{className:"space-y-4",children:[It("h2",{className:"font-bold text-2xl",children:"Required secrets and config"}),It("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:It("pre",{children:`// secret payload
|
|
1848
1848
|
{
|
|
1849
1849
|
"token": "ghp_...",
|
|
1850
1850
|
"webhookSecret": "..."
|
|
@@ -1858,7 +1858,7 @@ outputs:
|
|
|
1858
1858
|
}`})})]}),Va("div",{className:"space-y-4",children:[It("h2",{className:"font-bold text-2xl",children:"Webhook ingress"}),Va("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Va("li",{children:["Inbound GitHub events are accepted on"," ",It("code",{className:"rounded bg-background/50 px-2 py-1",children:"/webhooks/github/events"}),"."]}),Va("li",{children:["Signatures are checked using"," ",It("code",{className:"rounded bg-background/50 px-2 py-1",children:"x-hub-signature-256"})," ","and the configured webhook secret."]}),It("li",{children:"Current normalization focuses on issue comment workflows and durable comment dispatch."})]})]}),Va("div",{className:"space-y-4",children:[It("h2",{className:"font-bold text-2xl",children:"Workspace mapping"}),It("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:It("pre",{children:`CHANNEL_WORKSPACE_MAP_GITHUB={"lssm-tech/contractspec":"workspace-acme"}
|
|
1859
1859
|
|
|
1860
1860
|
# Optional dev fallback (off by default)
|
|
1861
|
-
CHANNEL_ALLOW_UNMAPPED_WORKSPACE=0`})})]}),Va("div",{className:"space-y-4",children:[It("h2",{className:"font-bold text-2xl",children:"Best practices"}),Va("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[It("li",{children:"Use a least-privileged token scoped for comment operations."}),It("li",{children:"Route repositories explicitly with workspace maps in multi-tenant environments."}),It("li",{children:"Keep dispatch endpoints protected with token or bearer auth."})]})]}),Va("div",{className:"flex items-center gap-4 pt-4",children:[It(
|
|
1861
|
+
CHANNEL_ALLOW_UNMAPPED_WORKSPACE=0`})})]}),Va("div",{className:"space-y-4",children:[It("h2",{className:"font-bold text-2xl",children:"Best practices"}),Va("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[It("li",{children:"Use a least-privileged token scoped for comment operations."}),It("li",{children:"Route repositories explicitly with workspace maps in multi-tenant environments."}),It("li",{children:"Keep dispatch endpoints protected with token or bearer auth."})]})]}),Va("div",{className:"flex items-center gap-4 pt-4",children:[It(ol,{href:"/docs/integrations/slack",className:"btn-ghost",children:"Previous: Slack Messaging"}),Va(ol,{href:"/docs/integrations/whatsapp-meta",className:"btn-primary",children:["Next: WhatsApp Meta ",It(Ju,{size:16})]})]})]})}import il from"@contractspec/lib.ui-link";import{ChevronRight as $u}from"lucide-react";import{jsx as Kt,jsxs as Jo}from"react/jsx-runtime";function Xu(){return Jo("div",{className:"space-y-8",children:[Jo("div",{className:"space-y-4",children:[Kt("h1",{className:"font-bold text-4xl",children:"Gmail API"}),Kt("p",{className:"text-muted-foreground",children:"The Gmail API integration allows you to read inbound emails, manage threads, and build email-based workflows. Perfect for support tickets, email parsing, and automated responses."})]}),Jo("div",{className:"space-y-4",children:[Kt("h2",{className:"font-bold text-2xl",children:"Setup"}),Kt("p",{className:"text-muted-foreground",children:"Configure OAuth 2.0 credentials in Google Cloud Console:"}),Kt("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:Kt("pre",{children:`# .env
|
|
1862
1862
|
GOOGLE_CLIENT_ID=...
|
|
1863
1863
|
GOOGLE_CLIENT_SECRET=...
|
|
1864
1864
|
GOOGLE_REDIRECT_URI=https://your-app.com/auth/google/callback`})})]}),Jo("div",{className:"space-y-4",children:[Kt("h2",{className:"font-bold text-2xl",children:"Reading emails"}),Kt("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:Kt("pre",{children:`capabilityId: gmail-list-messages
|
|
@@ -1882,7 +1882,7 @@ outputs:
|
|
|
1882
1882
|
properties:
|
|
1883
1883
|
id: string
|
|
1884
1884
|
threadId: string
|
|
1885
|
-
snippet: string`})})]}),Jo("div",{className:"space-y-4",children:[Kt("h2",{className:"font-bold text-2xl",children:"Use cases"}),Jo("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Kt("li",{children:"Parse support emails and create tickets"}),Kt("li",{children:"Extract attachments and process them"}),Kt("li",{children:"Build email-to-task workflows"}),Kt("li",{children:"Monitor specific email threads"})]})]}),Jo("div",{className:"flex items-center gap-4 pt-4",children:[Kt(
|
|
1885
|
+
snippet: string`})})]}),Jo("div",{className:"space-y-4",children:[Kt("h2",{className:"font-bold text-2xl",children:"Use cases"}),Jo("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Kt("li",{children:"Parse support emails and create tickets"}),Kt("li",{children:"Extract attachments and process them"}),Kt("li",{children:"Build email-to-task workflows"}),Kt("li",{children:"Monitor specific email threads"})]})]}),Jo("div",{className:"flex items-center gap-4 pt-4",children:[Kt(il,{href:"/docs/integrations/resend",className:"btn-ghost",children:"Previous: Resend"}),Jo(il,{href:"/docs/integrations/google-calendar",className:"btn-primary",children:["Next: Google Calendar ",Kt($u,{size:16})]})]})]})}import rl from"@contractspec/lib.ui-link";import{ChevronRight as xu}from"lucide-react";import{jsx as fo,jsxs as Ri}from"react/jsx-runtime";function ju(){return Ri("div",{className:"space-y-8",children:[Ri("div",{className:"space-y-4",children:[fo("h1",{className:"font-bold text-4xl",children:"Google Calendar"}),fo("p",{className:"text-muted-foreground",children:"Integrate Google Calendar to schedule appointments, manage availability, and sync events with your application."})]}),Ri("div",{className:"space-y-4",children:[fo("h2",{className:"font-bold text-2xl",children:"Setup"}),fo("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:fo("pre",{children:`# .env
|
|
1886
1886
|
GOOGLE_CLIENT_ID=...
|
|
1887
1887
|
GOOGLE_CLIENT_SECRET=...
|
|
1888
1888
|
GOOGLE_CALENDAR_ID=primary`})})]}),Ri("div",{className:"space-y-4",children:[fo("h2",{className:"font-bold text-2xl",children:"Creating events"}),fo("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:fo("pre",{children:`capabilityId: calendar-create-event
|
|
@@ -1909,7 +1909,7 @@ outputs:
|
|
|
1909
1909
|
eventId:
|
|
1910
1910
|
type: string
|
|
1911
1911
|
htmlLink:
|
|
1912
|
-
type: string`})})]}),Ri("div",{className:"flex items-center gap-4 pt-4",children:[fo(
|
|
1912
|
+
type: string`})})]}),Ri("div",{className:"flex items-center gap-4 pt-4",children:[fo(rl,{href:"/docs/integrations/gmail",className:"btn-ghost",children:"Previous: Gmail API"}),Ri(rl,{href:"/docs/integrations/openai",className:"btn-primary",children:["Next: OpenAI ",fo(xu,{size:16})]})]})]})}import nl from"@contractspec/lib.ui-link";import{jsx as mt,jsxs as Fa}from"react/jsx-runtime";function eg(){return Fa("div",{className:"space-y-8",children:[Fa("div",{className:"space-y-4",children:[mt("h1",{className:"font-bold text-4xl",children:"Health Routing Strategy"}),mt("p",{className:"text-muted-foreground",children:"Health integrations resolve providers through deterministic transport strategy order with explicit capability gating and unofficial-route controls."})]}),Fa("div",{className:"space-y-4",children:[mt("h2",{className:"font-bold text-2xl",children:"Connection config fields"}),mt("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:mt("pre",{children:`{
|
|
1913
1913
|
"defaultTransport": "official-api",
|
|
1914
1914
|
"strategyOrder": [
|
|
1915
1915
|
"official-api",
|
|
@@ -1932,7 +1932,7 @@ outputs:
|
|
|
1932
1932
|
"tokenExpiresAt": "2026-02-01T00:00:00.000Z",
|
|
1933
1933
|
"mcpAccessToken": "...",
|
|
1934
1934
|
"webhookSecret": "..."
|
|
1935
|
-
}`})})]}),Fa("div",{className:"space-y-4",children:[mt("h2",{className:"font-bold text-2xl",children:"Routing behavior"}),Fa("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[mt("li",{children:"Unsupported strategies are skipped per provider capability matrix."}),mt("li",{children:"Missing credentials fail closed and fall through only when a later strategy is valid."}),Fa("li",{children:["Unofficial routes are disabled unless",mt("code",{className:"ml-1 rounded bg-background/50 px-2 py-1",children:"allowUnofficial"}),"is true."]}),Fa("li",{children:["When",mt("code",{className:"ml-1 rounded bg-background/50 px-2 py-1",children:"unofficialAllowList"}),"is set, only listed provider keys can route unofficially."]}),Fa("li",{children:["OAuth refresh uses",mt("code",{className:"ml-1 rounded bg-background/50 px-2 py-1",children:"oauthTokenUrl"}),"with refresh/client credentials when APIs return 401."]})]})]}),Fa("div",{className:"space-y-4",children:[mt("h2",{className:"font-bold text-2xl",children:"Provider guidance"}),Fa("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[mt("li",{children:"Use official APIs when available (Whoop, Oura, Strava, Fitbit)."}),mt("li",{children:"Use aggregator routing for providers without stable official APIs (Garmin, MyFitnessPal, Eight Sleep, Peloton)."}),mt("li",{children:"Keep unofficial automation opt-in and auditable for production."})]})]}),Fa("div",{className:"flex items-center gap-4 pt-4",children:[mt(
|
|
1935
|
+
}`})})]}),Fa("div",{className:"space-y-4",children:[mt("h2",{className:"font-bold text-2xl",children:"Routing behavior"}),Fa("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[mt("li",{children:"Unsupported strategies are skipped per provider capability matrix."}),mt("li",{children:"Missing credentials fail closed and fall through only when a later strategy is valid."}),Fa("li",{children:["Unofficial routes are disabled unless",mt("code",{className:"ml-1 rounded bg-background/50 px-2 py-1",children:"allowUnofficial"}),"is true."]}),Fa("li",{children:["When",mt("code",{className:"ml-1 rounded bg-background/50 px-2 py-1",children:"unofficialAllowList"}),"is set, only listed provider keys can route unofficially."]}),Fa("li",{children:["OAuth refresh uses",mt("code",{className:"ml-1 rounded bg-background/50 px-2 py-1",children:"oauthTokenUrl"}),"with refresh/client credentials when APIs return 401."]})]})]}),Fa("div",{className:"space-y-4",children:[mt("h2",{className:"font-bold text-2xl",children:"Provider guidance"}),Fa("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[mt("li",{children:"Use official APIs when available (Whoop, Oura, Strava, Fitbit)."}),mt("li",{children:"Use aggregator routing for providers without stable official APIs (Garmin, MyFitnessPal, Eight Sleep, Peloton)."}),mt("li",{children:"Keep unofficial automation opt-in and auditable for production."})]})]}),Fa("div",{className:"flex items-center gap-4 pt-4",children:[mt(nl,{href:"/docs/integrations/whatsapp-twilio",className:"btn-ghost",children:"Previous: WhatsApp Twilio"}),mt(nl,{href:"/docs/integrations",className:"btn-primary",children:"Back to Integrations"})]})]})}import cl from"@contractspec/lib.ui-link";import{ChevronRight as tg}from"lucide-react";import{jsx as qe,jsxs as io}from"react/jsx-runtime";function ag(){return io("div",{className:"space-y-8",children:[io("div",{className:"space-y-4",children:[qe("h1",{className:"font-bold text-4xl",children:"Mistral"}),qe("p",{className:"text-muted-foreground",children:"Integrate Mistral models for chat, reasoning, embeddings, speech-to-text, and conversational voice workflows. ContractSpec ships first-class Mistral support across contracts, provider runtime wiring, and CLI provider selection."})]}),io("div",{className:"space-y-4",children:[qe("h2",{className:"font-bold text-2xl",children:"Setup"}),qe("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:qe("pre",{children:`# .env
|
|
1936
1936
|
MISTRAL_API_KEY=...`})})]}),io("div",{className:"space-y-4",children:[qe("h2",{className:"font-bold text-2xl",children:"Chat and reasoning"}),qe("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:qe("pre",{children:`capabilityId: mistral-chat
|
|
1937
1937
|
provider:
|
|
1938
1938
|
type: mistral
|
|
@@ -1988,7 +1988,7 @@ outputs:
|
|
|
1988
1988
|
segments:
|
|
1989
1989
|
type: array
|
|
1990
1990
|
language:
|
|
1991
|
-
type: string`})})]}),io("div",{className:"space-y-4",children:[qe("h2",{className:"font-bold text-2xl",children:"Conversational voice sessions"}),qe("p",{className:"text-muted-foreground",children:"Use the conversational provider for session-based realtime voice flows (turn handling, events, and interruption-safe streaming)."})]}),io("div",{className:"space-y-4",children:[qe("h2",{className:"font-bold text-2xl",children:"Best practices"}),io("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[qe("li",{children:"Choose model families by workload: coding, reasoning, or speech"}),qe("li",{children:"Persist session IDs for conversational continuity across turns"}),qe("li",{children:"Capture token and latency telemetry for provider-level tuning"}),qe("li",{children:"Set explicit fallbacks for network and rate-limit failures"})]})]}),io("div",{className:"flex items-center gap-4 pt-4",children:[qe(
|
|
1991
|
+
type: string`})})]}),io("div",{className:"space-y-4",children:[qe("h2",{className:"font-bold text-2xl",children:"Conversational voice sessions"}),qe("p",{className:"text-muted-foreground",children:"Use the conversational provider for session-based realtime voice flows (turn handling, events, and interruption-safe streaming)."})]}),io("div",{className:"space-y-4",children:[qe("h2",{className:"font-bold text-2xl",children:"Best practices"}),io("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[qe("li",{children:"Choose model families by workload: coding, reasoning, or speech"}),qe("li",{children:"Persist session IDs for conversational continuity across turns"}),qe("li",{children:"Capture token and latency telemetry for provider-level tuning"}),qe("li",{children:"Set explicit fallbacks for network and rate-limit failures"})]})]}),io("div",{className:"flex items-center gap-4 pt-4",children:[qe(cl,{href:"/docs/integrations/openai",className:"btn-ghost",children:"Previous: OpenAI"}),io(cl,{href:"/docs/integrations/elevenlabs",className:"btn-primary",children:["Next: ElevenLabs ",qe(tg,{size:16})]})]})]})}import ll from"@contractspec/lib.ui-link";import{ChevronRight as og}from"lucide-react";import{jsx as Ze,jsxs as ho}from"react/jsx-runtime";function ig(){return ho("div",{className:"space-y-8",children:[ho("div",{className:"space-y-4",children:[Ze("h1",{className:"font-bold text-4xl",children:"OpenAI"}),Ze("p",{className:"text-muted-foreground",children:"Integrate OpenAI's powerful AI models for chat completion, embeddings, and speech-to-text. Build intelligent features with GPT-4, generate embeddings for semantic search, and transcribe audio with Whisper."})]}),ho("div",{className:"space-y-4",children:[Ze("h2",{className:"font-bold text-2xl",children:"Setup"}),Ze("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:Ze("pre",{children:`# .env
|
|
1992
1992
|
OPENAI_API_KEY=sk-...
|
|
1993
1993
|
OPENAI_ORGANIZATION=org-...`})})]}),ho("div",{className:"space-y-4",children:[Ze("h2",{className:"font-bold text-2xl",children:"Chat completions"}),Ze("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:Ze("pre",{children:`capabilityId: openai-chat
|
|
1994
1994
|
provider:
|
|
@@ -2047,7 +2047,7 @@ outputs:
|
|
|
2047
2047
|
text:
|
|
2048
2048
|
type: string
|
|
2049
2049
|
language:
|
|
2050
|
-
type: string`})})]}),ho("div",{className:"space-y-4",children:[Ze("h2",{className:"font-bold text-2xl",children:"Best practices"}),ho("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Ze("li",{children:"Use streaming for real-time chat responses"}),Ze("li",{children:"Cache embeddings to reduce API costs"}),Ze("li",{children:"Implement rate limiting to avoid quota issues"}),Ze("li",{children:"Store conversation history for context"}),Ze("li",{children:"Monitor token usage and costs"})]})]}),ho("div",{className:"flex items-center gap-4 pt-4",children:[Ze(
|
|
2050
|
+
type: string`})})]}),ho("div",{className:"space-y-4",children:[Ze("h2",{className:"font-bold text-2xl",children:"Best practices"}),ho("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Ze("li",{children:"Use streaming for real-time chat responses"}),Ze("li",{children:"Cache embeddings to reduce API costs"}),Ze("li",{children:"Implement rate limiting to avoid quota issues"}),Ze("li",{children:"Store conversation history for context"}),Ze("li",{children:"Monitor token usage and costs"})]})]}),ho("div",{className:"flex items-center gap-4 pt-4",children:[Ze(ll,{href:"/docs/integrations/google-calendar",className:"btn-ghost",children:"Previous: Google Calendar"}),ho(ll,{href:"/docs/integrations/mistral",className:"btn-primary",children:["Next: Mistral ",Ze(og,{size:16})]})]})]})}import ln from"@contractspec/lib.ui-link";import{jsx as Qt,jsxs as Ro}from"react/jsx-runtime";var rg=[{title:"Models and voice",items:[{title:"OpenAI",href:"/docs/integrations/openai"},{title:"Mistral",href:"/docs/integrations/mistral"},{title:"ElevenLabs",href:"/docs/integrations/elevenlabs"}]},{title:"Messaging and product operations",items:[{title:"GitHub",href:"/docs/integrations/github"},{title:"Slack",href:"/docs/integrations/slack"},{title:"Twilio",href:"/docs/integrations/twilio"},{title:"Postmark",href:"/docs/integrations/postmark"}]},{title:"Data, storage, and retrieval",items:[{title:"Qdrant",href:"/docs/integrations/qdrant"},{title:"S3 storage",href:"/docs/integrations/s3"},{title:"Gmail",href:"/docs/integrations/gmail"},{title:"Google Calendar",href:"/docs/integrations/google-calendar"}]},{title:"Payments and external workflows",items:[{title:"Stripe",href:"/docs/integrations/stripe"},{title:"Powens",href:"/docs/integrations/powens"},{title:"Circuit breakers",href:"/docs/integrations/circuit-breakers"},{title:"Health routing",href:"/docs/integrations/health-routing"}]}];function ng(){return Ro("div",{className:"space-y-10",children:[Ro("div",{className:"space-y-3",children:[Qt("p",{className:"editorial-kicker",children:"Integrations"}),Qt("h1",{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"Integrations stay explicit: spec what a provider offers, then bind it per tenant and per app."}),Qt("p",{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:"The integration model keeps provider behavior out of ad hoc glue code. Define the capability contract first, configure the provider connection explicitly, then bind the integration into app workflows and runtime surfaces with clear ownership."})]}),Ro("div",{className:"editorial-proof-strip",children:[Ro("div",{className:"editorial-stat",children:[Qt("span",{className:"editorial-label",children:"Binding model"}),Qt("span",{className:"editorial-stat-value",children:"Integration spec → tenant connection → app binding"})]}),Qt("p",{className:"max-w-2xl text-muted-foreground text-sm leading-7",children:"That separation is what makes reuse, tenant isolation, and provider swaps practical without rewriting every surface."})]}),Qt("section",{className:"editorial-panel space-y-5",children:Ro("div",{className:"space-y-2",children:[Qt("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Start with the model, then pick a provider"}),Ro("div",{className:"grid gap-4 md:grid-cols-2",children:[Ro(ln,{href:"/docs/integrations/spec-model",className:"docs-footer-link",children:[Qt("h3",{className:"font-semibold text-lg",children:"Integration spec model"}),Qt("p",{className:"text-muted-foreground text-sm leading-7",children:"Define what the provider offers, what configuration it needs, and how the runtime should treat it."})]}),Ro(ln,{href:"/docs/architecture/integration-binding",className:"docs-footer-link",children:[Qt("h3",{className:"font-semibold text-lg",children:"Integration binding"}),Qt("p",{className:"text-muted-foreground text-sm leading-7",children:"Understand how tenant connections get mapped into concrete app surfaces and workflows."})]})]})]})}),Qt("div",{className:"grid gap-5 md:grid-cols-2",children:rg.map((e)=>Ro("section",{className:"editorial-panel space-y-4",children:[Qt("h2",{className:"font-serif text-2xl tracking-[-0.03em]",children:e.title}),Qt("div",{className:"space-y-3",children:e.items.map((t)=>Qt(ln,{href:t.href,className:"docs-chip-link",children:t.title},t.href))})]},e.title))})]})}import dl from"@contractspec/lib.ui-link";import{ChevronRight as cg}from"lucide-react";import{jsx as ae,jsxs as Ut}from"react/jsx-runtime";function lg(){return Ut("div",{className:"space-y-8",children:[Ut("div",{className:"space-y-4",children:[ae("h1",{className:"font-bold text-4xl",children:"Postmark"}),ae("p",{className:"text-muted-foreground",children:"Postmark is a transactional email service with industry-leading deliverability. Use it to send order confirmations, password resets, notifications, and other critical emails."})]}),Ut("div",{className:"space-y-4",children:[ae("h2",{className:"font-bold text-2xl",children:"Setup"}),ae("p",{className:"text-muted-foreground",children:"Add your Postmark credentials to your environment variables:"}),ae("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:ae("pre",{children:`# .env
|
|
2051
2051
|
POSTMARK_API_TOKEN=...
|
|
2052
2052
|
POSTMARK_FROM_EMAIL=noreply@example.com
|
|
2053
2053
|
POSTMARK_FROM_NAME="Your App Name"`})}),Ut("p",{className:"text-muted-foreground text-sm",children:["Get your API token from the"," ",ae("a",{href:"https://account.postmarkapp.com/servers",target:"_blank",rel:"noopener noreferrer",className:"text-violet-400 hover:text-violet-300",children:"Postmark Dashboard"}),"."]})]}),Ut("div",{className:"space-y-4",children:[ae("h2",{className:"font-bold text-2xl",children:"Sending emails"}),ae("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:ae("pre",{children:`capabilityId: send-email
|
|
@@ -2093,7 +2093,7 @@ config:
|
|
|
2093
2093
|
templateId: "welcome-email"
|
|
2094
2094
|
templateData:
|
|
2095
2095
|
user_name: \${input.userName}
|
|
2096
|
-
login_url: "https://app.example.com/login"`})})]}),Ut("div",{className:"space-y-4",children:[ae("h2",{className:"font-bold text-2xl",children:"Webhooks"}),ae("p",{className:"text-muted-foreground",children:"Postmark can notify your app about delivery, bounces, and opens:"}),ae("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:ae("pre",{children:"https://your-app.com/api/webhooks/postmark"})}),ae("p",{className:"text-muted-foreground",children:"ContractSpec automatically processes these webhook events:"}),Ut("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Ut("li",{children:[ae("strong",{children:"Delivery"})," – Email was successfully delivered"]}),Ut("li",{children:[ae("strong",{children:"Bounce"})," – Email bounced (hard or soft)"]}),Ut("li",{children:[ae("strong",{children:"SpamComplaint"})," – Recipient marked email as spam"]}),Ut("li",{children:[ae("strong",{children:"Open"})," – Recipient opened the email"]}),Ut("li",{children:[ae("strong",{children:"Click"})," – Recipient clicked a link"]})]})]}),Ut("div",{className:"space-y-4",children:[ae("h2",{className:"font-bold text-2xl",children:"Best practices"}),Ut("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[ae("li",{children:"Use templates for consistent branding"}),ae("li",{children:"Always provide both HTML and plain text versions"}),ae("li",{children:"Monitor bounce rates and remove invalid addresses"}),ae("li",{children:"Use message streams to separate different email types"}),ae("li",{children:"Test emails in the Postmark sandbox before going live"}),ae("li",{children:"Set up DKIM and SPF records for your domain"})]})]}),Ut("div",{className:"flex items-center gap-4 pt-4",children:[ae(
|
|
2096
|
+
login_url: "https://app.example.com/login"`})})]}),Ut("div",{className:"space-y-4",children:[ae("h2",{className:"font-bold text-2xl",children:"Webhooks"}),ae("p",{className:"text-muted-foreground",children:"Postmark can notify your app about delivery, bounces, and opens:"}),ae("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:ae("pre",{children:"https://your-app.com/api/webhooks/postmark"})}),ae("p",{className:"text-muted-foreground",children:"ContractSpec automatically processes these webhook events:"}),Ut("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Ut("li",{children:[ae("strong",{children:"Delivery"})," – Email was successfully delivered"]}),Ut("li",{children:[ae("strong",{children:"Bounce"})," – Email bounced (hard or soft)"]}),Ut("li",{children:[ae("strong",{children:"SpamComplaint"})," – Recipient marked email as spam"]}),Ut("li",{children:[ae("strong",{children:"Open"})," – Recipient opened the email"]}),Ut("li",{children:[ae("strong",{children:"Click"})," – Recipient clicked a link"]})]})]}),Ut("div",{className:"space-y-4",children:[ae("h2",{className:"font-bold text-2xl",children:"Best practices"}),Ut("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[ae("li",{children:"Use templates for consistent branding"}),ae("li",{children:"Always provide both HTML and plain text versions"}),ae("li",{children:"Monitor bounce rates and remove invalid addresses"}),ae("li",{children:"Use message streams to separate different email types"}),ae("li",{children:"Test emails in the Postmark sandbox before going live"}),ae("li",{children:"Set up DKIM and SPF records for your domain"})]})]}),Ut("div",{className:"flex items-center gap-4 pt-4",children:[ae(dl,{href:"/docs/integrations/stripe",className:"btn-ghost",children:"Previous: Stripe"}),Ut(dl,{href:"/docs/integrations/resend",className:"btn-primary",children:["Next: Resend ",ae(cg,{size:16})]})]})]})}import sl from"@contractspec/lib.ui-link";import{ChevronRight as dg}from"lucide-react";import{jsx as J,jsxs as Oe}from"react/jsx-runtime";function sg(){return Oe("div",{className:"space-y-8",children:[Oe("div",{className:"space-y-4",children:[J("h1",{className:"font-bold text-4xl",children:"Powens Open Banking"}),J("p",{className:"text-muted-foreground",children:"Powens provides read-only open banking connectivity for ContractSpec applications. The reference integration powers Pocket Family Office by synchronising household bank accounts, transactions, and balances while keeping all raw PII protected."})]}),Oe("div",{className:"space-y-4",children:[J("h2",{className:"font-bold text-2xl",children:"Setup"}),J("p",{className:"text-muted-foreground",children:"Create a Powens BYOK project, then store the credentials in your secret manager. The ContractSpec integration expects the following fields:"}),J("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:J("pre",{children:`{
|
|
2097
2097
|
"clientId": "powens-client-id",
|
|
2098
2098
|
"clientSecret": "powens-client-secret",
|
|
2099
2099
|
"apiKey": "optional-api-key",
|
|
@@ -2148,7 +2148,7 @@ inputs:
|
|
|
2148
2148
|
outputs:
|
|
2149
2149
|
balances:
|
|
2150
2150
|
type: AccountBalanceRecord[]
|
|
2151
|
-
description: "Current/available balances with timestamps"`})})]}),Oe("div",{className:"space-y-4",children:[J("h2",{className:"font-bold text-2xl",children:"Primary workflows"}),Oe("div",{className:"space-y-3",children:[J("h3",{className:"font-semibold text-lg",children:"Account sync"}),Oe("p",{className:"text-muted-foreground",children:["The workflow"," ",J("code",{className:"rounded bg-background/50 px-2 py-1",children:"pfo.workflow.sync-openbanking-accounts"})," ","refreshes account metadata, then surfaces canonical records to other automations."]})]}),Oe("div",{className:"space-y-3",children:[J("h3",{className:"font-semibold text-lg",children:"Transaction sync"}),Oe("p",{className:"text-muted-foreground",children:[J("code",{className:"rounded bg-background/50 px-2 py-1",children:"pfo.workflow.sync-openbanking-transactions"})," ","ingests incremental transactions for each linked account and stores them in the canonical ledger."]})]}),Oe("div",{className:"space-y-3",children:[J("h3",{className:"font-semibold text-lg",children:"Balance refresh"}),Oe("p",{className:"text-muted-foreground",children:[J("code",{className:"rounded bg-background/50 px-2 py-1",children:"pfo.workflow.refresh-openbanking-balances"})," ","retrieves current and available balances to power dashboards and anomaly detection."]})]}),Oe("div",{className:"space-y-3",children:[J("h3",{className:"font-semibold text-lg",children:"Derived financial overview"}),Oe("p",{className:"text-muted-foreground",children:[J("code",{className:"rounded bg-background/50 px-2 py-1",children:"pfo.workflow.generate-openbanking-overview"})," ","aggregates balances, category breakdowns, and cashflow trends into the ",J("code",{children:"knowledge.financial-overview"})," space. Only derived summaries are exposed to LLMs."]})]})]}),Oe("div",{className:"space-y-4",children:[J("h2",{className:"font-bold text-2xl",children:"Telemetry & guardrails"}),Oe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Oe("li",{children:["Telemetry events such as"," ",J("code",{className:"rounded bg-background/50 px-2 py-1",children:"openbanking.accounts.synced"})," ","and"," ",J("code",{className:"rounded bg-background/50 px-2 py-1",children:"openbanking.transactions.synced"})," ","are emitted automatically with tenant, slot, and config metadata."]}),Oe("li",{children:["Guard helpers ensure the"," ",J("code",{className:"rounded bg-background/50 px-2 py-1",children:"primaryOpenBanking"})," ","slot is bound and healthy before workflows execute."]}),Oe("li",{children:["PII fields (IBAN, counterparty names, descriptions) are redacted via"," ",J("code",{className:"rounded bg-background/50 px-2 py-1",children:"redactOpenBankingTelemetryPayload"})," ","before logging or sending telemetry."]})]})]}),Oe("div",{className:"space-y-4",children:[J("h2",{className:"font-bold text-2xl",children:"Best practices"}),Oe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[J("li",{children:"Use BYOK credentials per tenant to avoid cross-tenant exposure."}),J("li",{children:"Store only canonical entities (BankAccountRecord, BankTransactionRecord). Never persist raw Powens payloads or customer PII in logs."}),J("li",{children:"Run the transaction sync on a schedule appropriate for banking SLAs (e.g. every 15 minutes for cashflow dashboards)."}),J("li",{children:"Pair ledger updates with derived summaries to feed the knowledge layer instead of exposing raw transactions to agents."}),Oe("li",{children:["Monitor telemetry for"," ",J("code",{className:"rounded bg-background/50 px-2 py-1",children:"openbanking.*.sync_failed"})," ","events to detect credential issues early."]})]})]}),Oe("div",{className:"flex items-center gap-4 pt-4",children:[J(
|
|
2151
|
+
description: "Current/available balances with timestamps"`})})]}),Oe("div",{className:"space-y-4",children:[J("h2",{className:"font-bold text-2xl",children:"Primary workflows"}),Oe("div",{className:"space-y-3",children:[J("h3",{className:"font-semibold text-lg",children:"Account sync"}),Oe("p",{className:"text-muted-foreground",children:["The workflow"," ",J("code",{className:"rounded bg-background/50 px-2 py-1",children:"pfo.workflow.sync-openbanking-accounts"})," ","refreshes account metadata, then surfaces canonical records to other automations."]})]}),Oe("div",{className:"space-y-3",children:[J("h3",{className:"font-semibold text-lg",children:"Transaction sync"}),Oe("p",{className:"text-muted-foreground",children:[J("code",{className:"rounded bg-background/50 px-2 py-1",children:"pfo.workflow.sync-openbanking-transactions"})," ","ingests incremental transactions for each linked account and stores them in the canonical ledger."]})]}),Oe("div",{className:"space-y-3",children:[J("h3",{className:"font-semibold text-lg",children:"Balance refresh"}),Oe("p",{className:"text-muted-foreground",children:[J("code",{className:"rounded bg-background/50 px-2 py-1",children:"pfo.workflow.refresh-openbanking-balances"})," ","retrieves current and available balances to power dashboards and anomaly detection."]})]}),Oe("div",{className:"space-y-3",children:[J("h3",{className:"font-semibold text-lg",children:"Derived financial overview"}),Oe("p",{className:"text-muted-foreground",children:[J("code",{className:"rounded bg-background/50 px-2 py-1",children:"pfo.workflow.generate-openbanking-overview"})," ","aggregates balances, category breakdowns, and cashflow trends into the ",J("code",{children:"knowledge.financial-overview"})," space. Only derived summaries are exposed to LLMs."]})]})]}),Oe("div",{className:"space-y-4",children:[J("h2",{className:"font-bold text-2xl",children:"Telemetry & guardrails"}),Oe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Oe("li",{children:["Telemetry events such as"," ",J("code",{className:"rounded bg-background/50 px-2 py-1",children:"openbanking.accounts.synced"})," ","and"," ",J("code",{className:"rounded bg-background/50 px-2 py-1",children:"openbanking.transactions.synced"})," ","are emitted automatically with tenant, slot, and config metadata."]}),Oe("li",{children:["Guard helpers ensure the"," ",J("code",{className:"rounded bg-background/50 px-2 py-1",children:"primaryOpenBanking"})," ","slot is bound and healthy before workflows execute."]}),Oe("li",{children:["PII fields (IBAN, counterparty names, descriptions) are redacted via"," ",J("code",{className:"rounded bg-background/50 px-2 py-1",children:"redactOpenBankingTelemetryPayload"})," ","before logging or sending telemetry."]})]})]}),Oe("div",{className:"space-y-4",children:[J("h2",{className:"font-bold text-2xl",children:"Best practices"}),Oe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[J("li",{children:"Use BYOK credentials per tenant to avoid cross-tenant exposure."}),J("li",{children:"Store only canonical entities (BankAccountRecord, BankTransactionRecord). Never persist raw Powens payloads or customer PII in logs."}),J("li",{children:"Run the transaction sync on a schedule appropriate for banking SLAs (e.g. every 15 minutes for cashflow dashboards)."}),J("li",{children:"Pair ledger updates with derived summaries to feed the knowledge layer instead of exposing raw transactions to agents."}),Oe("li",{children:["Monitor telemetry for"," ",J("code",{className:"rounded bg-background/50 px-2 py-1",children:"openbanking.*.sync_failed"})," ","events to detect credential issues early."]})]})]}),Oe("div",{className:"flex items-center gap-4 pt-4",children:[J(sl,{href:"/docs/integrations",className:"btn-ghost",children:"Back to Integrations"}),Oe(sl,{href:"/docs/integrations/stripe",className:"btn-primary",children:["Next: Stripe ",J(dg,{size:16})]})]})]})}import pl from"@contractspec/lib.ui-link";import{ChevronRight as pg}from"lucide-react";import{jsx as Yt,jsxs as Zo}from"react/jsx-runtime";function mg(){return Zo("div",{className:"space-y-8",children:[Zo("div",{className:"space-y-4",children:[Yt("h1",{className:"font-bold text-4xl",children:"Qdrant"}),Yt("p",{className:"text-muted-foreground",children:"Qdrant is a high-performance vector database for semantic search, recommendations, and RAG (Retrieval-Augmented Generation) applications."})]}),Zo("div",{className:"space-y-4",children:[Yt("h2",{className:"font-bold text-2xl",children:"Setup"}),Yt("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:Yt("pre",{children:`# .env
|
|
2152
2152
|
QDRANT_URL=https://...
|
|
2153
2153
|
QDRANT_API_KEY=...
|
|
2154
2154
|
QDRANT_COLLECTION=documents`})})]}),Zo("div",{className:"space-y-4",children:[Yt("h2",{className:"font-bold text-2xl",children:"Storing vectors"}),Yt("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:Yt("pre",{children:`capabilityId: qdrant-upsert
|
|
@@ -2219,7 +2219,7 @@ steps:
|
|
|
2219
2219
|
- role: "user"
|
|
2220
2220
|
content: |
|
|
2221
2221
|
Context: \${steps.search-documents.output.results}
|
|
2222
|
-
Question: \${input.query}`})})]}),Zo("div",{className:"flex items-center gap-4 pt-4",children:[Yt(
|
|
2222
|
+
Question: \${input.query}`})})]}),Zo("div",{className:"flex items-center gap-4 pt-4",children:[Yt(pl,{href:"/docs/integrations/elevenlabs",className:"btn-ghost",children:"Previous: ElevenLabs"}),Zo(pl,{href:"/docs/integrations/s3",className:"btn-primary",children:["Next: S3 Storage ",Yt(pg,{size:16})]})]})]})}import ml from"@contractspec/lib.ui-link";import{ChevronRight as ug}from"lucide-react";import{jsx as Ta,jsxs as $o}from"react/jsx-runtime";function gg(){return $o("div",{className:"space-y-8",children:[$o("div",{className:"space-y-4",children:[Ta("h1",{className:"font-bold text-4xl",children:"Resend"}),Ta("p",{className:"text-muted-foreground",children:"Resend is a modern email API built for developers. It provides a simple, reliable way to send transactional emails with React Email templates."})]}),$o("div",{className:"space-y-4",children:[Ta("h2",{className:"font-bold text-2xl",children:"Setup"}),Ta("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:Ta("pre",{children:`# .env
|
|
2223
2223
|
RESEND_API_KEY=re_...
|
|
2224
2224
|
RESEND_FROM_EMAIL=onboarding@resend.dev`})})]}),$o("div",{className:"space-y-4",children:[Ta("h2",{className:"font-bold text-2xl",children:"Sending emails"}),Ta("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:Ta("pre",{children:`capabilityId: resend-send-email
|
|
2225
2225
|
provider:
|
|
@@ -2242,7 +2242,7 @@ inputs:
|
|
|
2242
2242
|
|
|
2243
2243
|
outputs:
|
|
2244
2244
|
id:
|
|
2245
|
-
type: string`})})]}),$o("div",{className:"space-y-4",children:[Ta("h2",{className:"font-bold text-2xl",children:"Best practices"}),$o("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Ta("li",{children:"Use React Email for type-safe templates"}),Ta("li",{children:"Verify your domain for better deliverability"}),Ta("li",{children:"Monitor email analytics in the Resend dashboard"})]})]}),$o("div",{className:"flex items-center gap-4 pt-4",children:[Ta(
|
|
2245
|
+
type: string`})})]}),$o("div",{className:"space-y-4",children:[Ta("h2",{className:"font-bold text-2xl",children:"Best practices"}),$o("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Ta("li",{children:"Use React Email for type-safe templates"}),Ta("li",{children:"Verify your domain for better deliverability"}),Ta("li",{children:"Monitor email analytics in the Resend dashboard"})]})]}),$o("div",{className:"flex items-center gap-4 pt-4",children:[Ta(ml,{href:"/docs/integrations/postmark",className:"btn-ghost",children:"Previous: Postmark"}),$o(ml,{href:"/docs/integrations/gmail",className:"btn-primary",children:["Next: Gmail API ",Ta(ug,{size:16})]})]})]})}import ul from"@contractspec/lib.ui-link";import{ChevronRight as fg}from"lucide-react";import{jsx as vt,jsxs as Lo}from"react/jsx-runtime";function hg(){return Lo("div",{className:"space-y-8",children:[Lo("div",{className:"space-y-4",children:[vt("h1",{className:"font-bold text-4xl",children:"S3-Compatible Storage"}),vt("p",{className:"text-muted-foreground",children:"Store files, images, and documents using any S3-compatible object storage service including AWS S3, Scaleway Object Storage, MinIO, DigitalOcean Spaces, and more."})]}),Lo("div",{className:"space-y-4",children:[vt("h2",{className:"font-bold text-2xl",children:"Setup"}),vt("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:vt("pre",{children:`# .env
|
|
2246
2246
|
S3_ENDPOINT=https://s3.fr-par.scw.cloud
|
|
2247
2247
|
S3_ACCESS_KEY_ID=...
|
|
2248
2248
|
S3_SECRET_ACCESS_KEY=...
|
|
@@ -2284,7 +2284,7 @@ inputs:
|
|
|
2284
2284
|
|
|
2285
2285
|
outputs:
|
|
2286
2286
|
url:
|
|
2287
|
-
type: string`})})]}),Lo("div",{className:"space-y-4",children:[vt("h2",{className:"font-bold text-2xl",children:"Best practices"}),Lo("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[vt("li",{children:"Use presigned URLs for secure, temporary access"}),vt("li",{children:"Set appropriate CORS policies for browser uploads"}),vt("li",{children:"Enable versioning for important files"}),vt("li",{children:"Use lifecycle policies to archive old files"}),vt("li",{children:"Organize files with a clear key structure"})]})]}),Lo("div",{className:"flex items-center gap-4 pt-4",children:[vt(
|
|
2287
|
+
type: string`})})]}),Lo("div",{className:"space-y-4",children:[vt("h2",{className:"font-bold text-2xl",children:"Best practices"}),Lo("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[vt("li",{children:"Use presigned URLs for secure, temporary access"}),vt("li",{children:"Set appropriate CORS policies for browser uploads"}),vt("li",{children:"Enable versioning for important files"}),vt("li",{children:"Use lifecycle policies to archive old files"}),vt("li",{children:"Organize files with a clear key structure"})]})]}),Lo("div",{className:"flex items-center gap-4 pt-4",children:[vt(ul,{href:"/docs/integrations/qdrant",className:"btn-ghost",children:"Previous: Qdrant"}),Lo(ul,{href:"/docs/integrations/twilio",className:"btn-primary",children:["Next: Twilio ",vt(fg,{size:16})]})]})]})}import gl from"@contractspec/lib.ui-link";import{ChevronRight as yg}from"lucide-react";import{jsx as Nt,jsxs as Ka}from"react/jsx-runtime";function bg(){return Ka("div",{className:"space-y-8",children:[Ka("div",{className:"space-y-4",children:[Nt("h1",{className:"font-bold text-4xl",children:"Slack Messaging"}),Nt("p",{className:"text-muted-foreground",children:"ContractSpec supports signed Slack event ingestion and outbox-backed outbound replies through the channel runtime."})]}),Ka("div",{className:"space-y-4",children:[Nt("h2",{className:"font-bold text-2xl",children:"Required secrets and config"}),Nt("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:Nt("pre",{children:`// secret payload
|
|
2288
2288
|
{
|
|
2289
2289
|
"botToken": "xoxb-...",
|
|
2290
2290
|
"signingSecret": "..."
|
|
@@ -2302,7 +2302,7 @@ CHANNEL_DISPATCH_TOKEN=...
|
|
|
2302
2302
|
|
|
2303
2303
|
# Optional scheduler
|
|
2304
2304
|
CHANNEL_DISPATCH_INTERVAL_MS=120000
|
|
2305
|
-
CHANNEL_DISPATCH_RUN_ON_START=1`})})]}),Ka("div",{className:"space-y-4",children:[Nt("h2",{className:"font-bold text-2xl",children:"Best practices"}),Ka("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Nt("li",{children:"Keep bot tokens and signing secrets in a managed secret provider."}),Nt("li",{children:"Use workspace mapping to prevent cross-tenant event leakage."}),Nt("li",{children:"Keep dispatch asynchronous so webhook handlers stay fast and reliable."}),Nt("li",{children:"Monitor telemetry for ingest, decision, outbox, and dispatch stages."})]})]}),Ka("div",{className:"flex items-center gap-4 pt-4",children:[Nt(
|
|
2305
|
+
CHANNEL_DISPATCH_RUN_ON_START=1`})})]}),Ka("div",{className:"space-y-4",children:[Nt("h2",{className:"font-bold text-2xl",children:"Best practices"}),Ka("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Nt("li",{children:"Keep bot tokens and signing secrets in a managed secret provider."}),Nt("li",{children:"Use workspace mapping to prevent cross-tenant event leakage."}),Nt("li",{children:"Keep dispatch asynchronous so webhook handlers stay fast and reliable."}),Nt("li",{children:"Monitor telemetry for ingest, decision, outbox, and dispatch stages."})]})]}),Ka("div",{className:"flex items-center gap-4 pt-4",children:[Nt(gl,{href:"/docs/integrations/twilio",className:"btn-ghost",children:"Previous: Twilio SMS"}),Ka(gl,{href:"/docs/integrations/github",className:"btn-primary",children:["Next: GitHub Messaging ",Nt(yg,{size:16})]})]})]})}import fl from"@contractspec/lib.ui-link";import{ChevronRight as vg}from"lucide-react";import{jsx as R,jsxs as $e}from"react/jsx-runtime";function Ng(){return $e("div",{className:"space-y-8",children:[$e("div",{className:"space-y-4",children:[R("h1",{className:"font-bold text-4xl",children:"Integration Spec Model"}),R("p",{className:"text-muted-foreground",children:"Integrations in ContractSpec are defined through typed specifications that declare capabilities, configuration requirements, and connection details. This page covers IntegrationSpec and IntegrationConnection."})]}),$e("div",{className:"space-y-4",children:[R("h2",{className:"font-bold text-2xl",children:"IntegrationSpec"}),$e("p",{className:"text-muted-foreground",children:["The ",R("strong",{children:"IntegrationSpec"})," is a global definition of an integration provider. It declares what the integration provides and what it requires."]}),R("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:R("pre",{children:`type IntegrationSpec = {
|
|
2306
2306
|
id: string;
|
|
2307
2307
|
label: string;
|
|
2308
2308
|
description: string;
|
|
@@ -2512,7 +2512,7 @@ CHANNEL_DISPATCH_RUN_ON_START=1`})})]}),Ka("div",{className:"space-y-4",children
|
|
|
2512
2512
|
"clientSecret": "...",
|
|
2513
2513
|
"tokenExpiresAt": "2026-02-01T00:00:00.000Z",
|
|
2514
2514
|
"mcpAccessToken": "..."
|
|
2515
|
-
}`})})]}),$e("div",{className:"space-y-4",children:[R("h2",{className:"font-bold text-2xl",children:"Health checks"}),R("p",{className:"text-muted-foreground",children:"IntegrationConnections are periodically health-checked to ensure they remain valid:"}),$e("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[$e("li",{children:[R("strong",{children:"API key validation"})," - Test that credentials are still valid"]}),$e("li",{children:[R("strong",{children:"Connectivity check"})," - Verify network access to the provider"]}),$e("li",{children:[R("strong",{children:"Permission verification"})," - Ensure required scopes are granted"]}),$e("li",{children:[R("strong",{children:"Webhook validation"})," - Test webhook endpoint reachability"]})]}),R("p",{className:"text-muted-foreground",children:'Failed health checks update the connection status to "error" and trigger alerts.'})]}),$e("div",{className:"space-y-4",children:[R("h2",{className:"font-bold text-2xl",children:"Secret management"}),R("p",{className:"text-muted-foreground",children:"Secrets (API keys, tokens) are never stored in plaintext:"}),$e("ol",{className:"list-inside list-decimal space-y-2 text-muted-foreground",children:[R("li",{children:"User provides secrets through secure UI or API"}),R("li",{children:"Secrets are encrypted using tenant-specific keys"}),R("li",{children:"Encrypted secrets are stored in secure vault (e.g., AWS Secrets Manager)"}),R("li",{children:"IntegrationConnection stores only a reference (secretRef)"}),R("li",{children:"At runtime, secrets are decrypted on-demand and never logged"})]})]}),$e("div",{className:"space-y-4",children:[R("h2",{className:"font-bold text-2xl",children:"Best practices"}),$e("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[R("li",{children:"Always maintain separate sandbox and production connections"}),R("li",{children:"Use descriptive connection IDs that include tenant and environment"}),R("li",{children:"Monitor health check status and set up alerts for failures"}),R("li",{children:"Rotate secrets regularly and update secretRef accordingly"}),R("li",{children:"Document the purpose and ownership of each connection"}),R("li",{children:"Test connections in sandbox before enabling in production"})]})]}),$e("div",{className:"flex items-center gap-4 pt-4",children:[R(
|
|
2515
|
+
}`})})]}),$e("div",{className:"space-y-4",children:[R("h2",{className:"font-bold text-2xl",children:"Health checks"}),R("p",{className:"text-muted-foreground",children:"IntegrationConnections are periodically health-checked to ensure they remain valid:"}),$e("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[$e("li",{children:[R("strong",{children:"API key validation"})," - Test that credentials are still valid"]}),$e("li",{children:[R("strong",{children:"Connectivity check"})," - Verify network access to the provider"]}),$e("li",{children:[R("strong",{children:"Permission verification"})," - Ensure required scopes are granted"]}),$e("li",{children:[R("strong",{children:"Webhook validation"})," - Test webhook endpoint reachability"]})]}),R("p",{className:"text-muted-foreground",children:'Failed health checks update the connection status to "error" and trigger alerts.'})]}),$e("div",{className:"space-y-4",children:[R("h2",{className:"font-bold text-2xl",children:"Secret management"}),R("p",{className:"text-muted-foreground",children:"Secrets (API keys, tokens) are never stored in plaintext:"}),$e("ol",{className:"list-inside list-decimal space-y-2 text-muted-foreground",children:[R("li",{children:"User provides secrets through secure UI or API"}),R("li",{children:"Secrets are encrypted using tenant-specific keys"}),R("li",{children:"Encrypted secrets are stored in secure vault (e.g., AWS Secrets Manager)"}),R("li",{children:"IntegrationConnection stores only a reference (secretRef)"}),R("li",{children:"At runtime, secrets are decrypted on-demand and never logged"})]})]}),$e("div",{className:"space-y-4",children:[R("h2",{className:"font-bold text-2xl",children:"Best practices"}),$e("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[R("li",{children:"Always maintain separate sandbox and production connections"}),R("li",{children:"Use descriptive connection IDs that include tenant and environment"}),R("li",{children:"Monitor health check status and set up alerts for failures"}),R("li",{children:"Rotate secrets regularly and update secretRef accordingly"}),R("li",{children:"Document the purpose and ownership of each connection"}),R("li",{children:"Test connections in sandbox before enabling in production"})]})]}),$e("div",{className:"flex items-center gap-4 pt-4",children:[R(fl,{href:"/docs/integrations",className:"btn-ghost",children:"Back to Integrations"}),$e(fl,{href:"/docs/architecture/integration-binding",className:"btn-primary",children:["Integration Binding ",R(vg,{size:16})]})]})]})}import hl from"@contractspec/lib.ui-link";import{ChevronRight as wg}from"lucide-react";import{jsx as N,jsxs as Xe}from"react/jsx-runtime";function kg(){return Xe("div",{className:"space-y-8",children:[Xe("div",{className:"space-y-4",children:[N("h1",{className:"font-bold text-4xl",children:"Stripe"}),N("p",{className:"text-muted-foreground",children:"The Stripe integration enables payment processing, subscription management, and invoicing in your ContractSpec applications. All Stripe operations are type-safe, policy-enforced, and automatically logged."})]}),Xe("div",{className:"space-y-4",children:[N("h2",{className:"font-bold text-2xl",children:"Setup"}),N("p",{className:"text-muted-foreground",children:"Add your Stripe credentials to your environment variables:"}),N("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:N("pre",{children:`# .env
|
|
2516
2516
|
STRIPE_SECRET_KEY=sk_test_...
|
|
2517
2517
|
STRIPE_PUBLISHABLE_KEY=pk_test_...
|
|
2518
2518
|
STRIPE_WEBHOOK_SECRET=whsec_...`})}),Xe("p",{className:"text-muted-foreground text-sm",children:["Get your API keys from the"," ",N("a",{href:"https://dashboard.stripe.com/apikeys",target:"_blank",rel:"noopener noreferrer",className:"text-violet-400 hover:text-violet-300",children:"Stripe Dashboard"}),"."]})]}),Xe("div",{className:"space-y-4",children:[N("h2",{className:"font-bold text-2xl",children:"Available capabilities"}),Xe("div",{className:"space-y-3",children:[N("h3",{className:"font-semibold text-lg",children:"Payment Intents"}),N("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:N("pre",{children:`capabilityId: stripe-create-payment-intent
|
|
@@ -2615,7 +2615,7 @@ steps:
|
|
|
2615
2615
|
to: "admin@example.com"
|
|
2616
2616
|
template: "payment-error"
|
|
2617
2617
|
data:
|
|
2618
|
-
error: \${error.message}`})})]}),Xe("div",{className:"space-y-4",children:[N("h2",{className:"font-bold text-2xl",children:"Testing"}),N("p",{className:"text-muted-foreground",children:"Use Stripe's test cards for development:"}),N("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:Xe("table",{className:"w-full text-left text-sm",children:[N("thead",{className:"bg-card/50",children:Xe("tr",{className:"border-border/50 border-b",children:[N("th",{className:"px-4 py-3 font-semibold",children:"Card Number"}),N("th",{className:"px-4 py-3 font-semibold",children:"Scenario"})]})}),Xe("tbody",{className:"divide-y divide-border/50",children:[Xe("tr",{children:[N("td",{className:"px-4 py-3 font-mono",children:"4242 4242 4242 4242"}),N("td",{className:"px-4 py-3",children:"Successful payment"})]}),Xe("tr",{children:[N("td",{className:"px-4 py-3 font-mono",children:"4000 0000 0000 9995"}),N("td",{className:"px-4 py-3",children:"Insufficient funds"})]}),Xe("tr",{children:[N("td",{className:"px-4 py-3 font-mono",children:"4000 0000 0000 0002"}),N("td",{className:"px-4 py-3",children:"Card declined"})]})]})]})})]}),Xe("div",{className:"space-y-4",children:[N("h2",{className:"font-bold text-2xl",children:"Best practices"}),Xe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[N("li",{children:"Always use test mode during development"}),N("li",{children:"Verify webhook signatures to prevent fraud"}),N("li",{children:"Handle idempotency for payment operations"}),N("li",{children:"Store customer IDs for recurring payments"}),N("li",{children:"Use metadata to link Stripe objects to your application records"}),N("li",{children:"Monitor failed payments and retry logic"})]})]}),Xe("div",{className:"flex items-center gap-4 pt-4",children:[N(
|
|
2618
|
+
error: \${error.message}`})})]}),Xe("div",{className:"space-y-4",children:[N("h2",{className:"font-bold text-2xl",children:"Testing"}),N("p",{className:"text-muted-foreground",children:"Use Stripe's test cards for development:"}),N("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:Xe("table",{className:"w-full text-left text-sm",children:[N("thead",{className:"bg-card/50",children:Xe("tr",{className:"border-border/50 border-b",children:[N("th",{className:"px-4 py-3 font-semibold",children:"Card Number"}),N("th",{className:"px-4 py-3 font-semibold",children:"Scenario"})]})}),Xe("tbody",{className:"divide-y divide-border/50",children:[Xe("tr",{children:[N("td",{className:"px-4 py-3 font-mono",children:"4242 4242 4242 4242"}),N("td",{className:"px-4 py-3",children:"Successful payment"})]}),Xe("tr",{children:[N("td",{className:"px-4 py-3 font-mono",children:"4000 0000 0000 9995"}),N("td",{className:"px-4 py-3",children:"Insufficient funds"})]}),Xe("tr",{children:[N("td",{className:"px-4 py-3 font-mono",children:"4000 0000 0000 0002"}),N("td",{className:"px-4 py-3",children:"Card declined"})]})]})]})})]}),Xe("div",{className:"space-y-4",children:[N("h2",{className:"font-bold text-2xl",children:"Best practices"}),Xe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[N("li",{children:"Always use test mode during development"}),N("li",{children:"Verify webhook signatures to prevent fraud"}),N("li",{children:"Handle idempotency for payment operations"}),N("li",{children:"Store customer IDs for recurring payments"}),N("li",{children:"Use metadata to link Stripe objects to your application records"}),N("li",{children:"Monitor failed payments and retry logic"})]})]}),Xe("div",{className:"flex items-center gap-4 pt-4",children:[N(hl,{href:"/docs/integrations",className:"btn-ghost",children:"Back to Integrations"}),Xe(hl,{href:"/docs/integrations/postmark",className:"btn-primary",children:["Next: Postmark ",N(wg,{size:16})]})]})]})}import yl from"@contractspec/lib.ui-link";import{jsx as lt,jsxs as Do}from"react/jsx-runtime";function Sg(){return Do("div",{className:"space-y-8",children:[Do("div",{className:"space-y-4",children:[lt("h1",{className:"font-bold text-4xl",children:"Twilio"}),lt("p",{className:"text-muted-foreground",children:"Send SMS notifications, alerts, and two-factor authentication codes using Twilio's reliable messaging platform."})]}),Do("div",{className:"space-y-4",children:[lt("h2",{className:"font-bold text-2xl",children:"Setup"}),lt("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:lt("pre",{children:`# .env
|
|
2619
2619
|
TWILIO_ACCOUNT_SID=...
|
|
2620
2620
|
TWILIO_AUTH_TOKEN=...
|
|
2621
2621
|
TWILIO_PHONE_NUMBER=+1234567890`})})]}),Do("div",{className:"space-y-4",children:[lt("h2",{className:"font-bold text-2xl",children:"Sending SMS"}),lt("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:lt("pre",{children:`capabilityId: twilio-send-sms
|
|
@@ -2635,7 +2635,7 @@ outputs:
|
|
|
2635
2635
|
messageSid:
|
|
2636
2636
|
type: string
|
|
2637
2637
|
status:
|
|
2638
|
-
type: string`})})]}),Do("div",{className:"space-y-4",children:[lt("h2",{className:"font-bold text-2xl",children:"Use cases"}),Do("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[lt("li",{children:"Order confirmations and shipping updates"}),lt("li",{children:"Two-factor authentication codes"}),lt("li",{children:"Appointment reminders"}),lt("li",{children:"Alert notifications"})]})]}),Do("div",{className:"space-y-4",children:[lt("h2",{className:"font-bold text-2xl",children:"Best practices"}),Do("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[lt("li",{children:"Always use E.164 format for phone numbers (+1234567890)"}),lt("li",{children:"Keep messages under 160 characters to avoid splitting"}),lt("li",{children:"Implement rate limiting to prevent spam"}),lt("li",{children:"Handle delivery failures gracefully"}),lt("li",{children:"Respect opt-out requests"})]})]}),Do("div",{className:"flex items-center gap-4 pt-4",children:[lt(
|
|
2638
|
+
type: string`})})]}),Do("div",{className:"space-y-4",children:[lt("h2",{className:"font-bold text-2xl",children:"Use cases"}),Do("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[lt("li",{children:"Order confirmations and shipping updates"}),lt("li",{children:"Two-factor authentication codes"}),lt("li",{children:"Appointment reminders"}),lt("li",{children:"Alert notifications"})]})]}),Do("div",{className:"space-y-4",children:[lt("h2",{className:"font-bold text-2xl",children:"Best practices"}),Do("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[lt("li",{children:"Always use E.164 format for phone numbers (+1234567890)"}),lt("li",{children:"Keep messages under 160 characters to avoid splitting"}),lt("li",{children:"Implement rate limiting to prevent spam"}),lt("li",{children:"Handle delivery failures gracefully"}),lt("li",{children:"Respect opt-out requests"})]})]}),Do("div",{className:"flex items-center gap-4 pt-4",children:[lt(yl,{href:"/docs/integrations/s3",className:"btn-ghost",children:"Previous: S3 Storage"}),lt(yl,{href:"/docs/integrations/slack",className:"btn-primary",children:"Next: Slack Messaging"})]})]})}import bl from"@contractspec/lib.ui-link";import{ChevronRight as Cg}from"lucide-react";import{jsx as Pt,jsxs as Ma}from"react/jsx-runtime";function Ig(){return Ma("div",{className:"space-y-8",children:[Ma("div",{className:"space-y-4",children:[Pt("h1",{className:"font-bold text-4xl",children:"WhatsApp Meta"}),Pt("p",{className:"text-muted-foreground",children:"Meta WhatsApp is the primary WhatsApp channel for ContractSpec's messaging runtime, with signed webhook verification and reliable outbound delivery."})]}),Ma("div",{className:"space-y-4",children:[Pt("h2",{className:"font-bold text-2xl",children:"Required secrets and config"}),Pt("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:Pt("pre",{children:`// secret payload
|
|
2639
2639
|
{
|
|
2640
2640
|
"accessToken": "...",
|
|
2641
2641
|
"appSecret": "...",
|
|
@@ -2646,7 +2646,7 @@ outputs:
|
|
|
2646
2646
|
{
|
|
2647
2647
|
"phoneNumberId": "120000000001",
|
|
2648
2648
|
"apiVersion": "v22.0"
|
|
2649
|
-
}`})})]}),Ma("div",{className:"space-y-4",children:[Pt("h2",{className:"font-bold text-2xl",children:"Webhook endpoints"}),Ma("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Ma("li",{children:["Verification challenge:"," ",Pt("code",{className:"rounded bg-background/50 px-2 py-1",children:"GET /webhooks/whatsapp/meta"})]}),Ma("li",{children:["Inbound messages:"," ",Pt("code",{className:"rounded bg-background/50 px-2 py-1",children:"POST /webhooks/whatsapp/meta"})]}),Ma("li",{children:["Signatures are validated with"," ",Pt("code",{className:"rounded bg-background/50 px-2 py-1",children:"x-hub-signature-256"}),"."]})]})]}),Ma("div",{className:"space-y-4",children:[Pt("h2",{className:"font-bold text-2xl",children:"Workspace mapping"}),Pt("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:Pt("pre",{children:'CHANNEL_WORKSPACE_MAP_WHATSAPP_META={"120000000001":"workspace-acme"}'})})]}),Ma("div",{className:"space-y-4",children:[Pt("h2",{className:"font-bold text-2xl",children:"Best practices"}),Ma("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Pt("li",{children:"Keep verify and app secrets separate from access tokens."}),Pt("li",{children:"Map each phone number ID to a workspace for strict tenant routing."}),Pt("li",{children:"Use Twilio WhatsApp only as fallback when you need active-passive routing."})]})]}),Ma("div",{className:"flex items-center gap-4 pt-4",children:[Pt(
|
|
2649
|
+
}`})})]}),Ma("div",{className:"space-y-4",children:[Pt("h2",{className:"font-bold text-2xl",children:"Webhook endpoints"}),Ma("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Ma("li",{children:["Verification challenge:"," ",Pt("code",{className:"rounded bg-background/50 px-2 py-1",children:"GET /webhooks/whatsapp/meta"})]}),Ma("li",{children:["Inbound messages:"," ",Pt("code",{className:"rounded bg-background/50 px-2 py-1",children:"POST /webhooks/whatsapp/meta"})]}),Ma("li",{children:["Signatures are validated with"," ",Pt("code",{className:"rounded bg-background/50 px-2 py-1",children:"x-hub-signature-256"}),"."]})]})]}),Ma("div",{className:"space-y-4",children:[Pt("h2",{className:"font-bold text-2xl",children:"Workspace mapping"}),Pt("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:Pt("pre",{children:'CHANNEL_WORKSPACE_MAP_WHATSAPP_META={"120000000001":"workspace-acme"}'})})]}),Ma("div",{className:"space-y-4",children:[Pt("h2",{className:"font-bold text-2xl",children:"Best practices"}),Ma("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Pt("li",{children:"Keep verify and app secrets separate from access tokens."}),Pt("li",{children:"Map each phone number ID to a workspace for strict tenant routing."}),Pt("li",{children:"Use Twilio WhatsApp only as fallback when you need active-passive routing."})]})]}),Ma("div",{className:"flex items-center gap-4 pt-4",children:[Pt(bl,{href:"/docs/integrations/github",className:"btn-ghost",children:"Previous: GitHub Messaging"}),Ma(bl,{href:"/docs/integrations/whatsapp-twilio",className:"btn-primary",children:["Next: WhatsApp Twilio ",Pt(Cg,{size:16})]})]})]})}import vl from"@contractspec/lib.ui-link";import{ChevronRight as Pg}from"lucide-react";import{jsx as Tt,jsxs as Aa}from"react/jsx-runtime";function Tg(){return Aa("div",{className:"space-y-8",children:[Aa("div",{className:"space-y-4",children:[Tt("h1",{className:"font-bold text-4xl",children:"WhatsApp Twilio"}),Tt("p",{className:"text-muted-foreground",children:"Twilio WhatsApp support provides a durable fallback channel with signature verification and outbox-backed outbound dispatch."})]}),Aa("div",{className:"space-y-4",children:[Tt("h2",{className:"font-bold text-2xl",children:"Required secrets and config"}),Tt("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:Tt("pre",{children:`// secret payload
|
|
2650
2650
|
{
|
|
2651
2651
|
"accountSid": "AC123",
|
|
2652
2652
|
"authToken": "..."
|
|
@@ -2655,7 +2655,7 @@ outputs:
|
|
|
2655
2655
|
// optional connection config
|
|
2656
2656
|
{
|
|
2657
2657
|
"fromNumber": "whatsapp:+15550002"
|
|
2658
|
-
}`})})]}),Aa("div",{className:"space-y-4",children:[Tt("h2",{className:"font-bold text-2xl",children:"Webhook ingress"}),Aa("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Aa("li",{children:["Inbound Twilio form payloads are accepted on"," ",Tt("code",{className:"rounded bg-background/50 px-2 py-1",children:"/webhooks/whatsapp/twilio"}),"."]}),Aa("li",{children:["Signatures are validated with"," ",Tt("code",{className:"rounded bg-background/50 px-2 py-1",children:"x-twilio-signature"})," ","and the configured auth token."]}),Aa("li",{children:["For deterministic verification, set the exact public webhook URL in"," ",Tt("code",{className:"rounded bg-background/50 px-2 py-1",children:"WHATSAPP_TWILIO_WEBHOOK_URL"}),"."]})]})]}),Aa("div",{className:"space-y-4",children:[Tt("h2",{className:"font-bold text-2xl",children:"Workspace mapping"}),Tt("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:Tt("pre",{children:'CHANNEL_WORKSPACE_MAP_WHATSAPP_TWILIO={"AC123":"workspace-acme"}'})})]}),Aa("div",{className:"space-y-4",children:[Tt("h2",{className:"font-bold text-2xl",children:"Best practices"}),Aa("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Tt("li",{children:"Use Twilio as fallback when Meta WhatsApp is your primary route."}),Tt("li",{children:"Keep account SID mapping explicit to avoid tenant misrouting."}),Aa("li",{children:["Protect internal dispatch endpoints with",Tt("code",{className:"ml-1 rounded bg-background/50 px-2 py-1",children:"CHANNEL_DISPATCH_TOKEN"}),"."]})]})]}),Aa("div",{className:"flex items-center gap-4 pt-4",children:[Tt(
|
|
2658
|
+
}`})})]}),Aa("div",{className:"space-y-4",children:[Tt("h2",{className:"font-bold text-2xl",children:"Webhook ingress"}),Aa("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Aa("li",{children:["Inbound Twilio form payloads are accepted on"," ",Tt("code",{className:"rounded bg-background/50 px-2 py-1",children:"/webhooks/whatsapp/twilio"}),"."]}),Aa("li",{children:["Signatures are validated with"," ",Tt("code",{className:"rounded bg-background/50 px-2 py-1",children:"x-twilio-signature"})," ","and the configured auth token."]}),Aa("li",{children:["For deterministic verification, set the exact public webhook URL in"," ",Tt("code",{className:"rounded bg-background/50 px-2 py-1",children:"WHATSAPP_TWILIO_WEBHOOK_URL"}),"."]})]})]}),Aa("div",{className:"space-y-4",children:[Tt("h2",{className:"font-bold text-2xl",children:"Workspace mapping"}),Tt("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:Tt("pre",{children:'CHANNEL_WORKSPACE_MAP_WHATSAPP_TWILIO={"AC123":"workspace-acme"}'})})]}),Aa("div",{className:"space-y-4",children:[Tt("h2",{className:"font-bold text-2xl",children:"Best practices"}),Aa("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Tt("li",{children:"Use Twilio as fallback when Meta WhatsApp is your primary route."}),Tt("li",{children:"Keep account SID mapping explicit to avoid tenant misrouting."}),Aa("li",{children:["Protect internal dispatch endpoints with",Tt("code",{className:"ml-1 rounded bg-background/50 px-2 py-1",children:"CHANNEL_DISPATCH_TOKEN"}),"."]})]})]}),Aa("div",{className:"flex items-center gap-4 pt-4",children:[Tt(vl,{href:"/docs/integrations/whatsapp-meta",className:"btn-ghost",children:"Previous: WhatsApp Meta"}),Aa(vl,{href:"/docs/integrations/health-routing",className:"btn-primary",children:["Next: Health Routing ",Tt(Pg,{size:16})]})]})]})}var KI={title:"Contract-first API",summary:"Design APIs by writing contracts first, then generate consistent implementations across frameworks.",problems:["API drift between frontend and backend","Inconsistent error handling across endpoints","Documentation becomes outdated quickly","Manual OpenAPI maintenance is error-prone"],solutions:["Single source of truth for API contracts","Generate OpenAPI and SDKs from contracts","Type-safe request/response validation","Always-in-sync documentation"],audience:{role:"API developers",industry:"Software development",maturity:"scaleup"},callToAction:"Start with a simple operation contract",references:[{label:"Next.js One Endpoint Guide",url:"/docs/guides/nextjs-one-endpoint"},{label:"API Reference",url:"/docs/api"}]},QI={title:"Spec-driven development",summary:"Build features by writing specifications first, then generate type-safe implementations.",problems:["Feature requirements are ambiguous","Frontend and backend implementations diverge","Testing lacks clear contract definitions","Code reviews focus on style instead of behavior"],solutions:["Executable specifications as single source of truth","Generate type-safe clients from specs","Automated contract testing","Clear behavior contracts for teams"],audience:{role:"Development teams",industry:"Software engineering",maturity:"enterprise"},callToAction:"Define your first feature spec",references:[{label:"Spec Validation + Typing Guide",url:"/docs/guides/spec-validation-and-typing"},{label:"Core Contracts",url:"/docs/core-contracts"}]},YI={title:"Deterministic codegen",summary:"Regenerate code from contracts without breaking existing functionality or losing customizations.",problems:["Generated code conflicts with manual changes","Regeneration loses custom business logic","Teams avoid regeneration after customization","Code migration between versions is risky"],solutions:["Clear separation of generated vs hand-written code","Incremental regeneration with conflict detection","Protected zones for custom logic","Automatic migration paths"],audience:{role:"Platform engineers",industry:"Developer tools",maturity:"scaleup"},callToAction:"Try deterministic regeneration",references:[{label:"Generate Docs + Clients Guide",url:"/docs/guides/generate-docs-clients-schemas"},{label:"CLI Reference",url:"/docs/getting-started/cli"}]},JI={title:"Schema validation TypeScript",summary:"Generate TypeScript types from contracts and validate data at runtime with zero overhead.",problems:["Runtime type validation is boilerplate-heavy","Type definitions drift from schemas","Validation logic scattered across codebase","Poor error messages for invalid data"],solutions:["Auto-generated TypeScript from contracts","Zod schemas for runtime validation","Type-safe validation with clear errors","Single source of schema truth"],audience:{role:"TypeScript developers",industry:"Web development",maturity:"early"},callToAction:"Generate typed contracts now",references:[{label:"Type Safety Guide",url:"/docs/guides/spec-validation-and-typing"},{label:"Schema Reference",url:"/docs/schemas"}]},ZI={title:"OpenAPI alternative",summary:"A spec-first approach that goes beyond OpenAPI with executable contracts and code generation.",problems:["OpenAPI is documentation-only","No type safety from OpenAPI specs","Manual SDK generation is complex","Cannot validate implementations against OpenAPI"],solutions:["Executable contracts with validation","Generate multiple outputs from one spec","Type-safe by default","Built-in testing and validation"],audience:{role:"API architects",industry:"Enterprise software",maturity:"enterprise"},callToAction:"Compare with OpenAPI approach",references:[{label:"Generate OpenAPI from Contracts",url:"/docs/guides/generate-docs-clients-schemas"},{label:"Contract vs OpenAPI",url:"/docs/comparison/openapi"}]},$I={title:"Generate client from schema",summary:"Automatically generate type-safe API clients in any language from your contracts.",problems:["Writing API clients is repetitive","Manual clients have type mismatches","Keeping clients in sync with APIs","Language-specific client maintenance"],solutions:["Generate clients for multiple languages","Type-safe request/response handling","Automatic client updates from contracts","Consistent error handling across languages"],audience:{role:"Full-stack developers",industry:"Software development",maturity:"scaleup"},callToAction:"Generate your first API client",references:[{label:"Client Generation Guide",url:"/docs/guides/generate-docs-clients-schemas"},{label:"Supported Languages",url:"/docs/integrations"}]};import{contractFirstApiBrief as Qi}from"@contractspec/bundle.library/components/docs/intent/intent-pages.docblocks";import{SeoOptimizer as Ag}from"@contractspec/lib.content-gen/seo";import{CodeBlock as Nl}from"@contractspec/lib.design-system";import wl from"@contractspec/lib.ui-link";import{ChevronRight as Rg}from"lucide-react";import{jsx as Jt,jsxs as Eo}from"react/jsx-runtime";var oP=new Ag().optimize(Qi);function Lg(){return Eo("div",{className:"space-y-8",children:[Eo("div",{className:"space-y-3",children:[Jt("h1",{className:"font-bold text-4xl",children:Qi.title}),Jt("p",{className:"text-lg text-muted-foreground",children:Qi.summary})]}),Eo("div",{className:"card-subtle space-y-4 p-6",children:[Jt("h2",{className:"font-bold text-2xl",children:"Problems Solved"}),Jt("ul",{className:"space-y-2 text-muted-foreground text-sm",children:Qi.problems.map((e,t)=>Jt("li",{children:e},t))})]}),Eo("div",{className:"card-subtle space-y-4 p-6",children:[Jt("h2",{className:"font-bold text-2xl",children:"Solutions"}),Jt("ul",{className:"space-y-2 text-muted-foreground text-sm",children:Qi.solutions.map((e,t)=>Jt("li",{children:e},t))})]}),Eo("div",{className:"space-y-6",children:[Eo("div",{className:"space-y-3",children:[Jt("h2",{className:"font-bold text-2xl",children:"Quick Start"}),Jt("p",{className:"text-muted-foreground text-sm",children:"Define your first API contract and generate consistent implementations."}),Jt(Nl,{language:"typescript",filename:"src/contracts/user-create.operation.ts",code:`import { defineOperation } from '@contractspec/lib.contracts-spec/operations';
|
|
2659
2659
|
import { SchemaModel, ScalarTypeEnum } from '@contractspec/lib.schema';
|
|
2660
2660
|
|
|
2661
2661
|
export const CreateUserOperation = defineOperation({
|
|
@@ -2689,7 +2689,7 @@ export const CreateUserOperation = defineOperation({
|
|
|
2689
2689
|
tags: ['users', 'auth'],
|
|
2690
2690
|
description: 'Create a new user account with email and password',
|
|
2691
2691
|
},
|
|
2692
|
-
});`})]}),Eo("div",{className:"space-y-3",children:[Jt("h2",{className:"font-bold text-2xl",children:"Generate OpenAPI"}),Jt("p",{className:"text-muted-foreground text-sm",children:"Export OpenAPI documentation directly from your contracts."}),Jt(
|
|
2692
|
+
});`})]}),Eo("div",{className:"space-y-3",children:[Jt("h2",{className:"font-bold text-2xl",children:"Generate OpenAPI"}),Jt("p",{className:"text-muted-foreground text-sm",children:"Export OpenAPI documentation directly from your contracts."}),Jt(Nl,{language:"bash",filename:"export-openapi",code:"contractspec openapi export \\\n --registry ./src/contracts/registry.ts \\\n --out ./openapi.json"})]})]}),Eo("div",{className:"flex items-center gap-4 pt-4",children:[Eo(wl,{href:"/docs/guides/nextjs-one-endpoint",className:"btn-primary",children:["Next.js Guide ",Jt(Rg,{size:16})]}),Jt(wl,{href:"/docs/intent/spec-driven-development",className:"btn-ghost",children:"Spec-driven Development"})]})]})}import{deterministicCodegenBrief as Yi}from"@contractspec/bundle.library/components/docs/intent/intent-pages.docblocks";import{SeoOptimizer as Dg}from"@contractspec/lib.content-gen/seo";import{CodeBlock as dn}from"@contractspec/lib.design-system";import kl from"@contractspec/lib.ui-link";import{ChevronRight as Eg}from"lucide-react";import{jsx as wt,jsxs as yo}from"react/jsx-runtime";var lP=new Dg().optimize(Yi);function Og(){return yo("div",{className:"space-y-8",children:[yo("div",{className:"space-y-3",children:[wt("h1",{className:"font-bold text-4xl",children:Yi.title}),wt("p",{className:"text-lg text-muted-foreground",children:Yi.summary})]}),yo("div",{className:"card-subtle space-y-4 p-6",children:[wt("h2",{className:"font-bold text-2xl",children:"Regeneration Challenges"}),wt("ul",{className:"space-y-2 text-muted-foreground text-sm",children:Yi.problems.map((e,t)=>wt("li",{children:e},t))})]}),yo("div",{className:"card-subtle space-y-4 p-6",children:[wt("h2",{className:"font-bold text-2xl",children:"Deterministic Solutions"}),wt("ul",{className:"space-y-2 text-muted-foreground text-sm",children:Yi.solutions.map((e,t)=>wt("li",{children:e},t))})]}),yo("div",{className:"space-y-6",children:[yo("div",{className:"space-y-3",children:[wt("h2",{className:"font-bold text-2xl",children:"Protected Zones"}),wt("p",{className:"text-muted-foreground text-sm",children:"Separate generated code from hand-written business logic with clear boundaries."}),wt(dn,{language:"typescript",filename:"src/handlers/user-handlers.ts",code:`// Hand-written business logic (protected from regeneration)
|
|
2693
2693
|
export class UserService {
|
|
2694
2694
|
async createUser(input: CreateUserInput): Promise<CreateUserOutput> {
|
|
2695
2695
|
// Custom validation and business rules
|
|
@@ -2726,7 +2726,7 @@ export const createUserHandler = wrapOperationHandler(
|
|
|
2726
2726
|
operationName: 'createUser',
|
|
2727
2727
|
errorMapper: mapToStandardErrors,
|
|
2728
2728
|
}
|
|
2729
|
-
);`})]}),yo("div",{className:"space-y-3",children:[wt("h2",{className:"font-bold text-2xl",children:"Incremental Regeneration"}),wt("p",{className:"text-muted-foreground text-sm",children:"Regenerate only what changed while preserving custom logic."}),wt(
|
|
2729
|
+
);`})]}),yo("div",{className:"space-y-3",children:[wt("h2",{className:"font-bold text-2xl",children:"Incremental Regeneration"}),wt("p",{className:"text-muted-foreground text-sm",children:"Regenerate only what changed while preserving custom logic."}),wt(dn,{language:"bash",filename:"incremental-regen",code:"contractspec generate \\\n --incremental \\\n --preserve-zones ./src/handlers/*.ts \\\n --input ./src/contracts/ \\\n --output ./generated/"})]}),yo("div",{className:"space-y-3",children:[wt("h2",{className:"font-bold text-2xl",children:"Conflict Detection"}),wt("p",{className:"text-muted-foreground text-sm",children:"Automatically detect and report conflicts during regeneration."}),wt(dn,{language:"bash",filename:"check-conflicts",code:"contractspec generate \\\n --check-conflicts \\\n --report-conflicts ./conflicts.json"})]})]}),yo("div",{className:"flex items-center gap-4 pt-4",children:[yo(kl,{href:"/docs/guides/generate-docs-clients-schemas",className:"btn-primary",children:["Client Generation ",wt(Eg,{size:16})]}),wt(kl,{href:"/docs/intent/schema-validation-typescript",className:"btn-ghost",children:"Type Safety"})]})]})}import{generateClientFromSchemaBrief as Ji}from"@contractspec/bundle.library/components/docs/intent/intent-pages.docblocks";import{SeoOptimizer as Bg}from"@contractspec/lib.content-gen/seo";import{CodeBlock as Li}from"@contractspec/lib.design-system";import Sl from"@contractspec/lib.ui-link";import{ChevronRight as Mg}from"lucide-react";import{jsx as Ie,jsxs as sa}from"react/jsx-runtime";var vP=new Bg().optimize(Ji);function Ug(){return sa("div",{className:"space-y-8",children:[sa("div",{className:"space-y-3",children:[Ie("h1",{className:"font-bold text-4xl",children:Ji.title}),Ie("p",{className:"text-lg text-muted-foreground",children:Ji.summary})]}),sa("div",{className:"card-subtle space-y-4 p-6",children:[Ie("h2",{className:"font-bold text-2xl",children:"Client Development Problems"}),Ie("ul",{className:"space-y-2 text-muted-foreground text-sm",children:Ji.problems.map((e,t)=>Ie("li",{children:e},t))})]}),sa("div",{className:"card-subtle space-y-4 p-6",children:[Ie("h2",{className:"font-bold text-2xl",children:"Automated Solutions"}),Ie("ul",{className:"space-y-2 text-muted-foreground text-sm",children:Ji.solutions.map((e,t)=>Ie("li",{children:e},t))})]}),sa("div",{className:"space-y-6",children:[sa("div",{className:"space-y-3",children:[Ie("h2",{className:"font-bold text-2xl",children:"Contract Definition"}),Ie("p",{className:"text-muted-foreground text-sm",children:"Define your API contract once, generate clients for any language."}),Ie(Li,{language:"typescript",filename:"src/contracts/api.contract.ts",code:`import { defineContract } from '@contractspec/lib.contracts-spec';
|
|
2730
2730
|
import { SchemaModel, ScalarTypeEnum } from '@contractspec/lib.schema';
|
|
2731
2731
|
|
|
2732
2732
|
export const ApiContract = defineContract({
|
|
@@ -2923,7 +2923,7 @@ const user2 = client.getUser({ id: '123' }); // Uses cached result
|
|
|
2923
2923
|
// Request cancellation
|
|
2924
2924
|
const controller = new AbortController();
|
|
2925
2925
|
const promise = client.getUsers({ page: 1, signal: controller.signal });
|
|
2926
|
-
controller.abort(); // Cancels the request`})]})]}),sa("div",{className:"flex items-center gap-4 pt-4",children:[sa(
|
|
2926
|
+
controller.abort(); // Cancels the request`})]})]}),sa("div",{className:"flex items-center gap-4 pt-4",children:[sa(Sl,{href:"/docs/guides/generate-docs-clients-schemas",className:"btn-primary",children:["Client Generation Guide ",Ie(Mg,{size:16})]}),Ie(Sl,{href:"/docs/intent/contract-first-api",className:"btn-ghost",children:"Contract-first API"})]})]})}import{openapiAlternativeBrief as Zi}from"@contractspec/bundle.library/components/docs/intent/intent-pages.docblocks";import{SeoOptimizer as Wg}from"@contractspec/lib.content-gen/seo";import{CodeBlock as Cl}from"@contractspec/lib.design-system";import Il from"@contractspec/lib.ui-link";import{ChevronRight as _g}from"lucide-react";import{jsx as pe,jsxs as pa}from"react/jsx-runtime";var TP=new Wg().optimize(Zi);function zg(){return pa("div",{className:"space-y-8",children:[pa("div",{className:"space-y-3",children:[pe("h1",{className:"font-bold text-4xl",children:Zi.title}),pe("p",{className:"text-lg text-muted-foreground",children:Zi.summary})]}),pa("div",{className:"card-subtle space-y-4 p-6",children:[pe("h2",{className:"font-bold text-2xl",children:"OpenAPI Limitations"}),pe("ul",{className:"space-y-2 text-muted-foreground text-sm",children:Zi.problems.map((e,t)=>pe("li",{children:e},t))})]}),pa("div",{className:"card-subtle space-y-4 p-6",children:[pe("h2",{className:"font-bold text-2xl",children:"ContractSpec Advantages"}),pe("ul",{className:"space-y-2 text-muted-foreground text-sm",children:Zi.solutions.map((e,t)=>pe("li",{children:e},t))})]}),pa("div",{className:"space-y-6",children:[pa("div",{className:"space-y-3",children:[pe("h2",{className:"font-bold text-2xl",children:"Comparison: OpenAPI vs ContractSpec"}),pe("p",{className:"text-muted-foreground text-sm",children:"Key differences between OpenAPI documentation and ContractSpec executable contracts."}),pa("div",{className:"grid gap-6 md:grid-cols-2",children:[pa("div",{className:"card-subtle space-y-3 p-4",children:[pe("h3",{className:"font-semibold text-lg",children:"OpenAPI"}),pa("ul",{className:"space-y-1 text-muted-foreground text-sm",children:[pe("li",{children:"• Documentation specification only"}),pe("li",{children:"• No runtime validation"}),pe("li",{children:"• Manual code generation"}),pe("li",{children:"• Type safety requires tools"}),pe("li",{children:"• Separate schemas from documentation"})]})]}),pa("div",{className:"card-subtle space-y-3 p-4",children:[pe("h3",{className:"font-semibold text-lg",children:"ContractSpec"}),pa("ul",{className:"space-y-1 text-muted-foreground text-sm",children:[pe("li",{children:"• Executable contracts"}),pe("li",{children:"• Built-in runtime validation"}),pe("li",{children:"• Automatic code generation"}),pe("li",{children:"• Type-safe by default"}),pe("li",{children:"• Unified spec and implementation"})]})]})]})]}),pa("div",{className:"space-y-3",children:[pe("h2",{className:"font-bold text-2xl",children:"Export from Contracts"}),pe("p",{className:"text-muted-foreground text-sm",children:"Generate OpenAPI documentation from ContractSpec for existing tooling."}),pe(Cl,{language:"bash",filename:"export-openapi",code:`# From ContractSpec contracts
|
|
2927
2927
|
contractspec openapi export \\
|
|
2928
2928
|
--registry ./src/contracts/registry.ts \\
|
|
2929
2929
|
--format yaml \\
|
|
@@ -2931,7 +2931,7 @@ contractspec openapi export \\
|
|
|
2931
2931
|
|
|
2932
2932
|
# Compare: Manual OpenAPI vs Generated
|
|
2933
2933
|
# Manual: Write OpenAPI by hand, maintain separately
|
|
2934
|
-
# Generated: Single source of truth, always in sync`})]}),pa("div",{className:"space-y-3",children:[pe("h2",{className:"font-bold text-2xl",children:"Beyond Documentation"}),pe("p",{className:"text-muted-foreground text-sm",children:"ContractSpec provides more than just API documentation."}),pe(
|
|
2934
|
+
# Generated: Single source of truth, always in sync`})]}),pa("div",{className:"space-y-3",children:[pe("h2",{className:"font-bold text-2xl",children:"Beyond Documentation"}),pe("p",{className:"text-muted-foreground text-sm",children:"ContractSpec provides more than just API documentation."}),pe(Cl,{language:"typescript",filename:"multi-output-example.ts",code:`// One contract, multiple outputs
|
|
2935
2935
|
import { UserApiContract } from './contracts/user-api.contract';
|
|
2936
2936
|
|
|
2937
2937
|
// Generated outputs
|
|
@@ -2961,7 +2961,7 @@ export const outputs = {
|
|
|
2961
2961
|
|
|
2962
2962
|
// Type definitions
|
|
2963
2963
|
types: UserApiContract.toTypescript(),
|
|
2964
|
-
};`})]})]}),pa("div",{className:"flex items-center gap-4 pt-4",children:[pa(
|
|
2964
|
+
};`})]})]}),pa("div",{className:"flex items-center gap-4 pt-4",children:[pa(Il,{href:"/docs/guides/generate-docs-clients-schemas",className:"btn-primary",children:["Generate from Contracts ",pe(_g,{size:16})]}),pe(Il,{href:"/docs/intent/generate-client-from-schema",className:"btn-ghost",children:"Client Generation"})]})]})}import{schemaValidationTypescriptBrief as $i}from"@contractspec/bundle.library/components/docs/intent/intent-pages.docblocks";import{SeoOptimizer as Gg}from"@contractspec/lib.content-gen/seo";import{CodeBlock as sn}from"@contractspec/lib.design-system";import Pl from"@contractspec/lib.ui-link";import{ChevronRight as qg}from"lucide-react";import{jsx as kt,jsxs as bo}from"react/jsx-runtime";var MP=new Gg().optimize($i);function Hg(){return bo("div",{className:"space-y-8",children:[bo("div",{className:"space-y-3",children:[kt("h1",{className:"font-bold text-4xl",children:$i.title}),kt("p",{className:"text-lg text-muted-foreground",children:$i.summary})]}),bo("div",{className:"card-subtle space-y-4 p-6",children:[kt("h2",{className:"font-bold text-2xl",children:"Validation Pain Points"}),kt("ul",{className:"space-y-2 text-muted-foreground text-sm",children:$i.problems.map((e,t)=>kt("li",{children:e},t))})]}),bo("div",{className:"card-subtle space-y-4 p-6",children:[kt("h2",{className:"font-bold text-2xl",children:"Type-safe Solutions"}),kt("ul",{className:"space-y-2 text-muted-foreground text-sm",children:$i.solutions.map((e,t)=>kt("li",{children:e},t))})]}),bo("div",{className:"space-y-6",children:[bo("div",{className:"space-y-3",children:[kt("h2",{className:"font-bold text-2xl",children:"Contract Schema"}),kt("p",{className:"text-muted-foreground text-sm",children:"Define data models with automatic TypeScript generation."}),kt(sn,{language:"typescript",filename:"src/contracts/user.schema.ts",code:`import { SchemaModel, ScalarTypeEnum } from '@contractspec/lib.schema';
|
|
2965
2965
|
|
|
2966
2966
|
export const UserSchema = new SchemaModel({
|
|
2967
2967
|
type: 'object',
|
|
@@ -3003,7 +3003,7 @@ export const UserSchema = new SchemaModel({
|
|
|
3003
3003
|
name: 'User',
|
|
3004
3004
|
description: 'User account information',
|
|
3005
3005
|
},
|
|
3006
|
-
});`})]}),bo("div",{className:"space-y-3",children:[kt("h2",{className:"font-bold text-2xl",children:"Generated Types"}),kt("p",{className:"text-muted-foreground text-sm",children:"TypeScript types are automatically generated with proper validation."}),kt(
|
|
3006
|
+
});`})]}),bo("div",{className:"space-y-3",children:[kt("h2",{className:"font-bold text-2xl",children:"Generated Types"}),kt("p",{className:"text-muted-foreground text-sm",children:"TypeScript types are automatically generated with proper validation."}),kt(sn,{language:"typescript",filename:"generated/types/user.ts",code:`// Auto-generated from UserSchema
|
|
3007
3007
|
export interface User {
|
|
3008
3008
|
id: string;
|
|
3009
3009
|
email: string;
|
|
@@ -3028,7 +3028,7 @@ export function validateUser(data: unknown): User {
|
|
|
3028
3028
|
|
|
3029
3029
|
export function isUser(data: unknown): data is User {
|
|
3030
3030
|
return UserSchemaZod.safeParse(data).success;
|
|
3031
|
-
}`})]}),bo("div",{className:"space-y-3",children:[kt("h2",{className:"font-bold text-2xl",children:"Runtime Validation"}),kt("p",{className:"text-muted-foreground text-sm",children:"Use generated validation in your API handlers with zero boilerplate."}),kt(
|
|
3031
|
+
}`})]}),bo("div",{className:"space-y-3",children:[kt("h2",{className:"font-bold text-2xl",children:"Runtime Validation"}),kt("p",{className:"text-muted-foreground text-sm",children:"Use generated validation in your API handlers with zero boilerplate."}),kt(sn,{language:"typescript",filename:"src/handlers/user-handler.ts",code:`import { validateUser } from '../generated/types/user';
|
|
3032
3032
|
|
|
3033
3033
|
export async function createUserHandler(request: Request) {
|
|
3034
3034
|
try {
|
|
@@ -3056,7 +3056,7 @@ export async function createUserHandler(request: Request) {
|
|
|
3056
3056
|
|
|
3057
3057
|
throw error;
|
|
3058
3058
|
}
|
|
3059
|
-
}`})]})]}),bo("div",{className:"flex items-center gap-4 pt-4",children:[bo(
|
|
3059
|
+
}`})]})]}),bo("div",{className:"flex items-center gap-4 pt-4",children:[bo(Pl,{href:"/docs/guides/spec-validation-and-typing",className:"btn-primary",children:["Type Safety Guide ",kt(qg,{size:16})]}),kt(Pl,{href:"/docs/intent/generate-client-from-schema",className:"btn-ghost",children:"Client Generation"})]})]})}import{specDrivenDevelopmentBrief as Xi}from"@contractspec/bundle.library/components/docs/intent/intent-pages.docblocks";import{SeoOptimizer as Vg}from"@contractspec/lib.content-gen/seo";import{CodeBlock as Tl}from"@contractspec/lib.design-system";import Al from"@contractspec/lib.ui-link";import{ChevronRight as Fg}from"lucide-react";import{jsx as Zt,jsxs as Oo}from"react/jsx-runtime";var VP=new Vg().optimize(Xi);function Kg(){return Oo("div",{className:"space-y-8",children:[Oo("div",{className:"space-y-3",children:[Zt("h1",{className:"font-bold text-4xl",children:Xi.title}),Zt("p",{className:"text-lg text-muted-foreground",children:Xi.summary})]}),Oo("div",{className:"card-subtle space-y-4 p-6",children:[Zt("h2",{className:"font-bold text-2xl",children:"Why Spec-driven?"}),Zt("ul",{className:"space-y-2 text-muted-foreground text-sm",children:Xi.problems.map((e,t)=>Zt("li",{children:e},t))})]}),Oo("div",{className:"card-subtle space-y-4 p-6",children:[Zt("h2",{className:"font-bold text-2xl",children:"Benefits"}),Zt("ul",{className:"space-y-2 text-muted-foreground text-sm",children:Xi.solutions.map((e,t)=>Zt("li",{children:e},t))})]}),Oo("div",{className:"space-y-6",children:[Oo("div",{className:"space-y-3",children:[Zt("h2",{className:"font-bold text-2xl",children:"Feature Specification Example"}),Zt("p",{className:"text-muted-foreground text-sm",children:"Define a complete feature with operations, events, and data models."}),Zt(Tl,{language:"typescript",filename:"src/contracts/user-management.feature.ts",code:`import { defineFeature } from '@contractspec/lib.contracts-spec/features';
|
|
3060
3060
|
import { defineOperation } from '@contractspec/lib.contracts-spec/operations';
|
|
3061
3061
|
import { defineEvent } from '@contractspec/lib.contracts-spec/events';
|
|
3062
3062
|
import { SchemaModel, ScalarTypeEnum } from '@contractspec/lib.schema';
|
|
@@ -3128,7 +3128,7 @@ export const UserManagementFeature = defineFeature({
|
|
|
3128
3128
|
version: '1.0.0',
|
|
3129
3129
|
description: 'Complete user management with operations and events',
|
|
3130
3130
|
},
|
|
3131
|
-
});`})]}),Oo("div",{className:"space-y-3",children:[Zt("h2",{className:"font-bold text-2xl",children:"Generate Type-safe Implementations"}),Zt("p",{className:"text-muted-foreground text-sm",children:"Generate validation, types, and API handlers from your feature."}),Zt(
|
|
3131
|
+
});`})]}),Oo("div",{className:"space-y-3",children:[Zt("h2",{className:"font-bold text-2xl",children:"Generate Type-safe Implementations"}),Zt("p",{className:"text-muted-foreground text-sm",children:"Generate validation, types, and API handlers from your feature."}),Zt(Tl,{language:"bash",filename:"generate-from-feature",code:"contractspec generate \\\n --input ./src/contracts/user-management.feature.ts \\\n --output ./generated/user-management"})]})]}),Oo("div",{className:"flex items-center gap-4 pt-4",children:[Oo(Al,{href:"/docs/guides/spec-validation-and-typing",className:"btn-primary",children:["Type Safety Guide ",Zt(Fg,{size:16})]}),Zt(Al,{href:"/docs/intent/deterministic-codegen",className:"btn-ghost",children:"Deterministic Codegen"})]})]})}import Rl from"@contractspec/lib.ui-link";import{ChevronRight as Qg}from"lucide-react";import{jsx as n,jsxs as m}from"react/jsx-runtime";function Yg(){return m("div",{className:"space-y-8",children:[m("div",{className:"space-y-4",children:[n("h1",{className:"font-bold text-4xl",children:"Knowledge Categories"}),n("p",{className:"text-muted-foreground",children:"ContractSpec classifies knowledge into four categories based on trust level, source authority, and intended use. This classification determines how knowledge can be used in workflows, policy decisions, and agent responses."})]}),m("div",{className:"space-y-4",children:[n("h2",{className:"font-bold text-2xl",children:"The four categories"}),n("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:n("pre",{children:`type KnowledgeCategory =
|
|
3132
3132
|
| "canonical" // Internal ground truth
|
|
3133
3133
|
| "operational" // Internal operational docs
|
|
3134
3134
|
| "external" // Third-party reference
|
|
@@ -3212,7 +3212,7 @@ export const UserManagementFeature = defineFeature({
|
|
|
3212
3212
|
"session:user-uploads",
|
|
3213
3213
|
"session:form-drafts"
|
|
3214
3214
|
]
|
|
3215
|
-
}`})})]}),n("div",{className:"card-subtle border-red-500/30 bg-red-500/10 p-3",children:m("p",{className:"text-red-300 text-sm",children:[n("strong",{children:"⚠️ Critical:"})," Ephemeral knowledge is never used for policy decisions, compliance checks, or any authoritative purpose."]})})]})]})]}),m("div",{className:"space-y-4",children:[n("h2",{className:"font-bold text-2xl",children:"Category comparison"}),n("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:m("table",{className:"w-full text-left text-sm",children:[n("thead",{className:"bg-card/50",children:m("tr",{className:"border-border/50 border-b",children:[n("th",{className:"px-4 py-3 font-semibold",children:"Feature"}),n("th",{className:"px-4 py-3 font-semibold",children:"Canonical"}),n("th",{className:"px-4 py-3 font-semibold",children:"Operational"}),n("th",{className:"px-4 py-3 font-semibold",children:"External"}),n("th",{className:"px-4 py-3 font-semibold",children:"Ephemeral"})]})}),m("tbody",{className:"divide-y divide-border/50",children:[m("tr",{children:[n("td",{className:"px-4 py-3 font-semibold",children:"Trust Level"}),n("td",{className:"px-4 py-3",children:"Highest"}),n("td",{className:"px-4 py-3",children:"High"}),n("td",{className:"px-4 py-3",children:"Medium"}),n("td",{className:"px-4 py-3",children:"Low"})]}),m("tr",{children:[n("td",{className:"px-4 py-3 font-semibold",children:"Policy Impact"}),n("td",{className:"px-4 py-3",children:"✅ Can drive decisions"}),n("td",{className:"px-4 py-3",children:"⚠️ Can inform"}),n("td",{className:"px-4 py-3",children:"❌ Reference only"}),n("td",{className:"px-4 py-3",children:"❌ Never used"})]}),m("tr",{children:[n("td",{className:"px-4 py-3 font-semibold",children:"Mutability"}),n("td",{className:"px-4 py-3",children:"Immutable"}),n("td",{className:"px-4 py-3",children:"Mutable"}),n("td",{className:"px-4 py-3",children:"Mutable"}),n("td",{className:"px-4 py-3",children:"Temporary"})]}),m("tr",{children:[n("td",{className:"px-4 py-3 font-semibold",children:"Retention"}),n("td",{className:"px-4 py-3",children:"Permanent"}),n("td",{className:"px-4 py-3",children:"Long-term"}),n("td",{className:"px-4 py-3",children:"Long-term"}),n("td",{className:"px-4 py-3",children:"Short-term"})]}),m("tr",{children:[n("td",{className:"px-4 py-3 font-semibold",children:"Audit Level"}),n("td",{className:"px-4 py-3",children:"Full audit"}),n("td",{className:"px-4 py-3",children:"Full audit"}),n("td",{className:"px-4 py-3",children:"Basic audit"}),n("td",{className:"px-4 py-3",children:"Minimal audit"})]})]})]})})]}),m("div",{className:"space-y-4",children:[n("h2",{className:"font-bold text-2xl",children:"Best practices"}),m("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[n("li",{children:"Use canonical for anything that affects policy, pricing, or compliance"}),n("li",{children:"Use operational for context that helps but doesn't dictate decisions"}),n("li",{children:"Use external for reference material that's helpful but not authoritative"}),n("li",{children:"Use ephemeral for temporary working memory that shouldn't persist"}),n("li",{children:"Never mix categories in a single knowledge space - keep them separate"}),n("li",{children:"Document the category and purpose of each knowledge space clearly"})]})]}),m("div",{className:"flex items-center gap-4 pt-4",children:[n(
|
|
3215
|
+
}`})})]}),n("div",{className:"card-subtle border-red-500/30 bg-red-500/10 p-3",children:m("p",{className:"text-red-300 text-sm",children:[n("strong",{children:"⚠️ Critical:"})," Ephemeral knowledge is never used for policy decisions, compliance checks, or any authoritative purpose."]})})]})]})]}),m("div",{className:"space-y-4",children:[n("h2",{className:"font-bold text-2xl",children:"Category comparison"}),n("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:m("table",{className:"w-full text-left text-sm",children:[n("thead",{className:"bg-card/50",children:m("tr",{className:"border-border/50 border-b",children:[n("th",{className:"px-4 py-3 font-semibold",children:"Feature"}),n("th",{className:"px-4 py-3 font-semibold",children:"Canonical"}),n("th",{className:"px-4 py-3 font-semibold",children:"Operational"}),n("th",{className:"px-4 py-3 font-semibold",children:"External"}),n("th",{className:"px-4 py-3 font-semibold",children:"Ephemeral"})]})}),m("tbody",{className:"divide-y divide-border/50",children:[m("tr",{children:[n("td",{className:"px-4 py-3 font-semibold",children:"Trust Level"}),n("td",{className:"px-4 py-3",children:"Highest"}),n("td",{className:"px-4 py-3",children:"High"}),n("td",{className:"px-4 py-3",children:"Medium"}),n("td",{className:"px-4 py-3",children:"Low"})]}),m("tr",{children:[n("td",{className:"px-4 py-3 font-semibold",children:"Policy Impact"}),n("td",{className:"px-4 py-3",children:"✅ Can drive decisions"}),n("td",{className:"px-4 py-3",children:"⚠️ Can inform"}),n("td",{className:"px-4 py-3",children:"❌ Reference only"}),n("td",{className:"px-4 py-3",children:"❌ Never used"})]}),m("tr",{children:[n("td",{className:"px-4 py-3 font-semibold",children:"Mutability"}),n("td",{className:"px-4 py-3",children:"Immutable"}),n("td",{className:"px-4 py-3",children:"Mutable"}),n("td",{className:"px-4 py-3",children:"Mutable"}),n("td",{className:"px-4 py-3",children:"Temporary"})]}),m("tr",{children:[n("td",{className:"px-4 py-3 font-semibold",children:"Retention"}),n("td",{className:"px-4 py-3",children:"Permanent"}),n("td",{className:"px-4 py-3",children:"Long-term"}),n("td",{className:"px-4 py-3",children:"Long-term"}),n("td",{className:"px-4 py-3",children:"Short-term"})]}),m("tr",{children:[n("td",{className:"px-4 py-3 font-semibold",children:"Audit Level"}),n("td",{className:"px-4 py-3",children:"Full audit"}),n("td",{className:"px-4 py-3",children:"Full audit"}),n("td",{className:"px-4 py-3",children:"Basic audit"}),n("td",{className:"px-4 py-3",children:"Minimal audit"})]})]})]})})]}),m("div",{className:"space-y-4",children:[n("h2",{className:"font-bold text-2xl",children:"Best practices"}),m("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[n("li",{children:"Use canonical for anything that affects policy, pricing, or compliance"}),n("li",{children:"Use operational for context that helps but doesn't dictate decisions"}),n("li",{children:"Use external for reference material that's helpful but not authoritative"}),n("li",{children:"Use ephemeral for temporary working memory that shouldn't persist"}),n("li",{children:"Never mix categories in a single knowledge space - keep them separate"}),n("li",{children:"Document the category and purpose of each knowledge space clearly"})]})]}),m("div",{className:"flex items-center gap-4 pt-4",children:[n(Rl,{href:"/docs/knowledge",className:"btn-ghost",children:"Back to Knowledge"}),m(Rl,{href:"/docs/knowledge/spaces",className:"btn-primary",children:["Knowledge Spaces ",n(Qg,{size:16})]})]})]})}import Ll from"@contractspec/lib.ui-link";import{jsx as xe,jsxs as Wt}from"react/jsx-runtime";function Jg(){return Wt("div",{className:"space-y-8",children:[Wt("div",{className:"space-y-4",children:[xe("h1",{className:"font-bold text-4xl",children:"Knowledge Examples"}),xe("p",{className:"text-muted-foreground",children:"Real-world examples of how different applications use knowledge spaces to power intelligent workflows and agents."})]}),Wt("div",{className:"space-y-6",children:[Wt("div",{className:"space-y-4",children:[xe("h2",{className:"font-bold text-2xl",children:"Example 1: ArtisanOS Support Agent"}),Wt("p",{className:"text-muted-foreground",children:[xe("strong",{children:"Context:"})," ArtisanOS needs a support agent that can answer product questions using official documentation and learn from past support tickets."]}),xe("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:xe("pre",{children:`// Knowledge spaces
|
|
3216
3216
|
knowledgeSpaces: [
|
|
3217
3217
|
{
|
|
3218
3218
|
id: "product-canon",
|
|
@@ -3380,7 +3380,7 @@ steps:
|
|
|
3380
3380
|
Question: \${input.question}
|
|
3381
3381
|
Internal: \${steps.search-internal-guides.output.results}
|
|
3382
3382
|
Stripe: \${steps.search-stripe-docs.output.results}
|
|
3383
|
-
Past: \${steps.search-past-questions.output.results}`})})]})]}),Wt("div",{className:"space-y-4",children:[xe("h2",{className:"font-bold text-2xl",children:"Key patterns"}),Wt("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Wt("li",{children:[xe("strong",{children:"Canonical first"})," - Always search canonical spaces before operational or external"]}),Wt("li",{children:[xe("strong",{children:"Category-aware prompts"})," - Tell the LLM which sources are authoritative vs reference"]}),Wt("li",{children:[xe("strong",{children:"Multi-space queries"})," - Combine results from multiple spaces for richer context"]}),Wt("li",{children:[xe("strong",{children:"Limit results"})," - Use appropriate limits (3-5) to avoid token overflow"]}),Wt("li",{children:[xe("strong",{children:"Audit everything"})," - Log all knowledge queries for debugging and compliance"]})]})]}),Wt("div",{className:"flex items-center gap-4 pt-4",children:[xe(
|
|
3383
|
+
Past: \${steps.search-past-questions.output.results}`})})]})]}),Wt("div",{className:"space-y-4",children:[xe("h2",{className:"font-bold text-2xl",children:"Key patterns"}),Wt("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Wt("li",{children:[xe("strong",{children:"Canonical first"})," - Always search canonical spaces before operational or external"]}),Wt("li",{children:[xe("strong",{children:"Category-aware prompts"})," - Tell the LLM which sources are authoritative vs reference"]}),Wt("li",{children:[xe("strong",{children:"Multi-space queries"})," - Combine results from multiple spaces for richer context"]}),Wt("li",{children:[xe("strong",{children:"Limit results"})," - Use appropriate limits (3-5) to avoid token overflow"]}),Wt("li",{children:[xe("strong",{children:"Audit everything"})," - Log all knowledge queries for debugging and compliance"]})]})]}),Wt("div",{className:"flex items-center gap-4 pt-4",children:[xe(Ll,{href:"/docs/knowledge/sources",className:"btn-ghost",children:"Previous: Sources"}),xe(Ll,{href:"/docs/architecture/knowledge-binding",className:"btn-ghost",children:"Knowledge Binding"})]})]})}import Zg from"@contractspec/lib.ui-link";import{jsx as Ra,jsxs as Xo}from"react/jsx-runtime";var $g=[{title:"Categories",body:"Separate canonical truth from operational notes, external material, and ephemeral working context.",href:"/docs/knowledge/categories"},{title:"Spaces",body:"Define the storage and retrieval boundary for each knowledge domain.",href:"/docs/knowledge/spaces"},{title:"Sources",body:"Connect tenant-owned sources explicitly instead of letting context leak in through prompts alone.",href:"/docs/knowledge/sources"},{title:"Examples",body:"See how support, compliance, and product systems consume trusted knowledge at runtime.",href:"/docs/knowledge/examples"}];function Xg(){return Xo("div",{className:"space-y-10",children:[Xo("div",{className:"space-y-3",children:[Ra("p",{className:"editorial-kicker",children:"Operate"}),Ra("h1",{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"Knowledge is part of the runtime, not a sidecar prompt hack."}),Ra("p",{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:"When AI-native systems depend on external context, the context needs the same discipline as the rest of the stack. ContractSpec treats knowledge as typed, bounded, and governable so teams can reason about trust, isolation, and retrieval behavior."})]}),Ra("section",{className:"editorial-panel space-y-5",children:Xo("div",{className:"space-y-2",children:[Ra("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"How knowledge enters the system"}),Xo("ul",{className:"editorial-list",children:[Xo("li",{children:[Ra("span",{className:"editorial-list-marker"}),Ra("span",{children:"Define the trust category and retrieval expectations first."})]}),Xo("li",{children:[Ra("span",{className:"editorial-list-marker"}),Ra("span",{children:"Bind tenant-owned sources explicitly to those knowledge spaces."})]}),Xo("li",{children:[Ra("span",{className:"editorial-list-marker"}),Ra("span",{children:"Consume knowledge through capabilities and workflows, not through invisible prompt assumptions."})]})]})]})}),Ra("div",{className:"grid gap-4 md:grid-cols-2",children:$g.map((e)=>Xo(Zg,{href:e.href,className:"editorial-panel",children:[Ra("h2",{className:"font-semibold text-xl",children:e.title}),Ra("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:e.body})]},e.href))})]})}import Dl from"@contractspec/lib.ui-link";import{ChevronRight as xg}from"lucide-react";import{jsx as f,jsxs as le}from"react/jsx-runtime";function jg(){return le("div",{className:"space-y-8",children:[le("div",{className:"space-y-4",children:[f("h1",{className:"font-bold text-4xl",children:"Knowledge Sources"}),le("p",{className:"text-muted-foreground",children:["A ",f("strong",{children:"KnowledgeSourceConfig"})," connects a tenant's data sources (Notion, Gmail, uploads, databases) to knowledge spaces. Each source is synced, chunked, embedded, and indexed according to the space's configuration."]})]}),le("div",{className:"space-y-4",children:[f("h2",{className:"font-bold text-2xl",children:"KnowledgeSourceConfig"}),f("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:f("pre",{children:`type KnowledgeSourceConfig = {
|
|
3384
3384
|
id: string;
|
|
3385
3385
|
tenantId: string;
|
|
3386
3386
|
spaceId: string;
|
|
@@ -3450,7 +3450,7 @@ steps:
|
|
|
3450
3450
|
syncPolicy: { manual: true }
|
|
3451
3451
|
}
|
|
3452
3452
|
]
|
|
3453
|
-
}`})})]}),le("div",{className:"space-y-4",children:[f("h2",{className:"font-bold text-2xl",children:"Processing pipeline"}),f("p",{className:"text-muted-foreground",children:"When a source is synced, ContractSpec processes it through several stages:"}),le("ol",{className:"list-inside list-decimal space-y-3 text-muted-foreground",children:[le("li",{children:[f("strong",{children:"Fetch"})," - Retrieve content from source (API, database, file)"]}),le("li",{children:[f("strong",{children:"Parse"})," - Extract text from documents (PDF, Word, HTML)"]}),le("li",{children:[f("strong",{children:"Chunk"})," - Split into semantic chunks (paragraphs, sections)"]}),le("li",{children:[f("strong",{children:"Embed"})," - Generate vector embeddings (OpenAI, Cohere)"]}),le("li",{children:[f("strong",{children:"Index"})," - Store in vector database (Qdrant) or search engine"]}),le("li",{children:[f("strong",{children:"Audit"})," - Log sync operation and results"]})]})]}),le("div",{className:"space-y-4",children:[f("h2",{className:"font-bold text-2xl",children:"Best practices"}),le("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[f("li",{children:"Use webhooks for real-time sources (Notion, Gmail) to minimize latency"}),f("li",{children:"Set appropriate sync intervals - hourly for active docs, daily for stable content"}),f("li",{children:"Monitor sync failures and set up alerts for critical sources"}),f("li",{children:"Test sources in sandbox before enabling in production"}),f("li",{children:"Document the purpose and ownership of each source for your team"}),f("li",{children:"Use manual sync for sensitive or infrequently updated content"})]})]}),le("div",{className:"flex items-center gap-4 pt-4",children:[f(
|
|
3453
|
+
}`})})]}),le("div",{className:"space-y-4",children:[f("h2",{className:"font-bold text-2xl",children:"Processing pipeline"}),f("p",{className:"text-muted-foreground",children:"When a source is synced, ContractSpec processes it through several stages:"}),le("ol",{className:"list-inside list-decimal space-y-3 text-muted-foreground",children:[le("li",{children:[f("strong",{children:"Fetch"})," - Retrieve content from source (API, database, file)"]}),le("li",{children:[f("strong",{children:"Parse"})," - Extract text from documents (PDF, Word, HTML)"]}),le("li",{children:[f("strong",{children:"Chunk"})," - Split into semantic chunks (paragraphs, sections)"]}),le("li",{children:[f("strong",{children:"Embed"})," - Generate vector embeddings (OpenAI, Cohere)"]}),le("li",{children:[f("strong",{children:"Index"})," - Store in vector database (Qdrant) or search engine"]}),le("li",{children:[f("strong",{children:"Audit"})," - Log sync operation and results"]})]})]}),le("div",{className:"space-y-4",children:[f("h2",{className:"font-bold text-2xl",children:"Best practices"}),le("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[f("li",{children:"Use webhooks for real-time sources (Notion, Gmail) to minimize latency"}),f("li",{children:"Set appropriate sync intervals - hourly for active docs, daily for stable content"}),f("li",{children:"Monitor sync failures and set up alerts for critical sources"}),f("li",{children:"Test sources in sandbox before enabling in production"}),f("li",{children:"Document the purpose and ownership of each source for your team"}),f("li",{children:"Use manual sync for sensitive or infrequently updated content"})]})]}),le("div",{className:"flex items-center gap-4 pt-4",children:[f(Dl,{href:"/docs/knowledge/spaces",className:"btn-ghost",children:"Previous: Spaces"}),le(Dl,{href:"/docs/knowledge/examples",className:"btn-primary",children:["Examples ",f(xg,{size:16})]})]})]})}import El from"@contractspec/lib.ui-link";import{ChevronRight as ef}from"lucide-react";import{jsx as E,jsxs as Ae}from"react/jsx-runtime";function tf(){return Ae("div",{className:"space-y-8",children:[Ae("div",{className:"space-y-4",children:[E("h1",{className:"font-bold text-4xl",children:"Knowledge Spaces"}),Ae("p",{className:"text-muted-foreground",children:["A ",E("strong",{children:"KnowledgeSpaceSpec"})," defines a logical domain of knowledge with a specific category, storage strategy, and intended audience. Spaces are defined globally and populated per-tenant through knowledge sources."]})]}),Ae("div",{className:"space-y-4",children:[E("h2",{className:"font-bold text-2xl",children:"KnowledgeSpaceSpec"}),E("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:E("pre",{children:`type KnowledgeSpaceSpec = {
|
|
3454
3454
|
id: string;
|
|
3455
3455
|
label: string;
|
|
3456
3456
|
description: string;
|
|
@@ -3514,7 +3514,7 @@ steps:
|
|
|
3514
3514
|
indexProvider: "qdrant",
|
|
3515
3515
|
vectorDimensions: 1536,
|
|
3516
3516
|
retentionPolicy: { days: 1 }
|
|
3517
|
-
}`})}),Ae("p",{className:"mt-2 text-muted-foreground text-sm",children:[E("strong",{children:"Use cases:"})," Conversation continuity, intermediate calculations, session state"]})]})]})]}),Ae("div",{className:"space-y-4",children:[E("h2",{className:"font-bold text-2xl",children:"Storage strategies"}),E("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:Ae("table",{className:"w-full text-left text-sm",children:[E("thead",{className:"bg-card/50",children:Ae("tr",{className:"border-border/50 border-b",children:[E("th",{className:"px-4 py-3 font-semibold",children:"Strategy"}),E("th",{className:"px-4 py-3 font-semibold",children:"Best For"}),E("th",{className:"px-4 py-3 font-semibold",children:"Providers"})]})}),Ae("tbody",{className:"divide-y divide-border/50",children:[Ae("tr",{children:[E("td",{className:"px-4 py-3 font-mono text-xs",children:"vector"}),E("td",{className:"px-4 py-3",children:"Semantic search, RAG, similarity matching"}),E("td",{className:"px-4 py-3",children:"Qdrant, Pinecone, Weaviate"})]}),Ae("tr",{children:[E("td",{className:"px-4 py-3 font-mono text-xs",children:"search"}),E("td",{className:"px-4 py-3",children:"Keyword search, exact matching, filtering"}),E("td",{className:"px-4 py-3",children:"Elasticsearch, Algolia"})]}),Ae("tr",{children:[E("td",{className:"px-4 py-3 font-mono text-xs",children:"hybrid"}),E("td",{className:"px-4 py-3",children:"Combined semantic + keyword search"}),E("td",{className:"px-4 py-3",children:"Qdrant + Elasticsearch"})]})]})]})})]}),Ae("div",{className:"space-y-4",children:[E("h2",{className:"font-bold text-2xl",children:"Best practices"}),Ae("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[E("li",{children:"Choose storage strategy based on query patterns - use vector for semantic, search for exact"}),E("li",{children:"Set appropriate retention policies - canonical is permanent, ephemeral is short-lived"}),E("li",{children:"Use consistent vector dimensions across spaces that will be queried together"}),E("li",{children:"Document the intended audience and use cases for each space"}),E("li",{children:"Monitor space size and query performance - add sharding if needed"})]})]}),Ae("div",{className:"flex items-center gap-4 pt-4",children:[E(
|
|
3517
|
+
}`})}),Ae("p",{className:"mt-2 text-muted-foreground text-sm",children:[E("strong",{children:"Use cases:"})," Conversation continuity, intermediate calculations, session state"]})]})]})]}),Ae("div",{className:"space-y-4",children:[E("h2",{className:"font-bold text-2xl",children:"Storage strategies"}),E("div",{className:"overflow-x-auto rounded-lg border border-border/50",children:Ae("table",{className:"w-full text-left text-sm",children:[E("thead",{className:"bg-card/50",children:Ae("tr",{className:"border-border/50 border-b",children:[E("th",{className:"px-4 py-3 font-semibold",children:"Strategy"}),E("th",{className:"px-4 py-3 font-semibold",children:"Best For"}),E("th",{className:"px-4 py-3 font-semibold",children:"Providers"})]})}),Ae("tbody",{className:"divide-y divide-border/50",children:[Ae("tr",{children:[E("td",{className:"px-4 py-3 font-mono text-xs",children:"vector"}),E("td",{className:"px-4 py-3",children:"Semantic search, RAG, similarity matching"}),E("td",{className:"px-4 py-3",children:"Qdrant, Pinecone, Weaviate"})]}),Ae("tr",{children:[E("td",{className:"px-4 py-3 font-mono text-xs",children:"search"}),E("td",{className:"px-4 py-3",children:"Keyword search, exact matching, filtering"}),E("td",{className:"px-4 py-3",children:"Elasticsearch, Algolia"})]}),Ae("tr",{children:[E("td",{className:"px-4 py-3 font-mono text-xs",children:"hybrid"}),E("td",{className:"px-4 py-3",children:"Combined semantic + keyword search"}),E("td",{className:"px-4 py-3",children:"Qdrant + Elasticsearch"})]})]})]})})]}),Ae("div",{className:"space-y-4",children:[E("h2",{className:"font-bold text-2xl",children:"Best practices"}),Ae("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[E("li",{children:"Choose storage strategy based on query patterns - use vector for semantic, search for exact"}),E("li",{children:"Set appropriate retention policies - canonical is permanent, ephemeral is short-lived"}),E("li",{children:"Use consistent vector dimensions across spaces that will be queried together"}),E("li",{children:"Document the intended audience and use cases for each space"}),E("li",{children:"Monitor space size and query performance - add sharding if needed"})]})]}),Ae("div",{className:"flex items-center gap-4 pt-4",children:[E(El,{href:"/docs/knowledge/categories",className:"btn-ghost",children:"Previous: Categories"}),Ae(El,{href:"/docs/knowledge/sources",className:"btn-primary",children:["Knowledge Sources ",E(ef,{size:16})]})]})]})}import{CodeBlock as Ol,InstallCommand as af}from"@contractspec/lib.design-system";import Bl from"@contractspec/lib.ui-link";import{ChevronRight as of}from"lucide-react";import{jsx as Be,jsxs as At}from"react/jsx-runtime";function rf(){return At("div",{className:"space-y-8",children:[At("div",{className:"space-y-4",children:[Be("h1",{className:"font-bold text-4xl",children:"@contractspec/lib.accessibility"}),Be("p",{className:"text-muted-foreground",children:"Stable exports of accessibility primitives for LSSM web apps, ensuring WCAG compliance and inclusive design."})]}),At("div",{className:"space-y-4",children:[Be("h2",{className:"font-bold text-2xl",children:"Installation"}),Be(af,{package:"@contractspec/lib.accessibility"})]}),At("div",{className:"space-y-4",children:[Be("h2",{className:"font-bold text-2xl",children:"Exports"}),At("ul",{className:"space-y-2 text-muted-foreground",children:[At("li",{children:[Be("code",{className:"rounded bg-background/50 px-2 py-1",children:"SkipLink"}),": A link to skip navigation, visible on focus"]}),At("li",{children:[Be("code",{className:"rounded bg-background/50 px-2 py-1",children:"VisuallyHidden"}),": Hide content visually but keep it for screen readers"]}),At("li",{children:[Be("code",{className:"rounded bg-background/50 px-2 py-1",children:"SRLiveRegionProvider"}),","," ",Be("code",{className:"rounded bg-background/50 px-2 py-1",children:"useSRLiveRegion"}),": Manage live region announcements"]}),At("li",{children:[Be("code",{className:"rounded bg-background/50 px-2 py-1",children:"RouteAnnouncer"}),": Announce page title/path changes on navigation"]}),At("li",{children:[Be("code",{className:"rounded bg-background/50 px-2 py-1",children:"FocusOnRouteChange"}),": Reset focus to body or main content on navigation"]}),At("li",{children:[Be("code",{className:"rounded bg-background/50 px-2 py-1",children:"useReducedMotion"}),": Detect if the user prefers reduced motion"]})]})]}),At("div",{className:"space-y-4",children:[Be("h2",{className:"font-bold text-2xl",children:"Example: App Setup"}),Be(Ol,{language:"tsx",code:`import {
|
|
3518
3518
|
SRLiveRegionProvider,
|
|
3519
3519
|
RouteAnnouncer,
|
|
3520
3520
|
SkipLink
|
|
@@ -3534,7 +3534,7 @@ export function RootLayout({ children }) {
|
|
|
3534
3534
|
</body>
|
|
3535
3535
|
</html>
|
|
3536
3536
|
);
|
|
3537
|
-
}`})]}),At("div",{className:"space-y-4",children:[Be("h2",{className:"font-bold text-2xl",children:"Example: Live Announcements"}),Be(
|
|
3537
|
+
}`})]}),At("div",{className:"space-y-4",children:[Be("h2",{className:"font-bold text-2xl",children:"Example: Live Announcements"}),Be(Ol,{language:"tsx",code:`import { useSRLiveRegion } from '@contractspec/lib.accessibility';
|
|
3538
3538
|
|
|
3539
3539
|
export function TodoList() {
|
|
3540
3540
|
const { announce } = useSRLiveRegion();
|
|
@@ -3545,7 +3545,7 @@ export function TodoList() {
|
|
|
3545
3545
|
};
|
|
3546
3546
|
|
|
3547
3547
|
return <button onClick={addTodo}>Add Todo</button>;
|
|
3548
|
-
}`})]}),At("div",{className:"space-y-4",children:[Be("h2",{className:"font-bold text-2xl",children:"WCAG Compliance"}),At("p",{className:"text-muted-foreground",children:["These components map directly to WCAG 2.1 Level AA requirements documented in ",Be("code",{children:"docs/accessibility_wcag_compliance_specs.md"}),":"]}),At("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Be("li",{children:"2.4.1 Bypass Blocks (SkipLink)"}),Be("li",{children:"4.1.3 Status Messages (LiveRegion)"}),Be("li",{children:"2.4.3 Focus Order (FocusOnRouteChange)"}),Be("li",{children:"2.3.3 Animation from Interactions (useReducedMotion)"})]})]}),At("div",{className:"flex items-center gap-4 pt-4",children:[Be(
|
|
3548
|
+
}`})]}),At("div",{className:"space-y-4",children:[Be("h2",{className:"font-bold text-2xl",children:"WCAG Compliance"}),At("p",{className:"text-muted-foreground",children:["These components map directly to WCAG 2.1 Level AA requirements documented in ",Be("code",{children:"docs/accessibility_wcag_compliance_specs.md"}),":"]}),At("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Be("li",{children:"2.4.1 Bypass Blocks (SkipLink)"}),Be("li",{children:"4.1.3 Status Messages (LiveRegion)"}),Be("li",{children:"2.4.3 Focus Order (FocusOnRouteChange)"}),Be("li",{children:"2.3.3 Animation from Interactions (useReducedMotion)"})]})]}),At("div",{className:"flex items-center gap-4 pt-4",children:[Be(Bl,{href:"/docs/libraries/design-system",className:"btn-ghost",children:"Previous: Design System"}),At(Bl,{href:"/docs/libraries",className:"btn-primary",children:["Back to Libraries ",Be(of,{size:16})]})]})]})}import{CodeBlock as Ml,InstallCommand as nf}from"@contractspec/lib.design-system";import Ul from"@contractspec/lib.ui-link";import{ChevronRight as cf}from"lucide-react";import{jsx as Rt,jsxs as Qa}from"react/jsx-runtime";function lf(){return Qa("div",{className:"space-y-8",children:[Qa("div",{className:"space-y-4",children:[Rt("h1",{className:"font-bold text-4xl",children:"@contractspec/lib.ai-agent"}),Rt("p",{className:"text-lg text-muted-foreground",children:"Define AI agents in TypeScript, run them with deterministic tool calling, capture working memory, and route low-confidence decisions to human reviewers."})]}),Qa("div",{className:"space-y-4",children:[Rt("h2",{className:"font-bold text-2xl",children:"Installation"}),Rt(nf,{package:"@contractspec/lib.ai-agent"})]}),Qa("div",{className:"space-y-3",children:[Rt("h2",{className:"font-bold text-2xl",children:"Define & register"}),Rt(Ml,{language:"typescript",code:`import { defineAgent, AgentRegistry } from '@contractspec/lib.contracts-spec/agent';
|
|
3549
3549
|
|
|
3550
3550
|
const SupportBot = defineAgent({
|
|
3551
3551
|
meta: {
|
|
@@ -3564,7 +3564,7 @@ const SupportBot = defineAgent({
|
|
|
3564
3564
|
},
|
|
3565
3565
|
});
|
|
3566
3566
|
|
|
3567
|
-
const registry = new AgentRegistry().register(SupportBot);`})]}),Qa("div",{className:"space-y-3",children:[Rt("h2",{className:"font-bold text-2xl",children:"Run with approvals"}),Rt(
|
|
3567
|
+
const registry = new AgentRegistry().register(SupportBot);`})]}),Qa("div",{className:"space-y-3",children:[Rt("h2",{className:"font-bold text-2xl",children:"Run with approvals"}),Rt(Ml,{language:"typescript",code:`import { createUnifiedAgent, ApprovalWorkflow } from '@contractspec/lib.ai-agent';
|
|
3568
3568
|
|
|
3569
3569
|
const approvals = new ApprovalWorkflow();
|
|
3570
3570
|
const agent = createUnifiedAgent(SupportBot, {
|
|
@@ -3574,7 +3574,7 @@ const agent = createUnifiedAgent(SupportBot, {
|
|
|
3574
3574
|
|
|
3575
3575
|
const result = await agent.run(ticket.body);
|
|
3576
3576
|
// Route low-confidence or manual-review flows through approvals when needed.
|
|
3577
|
-
`})]}),Qa("div",{className:"space-y-3",children:[Rt("h2",{className:"font-bold text-2xl",children:"What's inside"}),Qa("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Qa("li",{children:[Rt("code",{children:"createUnifiedAgent"}),", ",Rt("code",{children:"ContractSpecAgent"}),","," ",Rt("code",{children:"UnifiedAgent"})]}),Rt("li",{children:"MCP, operation-backed, memory, and subagent tool adapters"}),Qa("li",{children:[Rt("code",{children:"InMemoryAgentMemory"})," plus interfaces for custom stores"]}),Qa("li",{children:[Rt("code",{children:"ApprovalWorkflow"})," + ",Rt("code",{children:"ApprovalStore"})," for human-in-the-loop reviews"]})]})]}),Qa("div",{className:"flex items-center gap-4 pt-4",children:[Rt(
|
|
3577
|
+
`})]}),Qa("div",{className:"space-y-3",children:[Rt("h2",{className:"font-bold text-2xl",children:"What's inside"}),Qa("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Qa("li",{children:[Rt("code",{children:"createUnifiedAgent"}),", ",Rt("code",{children:"ContractSpecAgent"}),","," ",Rt("code",{children:"UnifiedAgent"})]}),Rt("li",{children:"MCP, operation-backed, memory, and subagent tool adapters"}),Qa("li",{children:[Rt("code",{children:"InMemoryAgentMemory"})," plus interfaces for custom stores"]}),Qa("li",{children:[Rt("code",{children:"ApprovalWorkflow"})," + ",Rt("code",{children:"ApprovalStore"})," for human-in-the-loop reviews"]})]})]}),Qa("div",{className:"flex items-center gap-4 pt-4",children:[Rt(Ul,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),Qa(Ul,{href:"/docs/libraries/support-bot",className:"btn-primary",children:["Next: Support Bot ",Rt(cf,{size:16})]})]})]})}import{CodeBlock as pn,InstallCommand as df}from"@contractspec/lib.design-system";import{jsx as vo,jsxs as Di}from"react/jsx-runtime";function sf(){return Di("div",{className:"space-y-8",children:[Di("div",{className:"space-y-4",children:[vo("h1",{className:"font-bold text-4xl",children:"@contractspec/lib.analytics"}),vo("p",{className:"text-lg text-muted-foreground",children:"Work directly with telemetry events to understand conversion, retention, churn, and growth opportunities."})]}),Di("div",{className:"space-y-4",children:[vo("h2",{className:"font-bold text-2xl",children:"Installation"}),vo(df,{package:"@contractspec/lib.analytics"})]}),Di("div",{className:"space-y-3",children:[vo("h2",{className:"font-bold text-2xl",children:"Funnels in memory"}),vo(pn,{language:"typescript",code:`import { FunnelAnalyzer } from '@contractspec/lib.analytics/funnel';
|
|
3578
3578
|
|
|
3579
3579
|
const analyzer = new FunnelAnalyzer();
|
|
3580
3580
|
const report = analyzer.analyze(events, {
|
|
@@ -3584,16 +3584,16 @@ const report = analyzer.analyze(events, {
|
|
|
3584
3584
|
{ id: 'submit', eventName: 'signup.submit' },
|
|
3585
3585
|
{ id: 'verified', eventName: 'account.verified' },
|
|
3586
3586
|
],
|
|
3587
|
-
});`})]}),Di("div",{className:"space-y-3",children:[vo("h2",{className:"font-bold text-2xl",children:"Cohorts & churn"}),vo(
|
|
3587
|
+
});`})]}),Di("div",{className:"space-y-3",children:[vo("h2",{className:"font-bold text-2xl",children:"Cohorts & churn"}),vo(pn,{language:"typescript",code:`import { CohortTracker } from '@contractspec/lib.analytics/cohort';
|
|
3588
3588
|
import { ChurnPredictor } from '@contractspec/lib.analytics/churn';
|
|
3589
3589
|
|
|
3590
3590
|
const cohorts = new CohortTracker().analyze(events, { bucket: 'week', periods: 8 });
|
|
3591
|
-
const churn = new ChurnPredictor().score(events);`})]}),Di("div",{className:"space-y-3",children:[vo("h2",{className:"font-bold text-2xl",children:"Growth hypotheses"}),vo(
|
|
3591
|
+
const churn = new ChurnPredictor().score(events);`})]}),Di("div",{className:"space-y-3",children:[vo("h2",{className:"font-bold text-2xl",children:"Growth hypotheses"}),vo(pn,{language:"typescript",code:`import { GrowthHypothesisGenerator } from '@contractspec/lib.analytics/growth';
|
|
3592
3592
|
|
|
3593
3593
|
const ideas = new GrowthHypothesisGenerator().generate([
|
|
3594
3594
|
{ name: 'Activation rate', current: 0.42, previous: 0.55, target: 0.6 },
|
|
3595
3595
|
{ name: 'Expansion ARPU', current: 1.2, previous: 0.9 },
|
|
3596
|
-
]);`})]})]})}import{CodeBlock as
|
|
3596
|
+
]);`})]})]})}import{CodeBlock as pf,InstallCommand as mf}from"@contractspec/lib.design-system";import Wl from"@contractspec/lib.ui-link";import{ChevronRight as uf}from"lucide-react";import{jsx as Ua,jsxs as xo}from"react/jsx-runtime";function gf(){return xo("div",{className:"space-y-8",children:[xo("div",{className:"space-y-4",children:[Ua("h1",{className:"font-bold text-4xl",children:"@contractspec/lib.content-gen"}),Ua("p",{className:"text-lg text-muted-foreground",children:"Feed a single ContentBrief and produce cohesive marketing assets without touching a CMS."})]}),xo("div",{className:"space-y-4",children:[Ua("h2",{className:"font-bold text-2xl",children:"Installation"}),Ua(mf,{package:"@contractspec/lib.content-gen"})]}),xo("div",{className:"space-y-3",children:[Ua("h2",{className:"font-bold text-2xl",children:"One brief, many assets"}),Ua(pf,{language:"typescript",code:`import {
|
|
3597
3597
|
BlogGenerator,
|
|
3598
3598
|
LandingPageGenerator,
|
|
3599
3599
|
EmailCampaignGenerator,
|
|
@@ -3613,7 +3613,7 @@ const blog = await new BlogGenerator().generate(brief);
|
|
|
3613
3613
|
const landing = await new LandingPageGenerator().generate(brief);
|
|
3614
3614
|
const email = await new EmailCampaignGenerator().generate({ brief, variant: 'announcement' });
|
|
3615
3615
|
const social = await new SocialPostGenerator().generate(brief);
|
|
3616
|
-
const seo = new SeoOptimizer().optimize(brief);`})]}),xo("div",{className:"space-y-3",children:[Ua("h2",{className:"font-bold text-2xl",children:"When to use"}),xo("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Ua("li",{children:"Ship landing page refreshes whenever specs change."}),Ua("li",{children:"Automate release emails + nurture sequences per vertical."}),Ua("li",{children:"Create social snippets that stay on-message with the same brief."}),Ua("li",{children:"Generate SEO metadata + Schema.org markup alongside content."})]})]}),xo("div",{className:"flex items-center gap-4 pt-4",children:[Ua(
|
|
3616
|
+
const seo = new SeoOptimizer().optimize(brief);`})]}),xo("div",{className:"space-y-3",children:[Ua("h2",{className:"font-bold text-2xl",children:"When to use"}),xo("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Ua("li",{children:"Ship landing page refreshes whenever specs change."}),Ua("li",{children:"Automate release emails + nurture sequences per vertical."}),Ua("li",{children:"Create social snippets that stay on-message with the same brief."}),Ua("li",{children:"Generate SEO metadata + Schema.org markup alongside content."})]})]}),xo("div",{className:"flex items-center gap-4 pt-4",children:[Ua(Wl,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),xo(Wl,{href:"/docs/libraries/support-bot",className:"btn-primary",children:["Next: Support Bot ",Ua(uf,{size:16})]})]})]})}import{CodeBlock as ff,InstallCommand as hf}from"@contractspec/lib.design-system";import mn from"@contractspec/lib.ui-link";import{ChevronRight as yf}from"lucide-react";import{jsx as ee,jsxs as te}from"react/jsx-runtime";var bf=`import { defineDataView } from '@contractspec/lib.contracts-spec/data-views';
|
|
3617
3617
|
import { ListDataGridShowcaseRowsQuery } from '@contractspec/example.data-grid-showcase/contracts/data-grid-showcase.operation';
|
|
3618
3618
|
|
|
3619
3619
|
export const DataGridShowcaseDataView = defineDataView({
|
|
@@ -3660,7 +3660,7 @@ export const DataGridShowcaseDataView = defineDataView({
|
|
|
3660
3660
|
{ key: 'notes', label: 'Notes', dataPath: 'notes' },
|
|
3661
3661
|
],
|
|
3662
3662
|
},
|
|
3663
|
-
});`;function
|
|
3663
|
+
});`;function vf(){return te("div",{className:"space-y-8",children:[te("div",{className:"space-y-4",children:[ee("h1",{className:"font-bold text-4xl",children:"@contractspec/lib.contracts-spec"}),ee("p",{className:"text-lg text-muted-foreground",children:"The core library for defining what your application can do. Unified specifications for Operations, Events, Presentations, and Features."})]}),te("div",{className:"space-y-4",children:[ee("h2",{className:"font-bold text-2xl",children:"Installation"}),ee(hf,{package:["@contractspec/lib.contracts-spec","@contractspec/lib.schema"]})]}),te("div",{className:"space-y-4",children:[ee("h2",{className:"font-bold text-2xl",children:"What lives where"}),te("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[te("li",{children:[ee("strong",{children:"@contractspec/lib.contracts-spec"})," (root): The core contracts definitions (OperationSpec, PresentationSpec, Registry)."]}),te("li",{children:[ee("strong",{children:"@contractspec/lib.contracts-runtime-client-react"}),": Browser-safe helpers (React renderers, client SDK). Import this for web/React Native."]}),te("li",{children:[ee("strong",{children:"@contractspec/lib.contracts-runtime-server-rest"}),": HTTP/MCP adapters, registries, integrations (Node-only)."]}),te("li",{children:[ee("strong",{children:"@contractspec/lib.schema"}),": Schema dictionary (SchemaModel, FieldType) for I/O definitions."]})]})]}),te("div",{className:"space-y-4",children:[ee("h2",{className:"font-bold text-2xl",children:"Data table contract example"}),te("p",{className:"text-muted-foreground",children:["The canonical account-grid example starts here in"," ",ee("code",{children:"@contractspec/lib.contracts-spec"}),". The contract declares table execution mode, selection, pinning, resizing, row expansion, and initial state before any renderer is chosen."]}),ee(ff,{language:"typescript",code:bf}),te("p",{className:"text-muted-foreground text-sm",children:["See the live version in"," ",ee(mn,{href:"/docs/examples/data-grid-showcase",className:"text-[color:var(--rust)] underline underline-offset-4",children:"/docs/examples/data-grid-showcase"}),"."]})]}),te("div",{className:"space-y-4",children:[ee("h2",{className:"font-bold text-2xl",children:"Core Concepts"}),te("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[te("li",{children:[ee("strong",{children:"OperationSpec"}),": Immutable description of an operation (Command or Query). Defines I/O, policy, and metadata."]}),te("li",{children:[ee("strong",{children:"OperationSpecRegistry"}),": Registry of specs + handlers. Use ",ee("code",{className:"font-mono text-xs",children:"installOp"})," ","to attach a handler."]}),te("li",{children:[ee("strong",{children:"CapabilitySpec"}),": Canonical capability declaration (requires/provides)."]}),te("li",{children:[ee("strong",{children:"PolicySpec"}),": Declarative policy rules (ABAC/ReBAC, rate limits)."]}),te("li",{children:[ee("strong",{children:"TelemetrySpec"}),": Analytics definitions and privacy levels."]}),te("li",{children:[ee("strong",{children:"PresentationSpec (V2)"}),": Describes how data is rendered (Web Components, Markdown, Data)."]}),te("li",{children:[ee("strong",{children:"DataViewSpec"}),": Declarative list, table, grid, and detail contracts that the table showcase uses as its canonical account-grid example."]})]})]}),te("div",{className:"space-y-4",children:[ee("h2",{className:"font-bold text-2xl",children:"Lifecycle"}),te("ol",{className:"list-inside list-decimal space-y-2 text-muted-foreground",children:[te("li",{children:[ee("strong",{children:"Define"})," the spec (I/O via SchemaModel or Zod)."]}),te("li",{children:[ee("strong",{children:"Register"})," it:"," ",ee("code",{className:"font-mono text-xs",children:"installOp(registry, spec, handler)"}),"."]}),te("li",{children:[ee("strong",{children:"Expose"})," it via an adapter (REST, GraphQL, MCP)."]}),te("li",{children:[ee("strong",{children:"Validate"})," at runtime automatically."]})]})]}),te("div",{className:"space-y-4",children:[ee("h2",{className:"font-bold text-2xl",children:"Adapters"}),te("ul",{className:"space-y-2 text-muted-foreground",children:[te("li",{children:[ee("code",{className:"rounded bg-background/50 px-2 py-1",children:"server/rest-next-app"}),": Next.js App Router adapter"]}),te("li",{children:[ee("code",{className:"rounded bg-background/50 px-2 py-1",children:"server/provider-mcp"}),": Model Context Protocol (MCP) for AI agents"]}),te("li",{children:[ee("code",{className:"rounded bg-background/50 px-2 py-1",children:"server/graphql-pothos"}),": GraphQL schema generator"]})]})]}),te("div",{className:"flex items-center gap-4 pt-4",children:[te(mn,{href:"/docs/libraries/schema",className:"btn-primary",children:["Next: Schema ",ee(yf,{size:16})]}),ee(mn,{href:"/docs/specs/capabilities",className:"btn-ghost",children:"Core Concepts"})]})]})}import{CodeBlock as _l,InstallCommand as Nf}from"@contractspec/lib.design-system";import zl from"@contractspec/lib.ui-link";import{ChevronRight as wf}from"lucide-react";import{jsx as Ya,jsxs as No}from"react/jsx-runtime";function kf(){return No("div",{className:"space-y-8",children:[No("div",{className:"space-y-4",children:[Ya("h1",{className:"font-bold text-4xl",children:"Cost Tracking Library"}),No("p",{className:"text-lg text-muted-foreground",children:[Ya("code",{children:"@contractspec/lib.cost-tracking"})," transforms raw telemetry into dollars: DB/API/compute costs per operation, budget alerts per tenant, and actionable optimization tips."]})]}),No("div",{className:"space-y-4",children:[Ya("h2",{className:"font-bold text-2xl",children:"Installation"}),Ya(Nf,{package:"@contractspec/lib.cost-tracking"})]}),No("div",{className:"space-y-4",children:[Ya("h2",{className:"font-bold text-2xl",children:"Record Samples"}),Ya(_l,{language:"typescript",code:`const tracker = new CostTracker();
|
|
3664
3664
|
tracker.recordSample({
|
|
3665
3665
|
operation: 'orders.list',
|
|
3666
3666
|
tenantId: 'acme',
|
|
@@ -3668,12 +3668,12 @@ tracker.recordSample({
|
|
|
3668
3668
|
dbWrites: 4,
|
|
3669
3669
|
computeMs: 180,
|
|
3670
3670
|
externalCalls: [{ provider: 'stripe', cost: 0.02 }],
|
|
3671
|
-
});`})]}),No("div",{className:"space-y-4",children:[Ya("h2",{className:"font-bold text-2xl",children:"Budget Alerts"}),Ya(
|
|
3671
|
+
});`})]}),No("div",{className:"space-y-4",children:[Ya("h2",{className:"font-bold text-2xl",children:"Budget Alerts"}),Ya(_l,{language:"typescript",code:`const budgets = new BudgetAlertManager({
|
|
3672
3672
|
budgets: [{ tenantId: 'acme', monthlyLimit: 150 }],
|
|
3673
3673
|
onAlert: ({ tenantId, total }) => notifyFinance(tenantId, total),
|
|
3674
3674
|
});
|
|
3675
3675
|
|
|
3676
|
-
tracker.getTotals({ tenantId: 'acme' }).forEach((summary) => budgets.track(summary));`})]}),No("div",{className:"space-y-4",children:[Ya("h2",{className:"font-bold text-2xl",children:"Optimization Suggestions"}),No("p",{className:"text-muted-foreground text-sm",children:["Feed summaries into ",Ya("code",{children:"OptimizationRecommender"})," to surface N+1 queries, compute-heavy steps, or expensive external calls. Store the generated suggestions in the new Prisma model to power Ops playbooks."]})]}),No("div",{className:"flex items-center gap-4 pt-4",children:[Ya(
|
|
3676
|
+
tracker.getTotals({ tenantId: 'acme' }).forEach((summary) => budgets.track(summary));`})]}),No("div",{className:"space-y-4",children:[Ya("h2",{className:"font-bold text-2xl",children:"Optimization Suggestions"}),No("p",{className:"text-muted-foreground text-sm",children:["Feed summaries into ",Ya("code",{children:"OptimizationRecommender"})," to surface N+1 queries, compute-heavy steps, or expensive external calls. Store the generated suggestions in the new Prisma model to power Ops playbooks."]})]}),No("div",{className:"flex items-center gap-4 pt-4",children:[Ya(zl,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),No(zl,{href:"/docs/libraries/slo",className:"btn-primary",children:["Next: SLO ",Ya(wf,{size:16})]})]})]})}var Gl=[{title:"@contractspec/lib.presentation-runtime-core",body:"Shared state, table models, workflow logic, visualization helpers, and the alias helpers consumed by web and native builds."},{title:"@contractspec/lib.presentation-runtime-react",body:"React-facing hooks such as useContractTable, useDataViewTable, and useWorkflow. This is the shared hook surface most product code starts from."},{title:"@contractspec/lib.presentation-runtime-react-native",body:"Native entrypoint for mobile apps. It re-exports the shared table and data-view hooks so the controller API stays aligned with the React package."},{title:"@contractspec/lib.ui-kit-web",body:"Browser-first primitives and accessibility helpers. Reach for this layer when you want direct control over the web renderer."},{title:"@contractspec/lib.ui-kit",body:"Native-first primitives for Expo and React Native. Reach for this layer when the render surface should stay mobile-native."},{title:"@contractspec/lib.design-system",body:"Composed components, ThemeSpec/TranslationSpec-aware controls, token helpers, and paired web/mobile implementations that sit on top of both UI kits."}],ql=[{title:"useContractTable",body:"Use this when your rows and column definitions already live in product code and you want one headless controller for sorting, pagination, selection, visibility, pinning, sizing, and expansion."},{title:"useDataViewTable",body:"Use this when the table should stay driven by a DataViewSpec instead of hand-authored columns. It adapts the spec to the same generic controller model."},{title:"Native re-export boundary",body:"On native apps, import the same hook names from @contractspec/lib.presentation-runtime-react-native when you want the import path itself to signal a mobile boundary."}],Hl=[{title:"Next.js / Turbopack",body:"Use withPresentationTurbopackAliases as the default path in current Next.js apps. It patches nextConfig.turbopack instead of mutating a webpack config object."},{title:"Next.js / Webpack fallback",body:"Use withPresentationWebpackAliases only when a Next.js app explicitly opts back into webpack via the CLI flags."},{title:"Expo / Metro",body:"Use withPresentationMetroAliases on Metro when native platforms should resolve web ui-kit /ui imports and the shared React runtime root to native implementations."}],Vl=[{title:"withPlatformUI",body:"Use this lightweight adapter when a design-system surface needs one object that carries the current platform, tokens, and breakpoints."},{title:"mapTokensForPlatform",body:"Use this when resolved tokens need to be mapped into platform-specific token shapes before the final renderer consumes them."}],Fl=[{title:"What Webpack remaps",items:["@contractspec/lib.ui-kit -> @contractspec/lib.ui-kit-web","@contractspec/lib.presentation-runtime-react-native -> @contractspec/lib.presentation-runtime-react","Prepends .web.js, .web.jsx, .web.ts, and .web.tsx to webpack resolve.extensions"]},{title:"What Turbopack remaps",items:["@contractspec/lib.ui-kit -> @contractspec/lib.ui-kit-web","@contractspec/lib.presentation-runtime-react-native -> @contractspec/lib.presentation-runtime-react","Initializes or merges turbopack.resolveExtensions with a web-first extension list"]},{title:"What Metro remaps",items:["@contractspec/lib.ui-kit-web/ui/* -> @contractspec/lib.ui-kit/ui/* on ios/android/native/mobile","Root @contractspec/lib.presentation-runtime-react -> @contractspec/lib.presentation-runtime-react-native","Enables package exports and expands platform resolution ordering"]}],Kl=["Set gap, align, justify, and wrap explicitly in shared code because defaults are not identical between web and native.","Shared-safe subset: VStack, HStack, and Box with className, gap, align, justify, and wrap.","Web-only feature: as lets stack primitives emit semantic elements such as section, header, main, or article.","Native-only extras: spacing, width, and padding exist on the native stack primitives and should stay out of shared renderer code.","HStack and Box reverse-wrap tokens differ: wrapReverse on web, reverse on native. Prefer nowrap or wrap in shared code.","Box defaults to nowrap on web and wrap on native, so shared code should set wrap intentionally."],Ql=["withPresentationNextAliases no longer exists. Use withPresentationTurbopackAliases for the default Next.js path or withPresentationWebpackAliases for explicit webpack fallback.","Prefer root runtime imports when alias helpers matter. Metro remaps the root @contractspec/lib.presentation-runtime-react package, not arbitrary deep hook subpaths.","Metro only rewrites @contractspec/lib.ui-kit-web/ui/* imports. Router-specific web packages and other web-only helpers still need platform-aware imports.","presentation-runtime-core is headless. It owns models and config helpers, not rendered React components.","design-system compatibility comes from paired .tsx / .native.tsx implementations and token helpers such as withPlatformUI and mapTokensForPlatform.","Form controls should come from @contractspec/lib.design-system when product code needs ThemeSpec or TranslationSpec support.","Stack primitives are similar across platforms, but the prop surface is not identical. Stay inside the common subset for shared renderers.","Alias helpers solve module resolution only. They do not replace app-level monorepo watchFolders, Expo Router setup, or other Next configuration."],Yl="Copy these markdown snippets into your own AGENTS.md, LLM guide, README, or engineering playbook when you want to enforce the same cross-surface rules across customer projects.",Jl=`import { withPresentationTurbopackAliases } from '@contractspec/lib.presentation-runtime-core';
|
|
3677
3677
|
|
|
3678
3678
|
/** @type {import('next').NextConfig} */
|
|
3679
3679
|
const nextConfig = withPresentationTurbopackAliases({
|
|
@@ -3684,14 +3684,14 @@ const nextConfig = withPresentationTurbopackAliases({
|
|
|
3684
3684
|
},
|
|
3685
3685
|
});
|
|
3686
3686
|
|
|
3687
|
-
export default nextConfig;`,
|
|
3687
|
+
export default nextConfig;`,Zl=`import { withPresentationWebpackAliases } from '@contractspec/lib.presentation-runtime-core';
|
|
3688
3688
|
|
|
3689
3689
|
/** @type {import('next').NextConfig} */
|
|
3690
3690
|
const nextConfig = {
|
|
3691
3691
|
webpack: (config) => withPresentationWebpackAliases(config),
|
|
3692
3692
|
};
|
|
3693
3693
|
|
|
3694
|
-
export default nextConfig
|
|
3694
|
+
export default nextConfig;`,$l=`const { getDefaultConfig } = require('expo/metro-config');
|
|
3695
3695
|
const {
|
|
3696
3696
|
withPresentationMetroAliases,
|
|
3697
3697
|
} = require('@contractspec/lib.presentation-runtime-core');
|
|
@@ -3699,8 +3699,8 @@ const {
|
|
|
3699
3699
|
const projectRoot = __dirname;
|
|
3700
3700
|
const config = getDefaultConfig(projectRoot);
|
|
3701
3701
|
|
|
3702
|
-
module.exports = withPresentationMetroAliases(config);`,
|
|
3703
|
-
`),
|
|
3702
|
+
module.exports = withPresentationMetroAliases(config);`,Xl=["import {"," defaultTokens,"," mapTokensForPlatform,"," withPlatformUI,","} from '@contractspec/lib.design-system';","","const nativeTokens = mapTokensForPlatform('native', defaultTokens);","","const ui = withPlatformUI({"," tokens: defaultTokens,"," platform: 'web',","});","","// ui is a lightweight config object for design-system consumers.","// nativeTokens is the mapped token shape for a native renderer."].join(`
|
|
3703
|
+
`),xl=`import { Box, HStack, VStack } from '@contractspec/lib.ui-kit-web/ui/stack';
|
|
3704
3704
|
|
|
3705
3705
|
export function AccountSummaryHeader() {
|
|
3706
3706
|
return (
|
|
@@ -3721,7 +3721,7 @@ export function AccountSummaryHeader() {
|
|
|
3721
3721
|
// @contractspec/lib.ui-kit/ui/stack
|
|
3722
3722
|
//
|
|
3723
3723
|
// On web-only pages, VStack / HStack / Box also support:
|
|
3724
|
-
// <VStack as="section">...</VStack
|
|
3724
|
+
// <VStack as="section">...</VStack>`,jl=`import { DataTable as DesignSystemTable } from '@contractspec/lib.design-system';
|
|
3725
3725
|
import { DataTable as NativeTable } from '@contractspec/lib.ui-kit/ui/data-table';
|
|
3726
3726
|
import { DataTable as WebTable } from '@contractspec/lib.ui-kit-web/ui/data-table';
|
|
3727
3727
|
import { useContractTable } from '@contractspec/lib.presentation-runtime-react';
|
|
@@ -3757,7 +3757,7 @@ export function ProductAccounts({ controller }) {
|
|
|
3757
3757
|
}
|
|
3758
3758
|
|
|
3759
3759
|
// If the table is spec-driven instead of hand-authored,
|
|
3760
|
-
// swap useContractTable for useDataViewTable.`,Xl="# Cross-Surface Rendering Policy\n\n- Import runtime bundler helpers from `@contractspec/lib.presentation-runtime-core` root only.\n- Use `withPresentationTurbopackAliases` for default Next.js projects.\n- Use `withPresentationWebpackAliases` only when the app explicitly opts into webpack.\n- Use `withPresentationMetroAliases` for Expo and Metro builds.\n- Prefer `@contractspec/lib.design-system` for shared product-facing surfaces.\n- Use design-system controls when a field must respect ThemeSpec component variants or TranslationSpec messages.\n- Use `@contractspec/lib.ui-kit-web` only for web-specific primitive lanes.\n- Use `@contractspec/lib.ui-kit` only for native-specific primitive lanes.\n- Keep shared layout code inside the common `VStack` / `HStack` / `Box` subset.\n- Do not use removed `withPresentationNextAliases`.\n- Treat `.tsx` / `.mobile.tsx` pairs as the standard design-system compatibility boundary.",xl="# Cross-Surface Rendering Checklist\n\n1. Configure the bundler aliases before sharing any UI code.\n2. Choose the controller layer:\n - use `useContractTable` for app-owned rows and columns\n - use `useDataViewTable` for DataViewSpec-driven tables\n3. Choose the renderer lane:\n - web primitive: `@contractspec/lib.ui-kit-web`\n - native primitive: `@contractspec/lib.ui-kit`\n - shared product surface: `@contractspec/lib.design-system`\n4. Verify mirrored `.tsx` / `.mobile.tsx` implementations where the design-system owns the surface.\n5. Wrap product surfaces in `DesignSystemThemeProvider` and `DesignSystemTranslationProvider` when ThemeSpec or TranslationSpec data is available.\n6. In shared layout code, set `gap`, `align`, `justify`, and `wrap` explicitly.\n7. Check docs and examples for root imports and current helper names before copying them into product code.";import{CodeBlock as jo}from"@contractspec/lib.design-system";import Sr from"@contractspec/lib.ui-link";import{ChevronRight as bf}from"lucide-react";import{jsx as C,jsxs as je}from"react/jsx-runtime";function vf(){return je("div",{className:"space-y-8",children:[je("div",{className:"space-y-4",children:[C("h1",{className:"font-bold text-4xl",children:"Cross-platform UI"}),C("p",{className:"text-lg text-muted-foreground",children:"How ContractSpec keeps React and React Native components compatible by splitting responsibility across shared runtime models, platform primitives, resolver aliases, and the composed design-system layer."})]}),je("div",{className:"space-y-4",children:[C("h2",{className:"font-bold text-2xl",children:"What cross-platform means here"}),C("p",{className:"text-muted-foreground",children:"The shared rendering story is layered: the core package owns models and resolver helpers, the React packages own hook APIs, the UI kits own raw primitives, and the design-system owns the higher-level product surfaces that pair web and mobile implementations."}),C("div",{className:"grid gap-4 md:grid-cols-2",children:Wl.map((e)=>je("div",{className:"rounded-[20px] border border-border/70 p-4",children:[C("h3",{className:"font-semibold text-base",children:e.title}),C("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:e.body})]},e.title))}),C("div",{className:"grid gap-4 md:grid-cols-3",children:_l.map((e)=>je("div",{className:"card-subtle p-4",children:[C("h3",{className:"font-semibold",children:e.title}),C("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:e.body})]},e.title))}),je("div",{className:"grid gap-4 lg:grid-cols-[1.1fr_0.9fr]",children:[C("div",{className:"grid gap-4 md:grid-cols-2",children:Gl.map((e)=>je("div",{className:"card-subtle p-4",children:[C("h3",{className:"font-semibold",children:e.title}),C("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:e.body})]},e.title))}),C(jo,{language:"typescript",filename:"design-system-platform.ts",code:Jl})]})]}),je("div",{className:"space-y-4",children:[C("h2",{className:"font-bold text-2xl",children:"Resolver and alias setup"}),je("p",{className:"text-muted-foreground",children:["Teach the bundler what “web” and “native” mean before you try to share component code. These helpers are public from the root",C("code",{children:" @contractspec/lib.presentation-runtime-core "}),"entrypoint."]}),C("div",{className:"grid gap-4 md:grid-cols-2",children:zl.map((e)=>je("div",{className:"card-subtle p-4",children:[C("h3",{className:"font-semibold",children:e.title}),C("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:e.body})]},e.title))}),je("div",{className:"grid gap-4 xl:grid-cols-3",children:[C(jo,{language:"typescript",filename:"next.config.mjs",code:Kl}),C(jo,{language:"typescript",filename:"next.config.mjs",code:Ql}),C(jo,{language:"javascript",filename:"metro.config.js",code:Yl})]})]}),je("div",{className:"space-y-4",children:[C("h2",{className:"font-bold text-2xl",children:"How the remapping works"}),C("p",{className:"text-muted-foreground",children:"The helpers are intentionally asymmetric because Turbopack patches the Next config object, Webpack mutates a resolver config, and Metro maps modules at request time for native platforms."}),C("div",{className:"grid gap-4 xl:grid-cols-3",children:ql.map((e)=>je("div",{className:"card-subtle p-4",children:[C("h3",{className:"font-semibold",children:e.title}),C("ul",{className:"mt-2 space-y-2 text-muted-foreground text-sm leading-7",children:e.items.map((t)=>C("li",{children:t},t))})]},e.title))})]}),je("div",{className:"space-y-4",children:[C("h2",{className:"font-bold text-2xl",children:"Layout primitives"}),je("p",{className:"text-muted-foreground",children:[C("code",{children:"VStack"}),", ",C("code",{children:"HStack"}),", and ",C("code",{children:"Box"})," are the closest thing to a shared layout vocabulary, but their defaults and a few props still differ across the web and native packages."]}),C("div",{className:"grid gap-4 md:grid-cols-2",children:Hl.map((e)=>C("div",{className:"card-subtle p-4 text-muted-foreground text-sm leading-7",children:e},e))}),C(jo,{language:"tsx",filename:"stack-layout.tsx",code:Zl})]}),je("div",{className:"space-y-4",children:[C("h2",{className:"font-bold text-2xl",children:"Rendering patterns"}),C("p",{className:"text-muted-foreground",children:"Keep the controller stable, then decide whether the final surface should be a raw web primitive, a raw native primitive, or a composed design-system wrapper."}),C(jo,{language:"tsx",filename:"cross-platform-rendering.tsx",code:$l}),je("div",{className:"card-subtle p-4 text-muted-foreground text-sm leading-7",children:["For higher-level shared rendering, use the design-system surfaces that already ship paired implementations such as"," ",C("code",{children:"DataViewRenderer"}),", ",C("code",{children:"ListTablePage"}),", and"," ",C("code",{children:"DataTable"}),". The web and mobile files stay separate inside the package while your app imports one design-system boundary."]})]}),je("div",{className:"space-y-4",children:[C("h2",{className:"font-bold text-2xl",children:"Gotchas and boundaries"}),C("ul",{className:"space-y-2 text-muted-foreground leading-7",children:Vl.map((e)=>C("li",{children:e},e))})]}),je("div",{className:"space-y-4",children:[C("h2",{className:"font-bold text-2xl",children:"Customer markdown kit"}),C("p",{className:"text-muted-foreground",children:Fl}),je("div",{className:"grid gap-4 xl:grid-cols-2",children:[C(jo,{language:"markdown",filename:"cross-surface-policy.md",code:Xl}),C(jo,{language:"markdown",filename:"cross-surface-checklist.md",code:xl})]})]}),je("div",{className:"flex flex-wrap items-center gap-3 pt-2",children:[C(Sr,{href:"/docs/libraries/runtime",className:"btn-ghost",children:"Runtime libraries"}),C(Sr,{href:"/docs/libraries/ui-kit",className:"btn-ghost",children:"UI Kit"}),C(Sr,{href:"/docs/libraries/ui-kit-web",className:"btn-ghost",children:"UI Kit Web"}),je(Sr,{href:"/docs/libraries/design-system",className:"btn-primary",children:["Design System ",C(bf,{size:16})]})]})]})}import{CodeBlock as Nf}from"@contractspec/lib.design-system";import jl from"@contractspec/lib.ui-link";import{ChevronRight as wf}from"lucide-react";import{jsx as _t,jsxs as zt}from"react/jsx-runtime";function kf(){return zt("div",{className:"space-y-8",children:[zt("div",{className:"space-y-4",children:[_t("h1",{className:"font-bold text-4xl",children:"Data & Backend"}),_t("p",{className:"text-muted-foreground",children:"A collection of robust, platform-agnostic libraries for building the backend infrastructure of your LSSM applications."})]}),zt("div",{className:"space-y-4",children:[_t("h2",{className:"font-bold text-2xl",children:"Libraries"}),zt("div",{className:"space-y-6",children:[zt("div",{className:"card-subtle p-6",children:[_t("h3",{className:"font-bold text-lg",children:"@contractspec/app.cli-database"}),zt("p",{className:"mt-2 text-muted-foreground text-sm",children:[_t("strong",{children:"Prisma Wrapper & CLI"}),". Provides a unified way to manage database schemas, migrations, and clients. Includes seeders and factory patterns for testing."]})]}),zt("div",{className:"card-subtle p-6",children:[_t("h3",{className:"font-bold text-lg",children:"@contractspec/lib.bus"}),zt("p",{className:"mt-2 text-muted-foreground text-sm",children:[_t("strong",{children:"Type-Safe Event Bus"}),". Decouple your architecture with typed events. Supports in-memory dispatch for monoliths and can be extended for distributed message queues (Redis, SQS)."]})]}),zt("div",{className:"card-subtle p-6",children:[_t("h3",{className:"font-bold text-lg",children:"@contractspec/lib.logger"}),zt("p",{className:"mt-2 text-muted-foreground text-sm",children:[_t("strong",{children:"High-Performance Logging"}),". Optimized for Bun and structured JSON output. Includes plugins for ElysiaJS to log HTTP requests automatically."]})]}),zt("div",{className:"card-subtle p-6",children:[_t("h3",{className:"font-bold text-lg",children:"@contractspec/lib.error"}),zt("p",{className:"mt-2 text-muted-foreground text-sm",children:[_t("strong",{children:"Standardized Errors"}),". Use `AppError` with standard codes (NOT_FOUND, UNAUTHORIZED) to ensure consistent HTTP responses and error handling across services."]})]}),zt("div",{className:"card-subtle p-6",children:[_t("h3",{className:"font-bold text-lg",children:"@contractspec/lib.exporter"}),zt("p",{className:"mt-2 text-muted-foreground text-sm",children:[_t("strong",{children:"Data Export"}),". Generate CSV and XML files from your data. Platform-agnostic and streaming-friendly."]})]})]})]}),zt("div",{className:"space-y-4",children:[_t("h2",{className:"font-bold text-2xl",children:"Example: Unified Backend Flow"}),_t(Nf,{language:"typescript",code:`import { logger } from '@contractspec/lib.logger';
|
|
3760
|
+
// swap useContractTable for useDataViewTable.`,ed="# Cross-Surface Rendering Policy\n\n- Import runtime bundler helpers from `@contractspec/lib.presentation-runtime-core` root only.\n- Use `withPresentationTurbopackAliases` for default Next.js projects.\n- Use `withPresentationWebpackAliases` only when the app explicitly opts into webpack.\n- Use `withPresentationMetroAliases` for Expo and Metro builds.\n- Prefer `@contractspec/lib.design-system` for shared product-facing surfaces.\n- Use design-system controls when a field must respect ThemeSpec component variants or TranslationSpec messages.\n- Use `@contractspec/lib.ui-kit-web` only for web-specific primitive lanes.\n- Use `@contractspec/lib.ui-kit` only for native-specific primitive lanes.\n- Keep shared layout code inside the common `VStack` / `HStack` / `Box` subset.\n- Do not use removed `withPresentationNextAliases`.\n- Treat `.tsx` / `.native.tsx` pairs as the standard design-system compatibility boundary.",td="# Cross-Surface Rendering Checklist\n\n1. Configure the bundler aliases before sharing any UI code.\n2. Choose the controller layer:\n - use `useContractTable` for app-owned rows and columns\n - use `useDataViewTable` for DataViewSpec-driven tables\n3. Choose the renderer lane:\n - web primitive: `@contractspec/lib.ui-kit-web`\n - native primitive: `@contractspec/lib.ui-kit`\n - shared product surface: `@contractspec/lib.design-system`\n4. Verify mirrored `.tsx` / `.native.tsx` implementations where the design-system owns the surface.\n5. Wrap product surfaces in `DesignSystemThemeProvider` and `DesignSystemTranslationProvider` when ThemeSpec or TranslationSpec data is available.\n6. In shared layout code, set `gap`, `align`, `justify`, and `wrap` explicitly.\n7. Check docs and examples for root imports and current helper names before copying them into product code.";import{CodeBlock as jo}from"@contractspec/lib.design-system";import Sr from"@contractspec/lib.ui-link";import{ChevronRight as Sf}from"lucide-react";import{jsx as C,jsxs as je}from"react/jsx-runtime";function Cf(){return je("div",{className:"space-y-8",children:[je("div",{className:"space-y-4",children:[C("h1",{className:"font-bold text-4xl",children:"Cross-platform UI"}),C("p",{className:"text-lg text-muted-foreground",children:"How ContractSpec keeps React and React Native components compatible by splitting responsibility across shared runtime models, platform primitives, resolver aliases, and the composed design-system layer."})]}),je("div",{className:"space-y-4",children:[C("h2",{className:"font-bold text-2xl",children:"What cross-platform means here"}),C("p",{className:"text-muted-foreground",children:"The shared rendering story is layered: the core package owns models and resolver helpers, the React packages own hook APIs, the UI kits own raw primitives, and the design-system owns the higher-level product surfaces that pair web and mobile implementations."}),C("div",{className:"grid gap-4 md:grid-cols-2",children:Gl.map((e)=>je("div",{className:"rounded-[20px] border border-border/70 p-4",children:[C("h3",{className:"font-semibold text-base",children:e.title}),C("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:e.body})]},e.title))}),C("div",{className:"grid gap-4 md:grid-cols-3",children:ql.map((e)=>je("div",{className:"card-subtle p-4",children:[C("h3",{className:"font-semibold",children:e.title}),C("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:e.body})]},e.title))}),je("div",{className:"grid gap-4 lg:grid-cols-[1.1fr_0.9fr]",children:[C("div",{className:"grid gap-4 md:grid-cols-2",children:Vl.map((e)=>je("div",{className:"card-subtle p-4",children:[C("h3",{className:"font-semibold",children:e.title}),C("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:e.body})]},e.title))}),C(jo,{language:"typescript",filename:"design-system-platform.ts",code:Xl})]})]}),je("div",{className:"space-y-4",children:[C("h2",{className:"font-bold text-2xl",children:"Resolver and alias setup"}),je("p",{className:"text-muted-foreground",children:["Teach the bundler what “web” and “native” mean before you try to share component code. These helpers are public from the root",C("code",{children:" @contractspec/lib.presentation-runtime-core "}),"entrypoint."]}),C("div",{className:"grid gap-4 md:grid-cols-2",children:Hl.map((e)=>je("div",{className:"card-subtle p-4",children:[C("h3",{className:"font-semibold",children:e.title}),C("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:e.body})]},e.title))}),je("div",{className:"grid gap-4 xl:grid-cols-3",children:[C(jo,{language:"typescript",filename:"next.config.mjs",code:Jl}),C(jo,{language:"typescript",filename:"next.config.mjs",code:Zl}),C(jo,{language:"javascript",filename:"metro.config.js",code:$l})]})]}),je("div",{className:"space-y-4",children:[C("h2",{className:"font-bold text-2xl",children:"How the remapping works"}),C("p",{className:"text-muted-foreground",children:"The helpers are intentionally asymmetric because Turbopack patches the Next config object, Webpack mutates a resolver config, and Metro maps modules at request time for native platforms."}),C("div",{className:"grid gap-4 xl:grid-cols-3",children:Fl.map((e)=>je("div",{className:"card-subtle p-4",children:[C("h3",{className:"font-semibold",children:e.title}),C("ul",{className:"mt-2 space-y-2 text-muted-foreground text-sm leading-7",children:e.items.map((t)=>C("li",{children:t},t))})]},e.title))})]}),je("div",{className:"space-y-4",children:[C("h2",{className:"font-bold text-2xl",children:"Layout primitives"}),je("p",{className:"text-muted-foreground",children:[C("code",{children:"VStack"}),", ",C("code",{children:"HStack"}),", and ",C("code",{children:"Box"})," are the closest thing to a shared layout vocabulary, but their defaults and a few props still differ across the web and native packages."]}),C("div",{className:"grid gap-4 md:grid-cols-2",children:Kl.map((e)=>C("div",{className:"card-subtle p-4 text-muted-foreground text-sm leading-7",children:e},e))}),C(jo,{language:"tsx",filename:"stack-layout.tsx",code:xl})]}),je("div",{className:"space-y-4",children:[C("h2",{className:"font-bold text-2xl",children:"Rendering patterns"}),C("p",{className:"text-muted-foreground",children:"Keep the controller stable, then decide whether the final surface should be a raw web primitive, a raw native primitive, or a composed design-system wrapper."}),C(jo,{language:"tsx",filename:"cross-platform-rendering.tsx",code:jl}),je("div",{className:"card-subtle p-4 text-muted-foreground text-sm leading-7",children:["For higher-level shared rendering, use the design-system surfaces that already ship paired implementations such as"," ",C("code",{children:"DataViewRenderer"}),", ",C("code",{children:"ListTablePage"}),", and"," ",C("code",{children:"DataTable"}),". The web and mobile files stay separate inside the package while your app imports one design-system boundary."]})]}),je("div",{className:"space-y-4",children:[C("h2",{className:"font-bold text-2xl",children:"Gotchas and boundaries"}),C("ul",{className:"space-y-2 text-muted-foreground leading-7",children:Ql.map((e)=>C("li",{children:e},e))})]}),je("div",{className:"space-y-4",children:[C("h2",{className:"font-bold text-2xl",children:"Customer markdown kit"}),C("p",{className:"text-muted-foreground",children:Yl}),je("div",{className:"grid gap-4 xl:grid-cols-2",children:[C(jo,{language:"markdown",filename:"cross-surface-policy.md",code:ed}),C(jo,{language:"markdown",filename:"cross-surface-checklist.md",code:td})]})]}),je("div",{className:"flex flex-wrap items-center gap-3 pt-2",children:[C(Sr,{href:"/docs/libraries/runtime",className:"btn-ghost",children:"Runtime libraries"}),C(Sr,{href:"/docs/libraries/ui-kit",className:"btn-ghost",children:"UI Kit"}),C(Sr,{href:"/docs/libraries/ui-kit-web",className:"btn-ghost",children:"UI Kit Web"}),je(Sr,{href:"/docs/libraries/design-system",className:"btn-primary",children:["Design System ",C(Sf,{size:16})]})]})]})}import{CodeBlock as If}from"@contractspec/lib.design-system";import ad from"@contractspec/lib.ui-link";import{ChevronRight as Pf}from"lucide-react";import{jsx as _t,jsxs as zt}from"react/jsx-runtime";function Tf(){return zt("div",{className:"space-y-8",children:[zt("div",{className:"space-y-4",children:[_t("h1",{className:"font-bold text-4xl",children:"Data & Backend"}),_t("p",{className:"text-muted-foreground",children:"A collection of robust, platform-agnostic libraries for building the backend infrastructure of your LSSM applications."})]}),zt("div",{className:"space-y-4",children:[_t("h2",{className:"font-bold text-2xl",children:"Libraries"}),zt("div",{className:"space-y-6",children:[zt("div",{className:"card-subtle p-6",children:[_t("h3",{className:"font-bold text-lg",children:"@contractspec/app.cli-database"}),zt("p",{className:"mt-2 text-muted-foreground text-sm",children:[_t("strong",{children:"Prisma Wrapper & CLI"}),". Provides a unified way to manage database schemas, migrations, and clients. Includes seeders and factory patterns for testing."]})]}),zt("div",{className:"card-subtle p-6",children:[_t("h3",{className:"font-bold text-lg",children:"@contractspec/lib.bus"}),zt("p",{className:"mt-2 text-muted-foreground text-sm",children:[_t("strong",{children:"Type-Safe Event Bus"}),". Decouple your architecture with typed events. Supports in-memory dispatch for monoliths and can be extended for distributed message queues (Redis, SQS)."]})]}),zt("div",{className:"card-subtle p-6",children:[_t("h3",{className:"font-bold text-lg",children:"@contractspec/lib.logger"}),zt("p",{className:"mt-2 text-muted-foreground text-sm",children:[_t("strong",{children:"High-Performance Logging"}),". Optimized for Bun and structured JSON output. Includes plugins for ElysiaJS to log HTTP requests automatically."]})]}),zt("div",{className:"card-subtle p-6",children:[_t("h3",{className:"font-bold text-lg",children:"@contractspec/lib.error"}),zt("p",{className:"mt-2 text-muted-foreground text-sm",children:[_t("strong",{children:"Standardized Errors"}),". Use `AppError` with standard codes (NOT_FOUND, UNAUTHORIZED) to ensure consistent HTTP responses and error handling across services."]})]}),zt("div",{className:"card-subtle p-6",children:[_t("h3",{className:"font-bold text-lg",children:"@contractspec/lib.exporter"}),zt("p",{className:"mt-2 text-muted-foreground text-sm",children:[_t("strong",{children:"Data Export"}),". Generate CSV and XML files from your data. Platform-agnostic and streaming-friendly."]})]})]})]}),zt("div",{className:"space-y-4",children:[_t("h2",{className:"font-bold text-2xl",children:"Example: Unified Backend Flow"}),_t(If,{language:"typescript",code:`import { logger } from '@contractspec/lib.logger';
|
|
3761
3761
|
import { AppError } from '@contractspec/lib.error';
|
|
3762
3762
|
import { db } from '@contractspec/app.cli-database';
|
|
3763
3763
|
import { EventBus } from '@contractspec/lib.bus';
|
|
@@ -3775,7 +3775,7 @@ export async function createUser(email: string) {
|
|
|
3775
3775
|
await EventBus.publish('user.created', { userId: user.id });
|
|
3776
3776
|
|
|
3777
3777
|
return user;
|
|
3778
|
-
}`})]}),zt("div",{className:"flex items-center gap-4 pt-4",children:[zt(
|
|
3778
|
+
}`})]}),zt("div",{className:"flex items-center gap-4 pt-4",children:[zt(ad,{href:"/docs/libraries/runtime",className:"btn-primary",children:["Next: Runtime ",_t(Pf,{size:16})]}),_t(ad,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"})]})]})}import{CodeBlock as od,InstallCommand as Af}from"@contractspec/lib.design-system";import id from"@contractspec/lib.ui-link";import{ChevronRight as Rf}from"lucide-react";import{jsx as He,jsxs as $t}from"react/jsx-runtime";function Lf(){return $t("div",{className:"space-y-8",children:[$t("div",{className:"space-y-4",children:[He("h1",{className:"font-bold text-4xl",children:"DataViews Runtime Library"}),$t("p",{className:"text-lg text-muted-foreground",children:["The ",He("code",{children:"@contractspec/lib.contracts-spec/data-views"})," and"," ",He("code",{children:"@contractspec/lib.design-system"})," libraries provide the runtime logic and UI components to render DataViews in your application."]})]}),$t("div",{className:"space-y-4",children:[He("h2",{className:"font-bold text-2xl",children:"Installation"}),He(Af,{package:["@contractspec/lib.contracts-spec","@contractspec/lib.design-system"]})]}),$t("div",{className:"space-y-4",children:[He("h2",{className:"font-bold text-2xl",children:"DataViewRenderer"}),He("p",{className:"text-muted-foreground",children:"The primary component for rendering any DataView. It automatically selects the correct layout (List, Table, Grid, Detail) based on the spec."}),He(od,{language:"tsx",code:`import { DataViewRenderer } from '@contractspec/lib.design-system';
|
|
3779
3779
|
import { MyUserList } from './specs/users.data-view';
|
|
3780
3780
|
|
|
3781
3781
|
export function UserPage() {
|
|
@@ -3787,7 +3787,7 @@ export function UserPage() {
|
|
|
3787
3787
|
onPageChange={(page) => fetchPage(page)}
|
|
3788
3788
|
/>
|
|
3789
3789
|
);
|
|
3790
|
-
}`}),He("h3",{className:"font-semibold text-xl",children:"Props"}),$t("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[$t("li",{children:[He("code",{children:"spec"}),": The DataViewSpec definition."]}),$t("li",{children:[He("code",{children:"items"}),": Array of data items to render."]}),$t("li",{children:[He("code",{children:"filters"}),": Current filter state object."]}),$t("li",{children:[He("code",{children:"onFilterChange"}),": Callback when filters change."]}),$t("li",{children:[He("code",{children:"pagination"}),": Object with ",He("code",{children:"page"}),","," ",He("code",{children:"pageSize"}),", ",He("code",{children:"total"}),"."]}),$t("li",{children:[He("code",{children:"onPageChange"}),": Callback when page changes."]})]})]}),$t("div",{className:"space-y-4",children:[He("h2",{className:"font-bold text-2xl",children:"Query Generation"}),$t("p",{className:"text-muted-foreground",children:["The ",He("code",{children:"DataViewQueryGenerator"})," utility helps translate DataView parameters (filters, sorting, pagination) into query arguments for your backend."]}),He(
|
|
3790
|
+
}`}),He("h3",{className:"font-semibold text-xl",children:"Props"}),$t("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[$t("li",{children:[He("code",{children:"spec"}),": The DataViewSpec definition."]}),$t("li",{children:[He("code",{children:"items"}),": Array of data items to render."]}),$t("li",{children:[He("code",{children:"filters"}),": Current filter state object."]}),$t("li",{children:[He("code",{children:"onFilterChange"}),": Callback when filters change."]}),$t("li",{children:[He("code",{children:"pagination"}),": Object with ",He("code",{children:"page"}),","," ",He("code",{children:"pageSize"}),", ",He("code",{children:"total"}),"."]}),$t("li",{children:[He("code",{children:"onPageChange"}),": Callback when page changes."]})]})]}),$t("div",{className:"space-y-4",children:[He("h2",{className:"font-bold text-2xl",children:"Query Generation"}),$t("p",{className:"text-muted-foreground",children:["The ",He("code",{children:"DataViewQueryGenerator"})," utility helps translate DataView parameters (filters, sorting, pagination) into query arguments for your backend."]}),He(od,{language:"typescript",code:`import { DataViewQueryGenerator } from '@contractspec/lib.contracts-spec/data-views/query-generator';
|
|
3791
3791
|
|
|
3792
3792
|
const generator = new DataViewQueryGenerator(MyUserList);
|
|
3793
3793
|
const query = generator.generate({
|
|
@@ -3795,7 +3795,7 @@ const query = generator.generate({
|
|
|
3795
3795
|
filters: { role: 'admin' }
|
|
3796
3796
|
});
|
|
3797
3797
|
|
|
3798
|
-
// query.input contains { skip: 0, take: 20, role: 'admin' }`})]}),$t("div",{className:"flex items-center gap-4 pt-4",children:[He(
|
|
3798
|
+
// query.input contains { skip: 0, take: 20, role: 'admin' }`})]}),$t("div",{className:"flex items-center gap-4 pt-4",children:[He(id,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),$t(id,{href:"/docs/libraries/data-backend",className:"btn-primary",children:["Next: Data & Backend ",He(Rf,{size:16})]})]})]})}import{CodeBlock as un,InstallCommand as Df}from"@contractspec/lib.design-system";import Cr from"@contractspec/lib.ui-link";import{ChevronRight as Ef}from"lucide-react";import{jsx as O,jsxs as ne}from"react/jsx-runtime";var Of=`import { Button, DataTable } from '@contractspec/lib.design-system';
|
|
3799
3799
|
import { useContractTable } from '@contractspec/lib.presentation-runtime-react';
|
|
3800
3800
|
|
|
3801
3801
|
import { SHOWCASE_ROWS } from '@contractspec/example.data-grid-showcase/ui/data-grid-showcase.data';
|
|
@@ -3843,7 +3843,7 @@ export function AccountHealthTable() {
|
|
|
3843
3843
|
footer={\`Page \${controller.pageIndex + 1} of \${controller.pageCount}\`}
|
|
3844
3844
|
/>
|
|
3845
3845
|
);
|
|
3846
|
-
}`,
|
|
3846
|
+
}`,Bf=`import {
|
|
3847
3847
|
DesignSystemThemeProvider,
|
|
3848
3848
|
resolveThemeModeTokens,
|
|
3849
3849
|
themeSpecToCssVariables,
|
|
@@ -3873,13 +3873,13 @@ export function TenantSurface({ children }: { children: React.ReactNode }) {
|
|
|
3873
3873
|
{children}
|
|
3874
3874
|
</DesignSystemThemeProvider>
|
|
3875
3875
|
);
|
|
3876
|
-
}`,
|
|
3876
|
+
}`,Mf=`import { themeSpecToTailwindPreset } from '@contractspec/lib.design-system/theme';
|
|
3877
3877
|
import { Select } from '@contractspec/lib.design-system/controls';
|
|
3878
3878
|
import { FormDialog } from '@contractspec/lib.design-system/forms';
|
|
3879
3879
|
import { HStack } from '@contractspec/lib.design-system/layout';
|
|
3880
3880
|
|
|
3881
3881
|
// Root imports remain supported:
|
|
3882
|
-
import { Button, DataTable } from '@contractspec/lib.design-system';`;function
|
|
3882
|
+
import { Button, DataTable } from '@contractspec/lib.design-system';`;function Uf(){return ne("div",{className:"space-y-8",children:[ne("div",{className:"space-y-4",children:[O("h1",{className:"font-bold text-4xl",children:"@contractspec/lib.design-system"}),ne("p",{className:"text-muted-foreground",children:["High-level design system components, patterns, and layouts for LSSM applications. Built on top of ",O("code",{children:"@contractspec/lib.ui-kit"}),"."]})]}),ne("div",{className:"space-y-4",children:[O("h2",{className:"font-bold text-2xl",children:"Installation"}),O(Df,{package:"@contractspec/lib.design-system"})]}),ne("div",{className:"space-y-4",children:[O("h2",{className:"font-bold text-2xl",children:"What It Provides"}),ne("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[ne("li",{children:[O("strong",{children:"Composite Components"}),": Molecules and Organisms that solve common UI problems"]}),ne("li",{children:[O("strong",{children:"Layouts"}),": Ready-to-use page structures for dashboards, marketing sites, and lists"]}),ne("li",{children:[O("strong",{children:"Data Views"}),": Standardized renderers for lists, tables, and detail views"]}),ne("li",{children:[O("strong",{children:"Forms"}),": Zod-integrated form layouts and components"]}),ne("li",{children:[O("strong",{children:"Code Display"}),": Syntax-highlighted code blocks with package manager tabs"]}),ne("li",{children:[O("strong",{children:"Platform Utilities"}),": Hooks for responsive and adaptive design"]}),ne("li",{children:[O("strong",{children:"Theme Bridge"}),": ThemeSpec to Tailwind variables, presets, CSS text, and runtime light/dark mode"]}),ne("li",{children:[O("strong",{children:"Legal Templates"}),": Compliant templates for Terms, Privacy, and GDPR"]})]})]}),ne("div",{className:"space-y-4",children:[O("h2",{className:"font-bold text-2xl",children:"ThemeSpec to Tailwind"}),ne("p",{className:"text-muted-foreground",children:["The theme bridge keeps ",O("code",{children:"ThemeSpec"})," as the source of truth and exposes no-generation Tailwind helpers, optional CSS text serialization, runtime CSS variables, light/dark modes, and OKLCH color pass-through."]}),O(un,{language:"tsx",code:Bf})]}),ne("div",{className:"space-y-4",children:[O("h2",{className:"font-bold text-2xl",children:"Focused import surfaces"}),O("p",{className:"text-muted-foreground",children:"New code can use focused subpaths for theme, controls, forms, and layout while existing root imports remain compatible."}),O(un,{language:"tsx",code:Mf})]}),ne("div",{className:"space-y-4",children:[O("h2",{className:"font-bold text-2xl",children:"Data table example"}),ne("p",{className:"text-muted-foreground",children:["This is the composed lane from the canonical"," ",O(Cr,{href:"/docs/examples/data-grid-showcase",className:"text-[color:var(--rust)] underline underline-offset-4",children:"Data Grid Showcase"}),". The design-system wrapper owns title, description, header actions, and the opinionated card shell on top of the raw web primitive."]}),O(un,{language:"tsx",code:Of})]}),ne("div",{className:"space-y-4",children:[O("h2",{className:"font-bold text-2xl",children:"Key Exports"}),ne("div",{className:"grid gap-4 md:grid-cols-2",children:[ne("div",{className:"card-subtle p-4",children:[O("h3",{className:"mb-2 font-semibold",children:"Organisms"}),ne("ul",{className:"space-y-1 text-muted-foreground text-sm",children:[O("li",{children:"AppLayout, AppHeader, AppSidebar"}),O("li",{children:"MarketingLayout, HeroSection"}),O("li",{children:"ListCardPage, ListTablePage"})]})]}),ne("div",{className:"card-subtle p-4",children:[O("h3",{className:"mb-2 font-semibold",children:"Data & Forms"}),ne("ul",{className:"space-y-1 text-muted-foreground text-sm",children:[O("li",{children:"DataTable"}),O("li",{children:"DataViewTable"}),O("li",{children:"DataViewRenderer"}),O("li",{children:"ZodForm"}),O("li",{children:"FormLayout, FormDialog"})]})]}),ne("div",{className:"card-subtle p-4",children:[O("h3",{className:"mb-2 font-semibold",children:"Code Display"}),ne("ul",{className:"space-y-1 text-muted-foreground text-sm",children:[O("li",{children:"CodeBlock (syntax highlighting)"}),O("li",{children:"CommandTabs (package manager tabs)"}),O("li",{children:"InstallCommand (convenience wrapper)"}),O("li",{children:"CopyButton"})]})]}),ne("div",{className:"card-subtle p-4",children:[O("h3",{className:"mb-2 font-semibold",children:"Providers"}),O("ul",{className:"space-y-1 text-muted-foreground text-sm",children:O("li",{children:"PackageManagerProvider"})})]})]})]}),ne("div",{className:"card-subtle space-y-3 p-6",children:[O("h2",{className:"font-bold text-2xl",children:"Where this layer fits"}),ne("p",{className:"text-muted-foreground",children:["Read"," ",O(Cr,{href:"/docs/libraries/cross-platform-ui",className:"text-[color:var(--rust)] underline underline-offset-4",children:"Cross-platform UI"})," ","for the package split between shared runtime controllers, leaf platform primitives, and this composed design-system layer."]})]}),ne("div",{className:"flex items-center gap-4 pt-4",children:[O(Cr,{href:"/docs/libraries/ui-kit-web",className:"btn-ghost",children:"Previous: UI Kit Web"}),ne(Cr,{href:"/docs/libraries/accessibility",className:"btn-primary",children:["Next: Accessibility ",O(Ef,{size:16})]})]})]})}import{CodeBlock as gn,InstallCommand as Wf}from"@contractspec/lib.design-system";import rd from"@contractspec/lib.ui-link";import{ChevronRight as _f}from"lucide-react";import{jsx as ma,jsxs as Bo}from"react/jsx-runtime";function zf(){return Bo("div",{className:"space-y-8",children:[Bo("div",{className:"space-y-4",children:[ma("h1",{className:"font-bold text-4xl",children:"@contractspec/lib.evolution"}),ma("p",{className:"text-lg text-muted-foreground",children:"Analyze production telemetry, surface anomalies, and turn them into AI-reviewed spec proposals that can be approved, rolled out, or reverted."})]}),Bo("div",{className:"space-y-4",children:[ma("h2",{className:"font-bold text-2xl",children:"Installation"}),ma(Wf,{package:"@contractspec/lib.evolution"})]}),Bo("div",{className:"space-y-3",children:[ma("h2",{className:"font-bold text-2xl",children:"From telemetry to intent"}),ma(gn,{language:"typescript",code:`import { SpecAnalyzer } from '@contractspec/lib.evolution/analyzer';
|
|
3883
3883
|
import { EvolutionPipeline } from '@contractspec/lib.observability';
|
|
3884
3884
|
|
|
3885
3885
|
const analyzer = new SpecAnalyzer();
|
|
@@ -3894,7 +3894,7 @@ pipeline.ingest({
|
|
|
3894
3894
|
success: false,
|
|
3895
3895
|
timestamp: new Date(),
|
|
3896
3896
|
errorCode: 'VALIDATION_FAILED',
|
|
3897
|
-
});`})]}),Bo("div",{className:"space-y-3",children:[ma("h2",{className:"font-bold text-2xl",children:"Generate & approve suggestions"}),ma(
|
|
3897
|
+
});`})]}),Bo("div",{className:"space-y-3",children:[ma("h2",{className:"font-bold text-2xl",children:"Generate & approve suggestions"}),ma(gn,{language:"typescript",code:`import {
|
|
3898
3898
|
SpecGenerator,
|
|
3899
3899
|
SpecSuggestionOrchestrator,
|
|
3900
3900
|
InMemorySpecSuggestionRepository,
|
|
@@ -3908,7 +3908,7 @@ const suggestion = generator.generateFromIntent(intentPattern, {
|
|
|
3908
3908
|
summary: 'Add PO number requirement for acme.corp',
|
|
3909
3909
|
});
|
|
3910
3910
|
|
|
3911
|
-
await orchestrator.submit(suggestion, sessionState);`})]}),Bo("div",{className:"space-y-3",children:[ma("h2",{className:"font-bold text-2xl",children:"Write approved specs back to git"}),ma(
|
|
3911
|
+
await orchestrator.submit(suggestion, sessionState);`})]}),Bo("div",{className:"space-y-3",children:[ma("h2",{className:"font-bold text-2xl",children:"Write approved specs back to git"}),ma(gn,{language:"typescript",code:`import { FileSystemSuggestionWriter } from '@contractspec/lib.evolution/approval';
|
|
3912
3912
|
|
|
3913
3913
|
const writer = new FileSystemSuggestionWriter({
|
|
3914
3914
|
outputDir:
|
|
@@ -3919,7 +3919,7 @@ await writer.write({
|
|
|
3919
3919
|
...suggestion,
|
|
3920
3920
|
status: 'approved',
|
|
3921
3921
|
approvals: { reviewer: 'ops@contractspec', decidedAt: new Date() },
|
|
3922
|
-
});`})]}),ma("div",{className:"grid gap-4 md:grid-cols-2",children:[{title:"Approvals by default",description:"Every suggestion flows through @contractspec/lib.ai-agent's ApprovalWorkflow. Tune auto-approval thresholds per environment."},{title:"Pluggable storage",description:"Use the Prisma repository in production, in-memory for tests, or stream serialized suggestions into your own queue."}].map((e)=>Bo("div",{className:"card-subtle space-y-2 p-4",children:[ma("h3",{className:"font-semibold text-lg",children:e.title}),ma("p",{className:"text-muted-foreground text-sm",children:e.description})]},e.title))}),Bo("div",{className:"flex items-center gap-4 pt-4",children:[ma(
|
|
3922
|
+
});`})]}),ma("div",{className:"grid gap-4 md:grid-cols-2",children:[{title:"Approvals by default",description:"Every suggestion flows through @contractspec/lib.ai-agent's ApprovalWorkflow. Tune auto-approval thresholds per environment."},{title:"Pluggable storage",description:"Use the Prisma repository in production, in-memory for tests, or stream serialized suggestions into your own queue."}].map((e)=>Bo("div",{className:"card-subtle space-y-2 p-4",children:[ma("h3",{className:"font-semibold text-lg",children:e.title}),ma("p",{className:"text-muted-foreground text-sm",children:e.description})]},e.title))}),Bo("div",{className:"flex items-center gap-4 pt-4",children:[ma(rd,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),Bo(rd,{href:"/docs/libraries/observability",className:"btn-primary",children:["Next: Observability ",ma(_f,{size:16})]})]})]})}import{CodeBlock as Gf,InstallCommand as qf}from"@contractspec/lib.design-system";import nd from"@contractspec/lib.ui-link";import{ChevronRight as Hf}from"lucide-react";import{jsx as ut,jsxs as Xt}from"react/jsx-runtime";function Vf(){return Xt("div",{className:"space-y-8",children:[Xt("div",{className:"space-y-4",children:[ut("h1",{className:"font-bold text-4xl",children:"GraphQL Libraries"}),ut("p",{className:"text-muted-foreground",children:"This suite of libraries enables seamless GraphQL integration, transforming your ContractSpecs into a type-safe Pothos schema, connecting with Prisma, and enabling Apollo Federation."})]}),Xt("div",{className:"space-y-4",children:[ut("h2",{className:"font-bold text-2xl",children:"Libraries"}),Xt("div",{className:"grid gap-4 md:grid-cols-1",children:[Xt("div",{className:"card-subtle p-6",children:[ut("h3",{className:"font-bold text-lg",children:"@contractspec/lib.graphql-core"}),ut("p",{className:"mt-2 text-muted-foreground text-sm",children:"The foundation. Provides a configured Pothos builder, common scalars (JSON, DateTime), and utilities for mapping ContractSpec I/O to Pothos types."})]}),Xt("div",{className:"card-subtle p-6",children:[ut("h3",{className:"font-bold text-lg",children:"@contractspec/lib.graphql-prisma"}),ut("p",{className:"mt-2 text-muted-foreground text-sm",children:"Connects Pothos to Prisma. Automatically generates GraphQL types from your Prisma schema and optimizes queries to prevent N+1 issues."})]}),Xt("div",{className:"card-subtle p-6",children:[ut("h3",{className:"font-bold text-lg",children:"@contractspec/lib.graphql-federation"}),ut("p",{className:"mt-2 text-muted-foreground text-sm",children:"Adds Apollo Federation V2 support. Allows your subgraph to define keys and entities, making it ready for a supergraph."})]})]})]}),Xt("div",{className:"space-y-4",children:[ut("h2",{className:"font-bold text-2xl",children:"Installation"}),ut(qf,{package:["@contractspec/lib.graphql-core","@contractspec/lib.graphql-prisma","@contractspec/lib.graphql-federation"]})]}),Xt("div",{className:"space-y-4",children:[ut("h2",{className:"font-bold text-2xl",children:"Usage: Building a Schema"}),ut("p",{className:"text-muted-foreground",children:"Here's how to assemble a federated GraphQL schema from your specs:"}),ut(Gf,{language:"typescript",code:`import { builder } from '@contractspec/lib.graphql-core';
|
|
3923
3923
|
import { registerContractsOnBuilder } from '@contractspec/lib.contracts-runtime-server-graphql/graphql-pothos';
|
|
3924
3924
|
import { OperationSpecRegistry } from '@contractspec/lib.contracts-spec';
|
|
3925
3925
|
import { MySpecs } from './specs';
|
|
@@ -3933,7 +3933,7 @@ registerContractsOnBuilder(builder, registry);
|
|
|
3933
3933
|
|
|
3934
3934
|
// 3. Build and print schema
|
|
3935
3935
|
const schema = builder.toSchema();
|
|
3936
|
-
console.log(printSchema(schema));`})]}),Xt("div",{className:"space-y-4",children:[ut("h2",{className:"font-bold text-2xl",children:"Features"}),Xt("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Xt("li",{children:[ut("strong",{children:"Code-First"}),": Define schema in TypeScript (Pothos), get SDL as artifact."]}),Xt("li",{children:[ut("strong",{children:"Spec Integration"}),": `registerContractsOnBuilder` automatically converts Command/Query specs into Mutations/Queries."]}),Xt("li",{children:[ut("strong",{children:"Federation Ready"}),": Just add `provider: 'federation'` to your config."]})]})]}),Xt("div",{className:"flex items-center gap-4 pt-4",children:[Xt(
|
|
3936
|
+
console.log(printSchema(schema));`})]}),Xt("div",{className:"space-y-4",children:[ut("h2",{className:"font-bold text-2xl",children:"Features"}),Xt("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Xt("li",{children:[ut("strong",{children:"Code-First"}),": Define schema in TypeScript (Pothos), get SDL as artifact."]}),Xt("li",{children:[ut("strong",{children:"Spec Integration"}),": `registerContractsOnBuilder` automatically converts Command/Query specs into Mutations/Queries."]}),Xt("li",{children:[ut("strong",{children:"Federation Ready"}),": Just add `provider: 'federation'` to your config."]})]})]}),Xt("div",{className:"flex items-center gap-4 pt-4",children:[Xt(nd,{href:"/docs/libraries/data-backend",className:"btn-primary",children:["Next: Data & Backend ",ut(Hf,{size:16})]}),ut(nd,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"})]})]})}import{CodeBlock as cd,InstallCommand as Ff}from"@contractspec/lib.design-system";import ld from"@contractspec/lib.ui-link";import{ChevronRight as Kf}from"lucide-react";import{jsx as wo,jsxs as pi}from"react/jsx-runtime";function Qf(){return pi("div",{className:"space-y-8",children:[pi("div",{className:"space-y-4",children:[wo("h1",{className:"font-bold text-4xl",children:"@contractspec/lib.growth"}),wo("p",{className:"text-lg text-muted-foreground",children:"Launch experiments without third-party SDKs. Register variants, assign users deterministically, track exposures, and compute significance."})]}),pi("div",{className:"space-y-4",children:[wo("h2",{className:"font-bold text-2xl",children:"Installation"}),wo(Ff,{package:"@contractspec/lib.growth"})]}),pi("div",{className:"space-y-3",children:[wo("h2",{className:"font-bold text-2xl",children:"Register + assign"}),wo(cd,{language:"typescript",code:`import { ExperimentRegistry, ExperimentRunner } from '@contractspec/lib.growth/experiments';
|
|
3937
3937
|
|
|
3938
3938
|
const registry = new ExperimentRegistry().register({
|
|
3939
3939
|
key: 'pricing.cta',
|
|
@@ -3947,7 +3947,7 @@ const registry = new ExperimentRegistry().register({
|
|
|
3947
3947
|
});
|
|
3948
3948
|
|
|
3949
3949
|
const runner = new ExperimentRunner();
|
|
3950
|
-
const assignment = runner.assign(registry.get('pricing.cta')!, 'user_123');`})]}),pi("div",{className:"space-y-3",children:[wo("h2",{className:"font-bold text-2xl",children:"Track + analyze"}),wo(
|
|
3950
|
+
const assignment = runner.assign(registry.get('pricing.cta')!, 'user_123');`})]}),pi("div",{className:"space-y-3",children:[wo("h2",{className:"font-bold text-2xl",children:"Track + analyze"}),wo(cd,{language:"typescript",code:`import { ExperimentTracker } from '@contractspec/lib.growth/tracker';
|
|
3951
3951
|
import { StatsEngine } from '@contractspec/lib.growth/stats';
|
|
3952
3952
|
|
|
3953
3953
|
const tracker = new ExperimentTracker(new InMemoryTrackerStore());
|
|
@@ -3963,11 +3963,11 @@ await tracker.recordSample({
|
|
|
3963
3963
|
const stats = new StatsEngine().summarize(
|
|
3964
3964
|
await tracker.getSamples(assignment.experimentKey, 'demo_booked'),
|
|
3965
3965
|
'demo_booked'
|
|
3966
|
-
);`})]}),pi("div",{className:"flex items-center gap-4 pt-4",children:[wo(
|
|
3966
|
+
);`})]}),pi("div",{className:"flex items-center gap-4 pt-4",children:[wo(ld,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),pi(ld,{href:"/docs/libraries/analytics",className:"btn-primary",children:["Next: Analytics ",wo(Kf,{size:16})]})]})]})}import{CodeBlock as dd,InstallCommand as Yf}from"@contractspec/lib.design-system";import sd from"@contractspec/lib.ui-link";import{ChevronRight as Jf}from"lucide-react";import{jsx as Ja,jsxs as Mo}from"react/jsx-runtime";function Zf(){return Mo("div",{className:"space-y-8",children:[Mo("div",{className:"space-y-4",children:[Ja("h1",{className:"font-bold text-4xl",children:"Multi-Tenancy Library"}),Mo("p",{className:"text-lg text-muted-foreground",children:["The ",Ja("code",{children:"@contractspec/lib.multi-tenancy"})," library provides the core building blocks for secure SaaS applications."]})]}),Mo("div",{className:"space-y-4",children:[Ja("h2",{className:"font-bold text-2xl",children:"Installation"}),Ja(Yf,{package:"@contractspec/lib.multi-tenancy"})]}),Mo("div",{className:"space-y-4",children:[Ja("h2",{className:"font-bold text-2xl",children:"Prisma RLS Middleware"}),Mo("p",{className:"text-muted-foreground",children:["Automatically injects ",Ja("code",{children:"tenantId"})," into all queries."]}),Ja(dd,{language:"typescript",code:`import { createRlsMiddleware } from '@contractspec/lib.multi-tenancy/rls';
|
|
3967
3967
|
import { prisma } from './db';
|
|
3968
3968
|
import { getTenantId } from './context';
|
|
3969
3969
|
|
|
3970
|
-
prisma.$use(createRlsMiddleware(() => getTenantId()));`})]}),Mo("div",{className:"space-y-4",children:[Ja("h2",{className:"font-bold text-2xl",children:"Provisioning Service"}),Ja("p",{className:"text-muted-foreground",children:"Automates the creation of new tenants, including database setup and default user creation."}),Ja(
|
|
3970
|
+
prisma.$use(createRlsMiddleware(() => getTenantId()));`})]}),Mo("div",{className:"space-y-4",children:[Ja("h2",{className:"font-bold text-2xl",children:"Provisioning Service"}),Ja("p",{className:"text-muted-foreground",children:"Automates the creation of new tenants, including database setup and default user creation."}),Ja(dd,{language:"typescript",code:`import { TenantProvisioningService } from '@contractspec/lib.multi-tenancy/provisioning';
|
|
3971
3971
|
|
|
3972
3972
|
const service = new TenantProvisioningService({ db: prisma });
|
|
3973
3973
|
await service.provision({
|
|
@@ -3975,7 +3975,7 @@ await service.provision({
|
|
|
3975
3975
|
name: 'Acme Corp',
|
|
3976
3976
|
slug: 'acme',
|
|
3977
3977
|
ownerEmail: 'admin@acme.com'
|
|
3978
|
-
});`})]}),Mo("div",{className:"flex items-center gap-4 pt-4",children:[Ja(
|
|
3978
|
+
});`})]}),Mo("div",{className:"flex items-center gap-4 pt-4",children:[Ja(sd,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),Mo(sd,{href:"/docs/libraries/progressive-delivery",className:"btn-primary",children:["Next: Progressive Delivery ",Ja(Jf,{size:16})]})]})]})}import{CodeBlock as Ir,InstallCommand as $f}from"@contractspec/lib.design-system";import pd from"@contractspec/lib.ui-link";import{ChevronRight as Xf}from"lucide-react";import{jsx as xt,jsxs as ko}from"react/jsx-runtime";function xf(){return ko("div",{className:"space-y-8",children:[ko("div",{className:"space-y-4",children:[xt("h1",{className:"font-bold text-4xl",children:"Observability Library"}),ko("p",{className:"text-lg text-muted-foreground",children:["The ",xt("code",{children:"@contractspec/lib.observability"})," library provides a thin wrapper around OpenTelemetry to simplify instrumentation."]})]}),ko("div",{className:"space-y-4",children:[xt("h2",{className:"font-bold text-2xl",children:"Installation"}),xt($f,{package:"@contractspec/lib.observability"})]}),ko("div",{className:"space-y-4",children:[xt("h2",{className:"font-bold text-2xl",children:"Tracing"}),xt(Ir,{language:"typescript",code:`import { traceAsync, traceSync } from '@contractspec/lib.observability/tracing';
|
|
3979
3979
|
|
|
3980
3980
|
await traceAsync('process_order', async (span) => {
|
|
3981
3981
|
span.setAttribute('order_id', order.id);
|
|
@@ -3998,7 +3998,7 @@ const signals = detector.evaluate(point);
|
|
|
3998
3998
|
signals.forEach((signal) => {
|
|
3999
3999
|
const analysis = analyzer.analyze(signal, recentDeployments);
|
|
4000
4000
|
alertManager.notify(signal, analysis);
|
|
4001
|
-
});`})]}),ko("div",{className:"flex items-center gap-4 pt-4",children:[xt(
|
|
4001
|
+
});`})]}),ko("div",{className:"flex items-center gap-4 pt-4",children:[xt(pd,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),ko(pd,{href:"/docs/libraries/slo",className:"btn-primary",children:["Next: SLO ",xt(Xf,{size:16})]})]})]})}import{CodeBlock as fn,InstallCommand as jf}from"@contractspec/lib.design-system";import md from"@contractspec/lib.ui-link";import{ChevronRight as eh}from"lucide-react";import{jsx as La,jsxs as ei}from"react/jsx-runtime";function th(){return ei("div",{className:"space-y-8",children:[ei("div",{className:"space-y-4",children:[La("h1",{className:"font-bold text-4xl",children:"Overlay Engine"}),La("p",{className:"text-lg text-muted-foreground",children:"`@contractspec/lib.overlay-engine` keeps OverlaySpecs typed, signed, and auditable across tenants, roles, users, and devices."})]}),ei("div",{className:"space-y-4",children:[La("h2",{className:"font-bold text-2xl",children:"Installation"}),La(jf,{package:"@contractspec/lib.overlay-engine"})]}),ei("div",{className:"space-y-4",children:[La("h2",{className:"font-bold text-2xl",children:"Define + Sign"}),La(fn,{language:"typescript",code:`import { defineOverlay } from '@contractspec/lib.overlay-engine/spec';
|
|
4002
4002
|
import { signOverlay } from '@contractspec/lib.overlay-engine/signer';
|
|
4003
4003
|
|
|
4004
4004
|
const overlay = defineOverlay({
|
|
@@ -4008,7 +4008,7 @@ const overlay = defineOverlay({
|
|
|
4008
4008
|
modifications: [{ type: 'hideField', field: 'internalNotes' }],
|
|
4009
4009
|
});
|
|
4010
4010
|
|
|
4011
|
-
const signed = await signOverlay(overlay, privateKeyPem);`})]}),ei("div",{className:"space-y-4",children:[La("h2",{className:"font-bold text-2xl",children:"Runtime"}),La("p",{className:"text-muted-foreground",children:"`OverlayRegistry` stores signed overlays with specificity scoring. `OverlayEngine` merges modifications and emits audit events."}),La(
|
|
4011
|
+
const signed = await signOverlay(overlay, privateKeyPem);`})]}),ei("div",{className:"space-y-4",children:[La("h2",{className:"font-bold text-2xl",children:"Runtime"}),La("p",{className:"text-muted-foreground",children:"`OverlayRegistry` stores signed overlays with specificity scoring. `OverlayEngine` merges modifications and emits audit events."}),La(fn,{language:"typescript",code:`const registry = new OverlayRegistry();
|
|
4012
4012
|
registry.register(signed);
|
|
4013
4013
|
|
|
4014
4014
|
const engine = new OverlayEngine({
|
|
@@ -4020,13 +4020,13 @@ const result = engine.apply({
|
|
|
4020
4020
|
target: { fields },
|
|
4021
4021
|
capability: 'billing.createOrder',
|
|
4022
4022
|
tenantId: 'acme',
|
|
4023
|
-
});`})]}),ei("div",{className:"space-y-4",children:[La("h2",{className:"font-bold text-2xl",children:"React Hooks"}),La("p",{className:"text-muted-foreground",children:"Render overlays in React/React Native via `useOverlay`."}),La(
|
|
4023
|
+
});`})]}),ei("div",{className:"space-y-4",children:[La("h2",{className:"font-bold text-2xl",children:"React Hooks"}),La("p",{className:"text-muted-foreground",children:"Render overlays in React/React Native via `useOverlay`."}),La(fn,{language:"typescript",code:`import { useOverlay } from '@contractspec/lib.overlay-engine/react';
|
|
4024
4024
|
|
|
4025
4025
|
const { target } = useOverlay(engine, {
|
|
4026
4026
|
target: { fields },
|
|
4027
4027
|
capability: 'billing.createOrder',
|
|
4028
4028
|
tenantId: 'acme',
|
|
4029
|
-
});`})]}),ei("div",{className:"flex items-center gap-4 pt-4",children:[La(
|
|
4029
|
+
});`})]}),ei("div",{className:"flex items-center gap-4 pt-4",children:[La(md,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),ei(md,{href:"/docs/libraries/workflow-composer",className:"btn-primary",children:["Next: Workflow Composer ",La(eh,{size:16})]})]})]})}import ah from"@contractspec/lib.ui-link";import{ChevronRight as oh}from"lucide-react";import{jsx as Wa,jsxs as ti}from"react/jsx-runtime";var ih=[{title:"Contract and schema foundation",body:"Use these packages to define explicit contracts, schemas, and generated artifacts without inventing a new platform-specific language.",items:[{title:"@contractspec/lib.contracts-spec",description:"Define operations, events, policies, and generated surfaces in TypeScript.",href:"/docs/libraries/contracts"},{title:"@contractspec/lib.schema",description:"Share type-safe schema definitions across validation, clients, and runtime adapters.",href:"/docs/libraries/schema"}]},{title:"Runtime and surface libraries",body:"These packages execute the contract model across UI, data, observability, workflows, and generated runtime behavior.",items:[{title:"@contractspec/lib.runtime",description:"Run typed capability surfaces, execute policies, and connect runtime adapters.",href:"/docs/libraries/runtime"},{title:"@contractspec/lib.ui-kit",description:"Render shared surfaces across web and React Native without forking the contract layer.",href:"/docs/libraries/ui-kit"},{title:"@contractspec/lib.ui-kit-web",description:"Use the raw web primitive layer directly when you want the browser table, accessibility, and interaction model without the design-system shell.",href:"/docs/libraries/ui-kit-web"},{title:"@contractspec/lib.design-system",description:"Build higher-level product surfaces and documented marketing/docs primitives on top of the web and native UI packages.",href:"/docs/libraries/design-system"},{title:"Cross-platform UI",description:"See how the presentation runtimes, ui-kit-web, ui-kit, and design-system stay compatible across React and React Native.",href:"/docs/libraries/cross-platform-ui"},{title:"@contractspec/lib.data-views",description:"Generate and render list/detail style surfaces that stay aligned with data contracts.",href:"/docs/libraries/data-views"}]},{title:"Operator and system packages",body:"These packages matter once the system is live and you need governance, resilience, and observability.",items:[{title:"@contractspec/lib.observability",description:"Trace, log, and measure contract execution using the same system boundaries.",href:"/docs/libraries/observability"},{title:"@contractspec/lib.resilience",description:"Add circuit breakers, retries, and failure controls without hiding the integration model.",href:"/docs/libraries/resilience"},{title:"@contractspec/lib.multi-tenancy",description:"Keep tenant-specific config, policy, and surface resolution explicit.",href:"/docs/libraries/multi-tenancy"},{title:"@contractspec/lib.workflow-composer",description:"Compose and extend workflows without smearing orchestration concerns across apps.",href:"/docs/libraries/workflow-composer"}]}];function rh(){return ti("div",{className:"space-y-10",children:[ti("div",{className:"space-y-3",children:[Wa("p",{className:"editorial-kicker",children:"Build"}),Wa("h1",{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"The OSS foundation is a library system, not a closed platform."}),Wa("p",{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:"ContractSpec is assembled from libraries that remain useful on their own and stronger together. Start with the contract and schema foundation, then add runtime, UI, integration, and operator packages as your system grows."})]}),ti("div",{className:"editorial-proof-strip",children:[ti("div",{className:"editorial-stat",children:[Wa("span",{className:"editorial-label",children:"Layering rule"}),Wa("span",{className:"editorial-stat-value",children:"libs → bundles → apps"})]}),Wa("p",{className:"max-w-2xl text-muted-foreground text-sm leading-7",children:"Keep reusable behavior in libraries, compose it into bundle-level surfaces, and reserve app packages for concrete delivery shells."})]}),Wa("div",{className:"space-y-6",children:ih.map((e)=>ti("section",{className:"editorial-panel space-y-5",children:[ti("div",{className:"space-y-2",children:[Wa("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:e.title}),Wa("p",{className:"text-muted-foreground text-sm leading-7",children:e.body})]}),Wa("div",{className:"grid gap-4 md:grid-cols-2",children:e.items.map((t)=>ti(ah,{href:t.href,className:"rounded-[24px] border border-border/75 bg-background/70 p-5 transition-colors hover:border-[color:rgb(162_79_42_/_0.45)]",children:[Wa("h3",{className:"font-semibold text-lg",children:t.title}),Wa("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:t.description}),ti("div",{className:"mt-3 flex items-center gap-2 text-[color:var(--rust)] text-sm",children:["Learn more ",Wa(oh,{size:14})]})]},t.title))})]},e.title))})]})}import{CodeBlock as hn,InstallCommand as nh}from"@contractspec/lib.design-system";import ud from"@contractspec/lib.ui-link";import{ChevronRight as ch}from"lucide-react";import{jsx as ua,jsxs as ai}from"react/jsx-runtime";function lh(){return ai("div",{className:"space-y-8",children:[ai("div",{className:"space-y-4",children:[ua("h1",{className:"font-bold text-4xl",children:"@contractspec/lib.personalization"}),ua("p",{className:"text-lg text-muted-foreground",children:"Track field/feature/workflow usage, analyze drop-offs, and convert insights into OverlaySpecs or workflow tweaks."})]}),ai("div",{className:"space-y-4",children:[ua("h2",{className:"font-bold text-2xl",children:"Installation"}),ua(nh,{package:"@contractspec/lib.personalization"})]}),ai("div",{className:"space-y-4",children:[ua("h2",{className:"font-bold text-2xl",children:"Tracker"}),ua("p",{className:"text-muted-foreground",children:"Buffer events per tenant/user and emit OpenTelemetry counters automatically."}),ua(hn,{language:"typescript",code:`import { createBehaviorTracker } from '@contractspec/lib.personalization';
|
|
4030
4030
|
|
|
4031
4031
|
const tracker = createBehaviorTracker({
|
|
4032
4032
|
store,
|
|
@@ -4034,17 +4034,17 @@ const tracker = createBehaviorTracker({
|
|
|
4034
4034
|
});
|
|
4035
4035
|
|
|
4036
4036
|
tracker.trackFieldAccess({ operation: 'billing.createOrder', field: 'items' });
|
|
4037
|
-
tracker.trackWorkflowStep({ workflow: 'invoice', step: 'review', status: 'entered' });`})]}),ai("div",{className:"space-y-4",children:[ua("h2",{className:"font-bold text-2xl",children:"Analyzer"}),ua("p",{className:"text-muted-foreground",children:"Summarize events and highlight unused UI, frequent fields, and workflow bottlenecks."}),ua(
|
|
4037
|
+
tracker.trackWorkflowStep({ workflow: 'invoice', step: 'review', status: 'entered' });`})]}),ai("div",{className:"space-y-4",children:[ua("h2",{className:"font-bold text-2xl",children:"Analyzer"}),ua("p",{className:"text-muted-foreground",children:"Summarize events and highlight unused UI, frequent fields, and workflow bottlenecks."}),ua(hn,{language:"typescript",code:`import { BehaviorAnalyzer } from '@contractspec/lib.personalization/analyzer';
|
|
4038
4038
|
|
|
4039
4039
|
const analyzer = new BehaviorAnalyzer(store);
|
|
4040
4040
|
const insights = await analyzer.analyze({ tenantId: 'acme', userId: 'ops-42' });
|
|
4041
|
-
// { unusedFields: ['internalNotes'], workflowBottlenecks: [...] }`})]}),ai("div",{className:"space-y-4",children:[ua("h2",{className:"font-bold text-2xl",children:"Adapter"}),ua("p",{className:"text-muted-foreground",children:"Convert insights into overlays or workflow extension hints."}),ua(
|
|
4041
|
+
// { unusedFields: ['internalNotes'], workflowBottlenecks: [...] }`})]}),ai("div",{className:"space-y-4",children:[ua("h2",{className:"font-bold text-2xl",children:"Adapter"}),ua("p",{className:"text-muted-foreground",children:"Convert insights into overlays or workflow extension hints."}),ua(hn,{language:"typescript",code:`import { insightsToOverlaySuggestion } from '@contractspec/lib.personalization/adapter';
|
|
4042
4042
|
|
|
4043
4043
|
const overlay = insightsToOverlaySuggestion(insights, {
|
|
4044
4044
|
overlayId: 'acme-order-form',
|
|
4045
4045
|
tenantId: 'acme',
|
|
4046
4046
|
capability: 'billing.createOrder',
|
|
4047
|
-
});`})]}),ai("div",{className:"flex items-center gap-4 pt-4",children:[ua(
|
|
4047
|
+
});`})]}),ai("div",{className:"flex items-center gap-4 pt-4",children:[ua(ud,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),ai(ud,{href:"/docs/libraries/overlay-engine",className:"btn-primary",children:["Next: Overlay Engine ",ua(ch,{size:16})]})]})]})}import{CodeBlock as gd,InstallCommand as dh}from"@contractspec/lib.design-system";import fd from"@contractspec/lib.ui-link";import{ChevronRight as sh}from"lucide-react";import{jsx as ga,jsxs as ro}from"react/jsx-runtime";function ph(){return ro("div",{className:"space-y-8",children:[ro("div",{className:"space-y-4",children:[ga("h1",{className:"font-bold text-4xl",children:"Progressive Delivery Library"}),ro("p",{className:"text-lg text-muted-foreground",children:["The ",ga("code",{children:"@contractspec/lib.progressive-delivery"})," package helps you ship new specs with confidence: canary + blue-green strategies, metric guardrails, and rollback hooks in one place."]})]}),ro("div",{className:"space-y-4",children:[ga("h2",{className:"font-bold text-2xl",children:"Installation"}),ga(dh,{package:"@contractspec/lib.progressive-delivery"})]}),ro("div",{className:"space-y-4",children:[ga("h2",{className:"font-bold text-2xl",children:"Define a Strategy"}),ga(gd,{language:"typescript",code:`import { DeploymentCoordinator, createDefaultCanaryController, TrafficShifter, RollbackManager } from '@contractspec/lib.progressive-delivery';
|
|
4048
4048
|
|
|
4049
4049
|
const strategy = {
|
|
4050
4050
|
target: { name: 'billing.createInvoice', version: 7 },
|
|
@@ -4054,7 +4054,7 @@ const strategy = {
|
|
|
4054
4054
|
latencyP99: 500,
|
|
4055
4055
|
latencyP95: 250,
|
|
4056
4056
|
},
|
|
4057
|
-
};`})]}),ro("div",{className:"space-y-4",children:[ga("h2",{className:"font-bold text-2xl",children:"Run the Coordinator"}),ga(
|
|
4057
|
+
};`})]}),ro("div",{className:"space-y-4",children:[ga("h2",{className:"font-bold text-2xl",children:"Run the Coordinator"}),ga(gd,{language:"typescript",code:`const eventBus = new DeploymentEventBus();
|
|
4058
4058
|
const controller = createDefaultCanaryController(strategy, fetchMetrics, eventBus);
|
|
4059
4059
|
const coordinator = new DeploymentCoordinator({
|
|
4060
4060
|
strategy,
|
|
@@ -4065,7 +4065,7 @@ const coordinator = new DeploymentCoordinator({
|
|
|
4065
4065
|
eventBus,
|
|
4066
4066
|
});
|
|
4067
4067
|
|
|
4068
|
-
const result = await coordinator.run();`}),ro("p",{className:"text-muted-foreground text-sm",children:["The coordinator emits ",ga("code",{children:"stage_started"}),","," ",ga("code",{children:"stage_failed"}),", and ",ga("code",{children:"rolled_back"})," events, making it easy to power dashboards or alerting workflows."]})]}),ro("div",{className:"space-y-4",children:[ga("h2",{className:"font-bold text-2xl",children:"Blue-Green Swap"}),ro("p",{className:"text-muted-foreground text-sm",children:["Switch to ",ga("code",{children:"mode: 'blue-green'"})," to warm up the new stack in parallel and cut over once smoke tests pass. The same guardrails apply before the final swap."]})]}),ro("div",{className:"flex items-center gap-4 pt-4",children:[ga(
|
|
4068
|
+
const result = await coordinator.run();`}),ro("p",{className:"text-muted-foreground text-sm",children:["The coordinator emits ",ga("code",{children:"stage_started"}),","," ",ga("code",{children:"stage_failed"}),", and ",ga("code",{children:"rolled_back"})," events, making it easy to power dashboards or alerting workflows."]})]}),ro("div",{className:"space-y-4",children:[ga("h2",{className:"font-bold text-2xl",children:"Blue-Green Swap"}),ro("p",{className:"text-muted-foreground text-sm",children:["Switch to ",ga("code",{children:"mode: 'blue-green'"})," to warm up the new stack in parallel and cut over once smoke tests pass. The same guardrails apply before the final swap."]})]}),ro("div",{className:"flex items-center gap-4 pt-4",children:[ga(fd,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),ro(fd,{href:"/docs/libraries/resilience",className:"btn-primary",children:["Next: Resilience ",ga(sh,{size:16})]})]})]})}import{CodeBlock as yn,InstallCommand as mh}from"@contractspec/lib.design-system";import hd from"@contractspec/lib.ui-link";import{ChevronRight as uh}from"lucide-react";import{jsx as fa,jsxs as Uo}from"react/jsx-runtime";function gh(){return Uo("div",{className:"space-y-8",children:[Uo("div",{className:"space-y-4",children:[fa("h1",{className:"font-bold text-4xl",children:"Resilience Library"}),Uo("p",{className:"text-lg text-muted-foreground",children:["The ",fa("code",{children:"@contractspec/lib.resilience"})," library provides primitives to handle failures gracefully."]})]}),Uo("div",{className:"space-y-4",children:[fa("h2",{className:"font-bold text-2xl",children:"Installation"}),fa(mh,{package:"@contractspec/lib.resilience"})]}),Uo("div",{className:"space-y-4",children:[fa("h2",{className:"font-bold text-2xl",children:"Circuit Breaker"}),fa("p",{className:"text-muted-foreground",children:"Prevent cascading failures by stopping calls to a failing dependency."}),fa(yn,{language:"typescript",code:`import { CircuitBreaker } from '@contractspec/lib.resilience/circuit-breaker';
|
|
4069
4069
|
|
|
4070
4070
|
const breaker = new CircuitBreaker({
|
|
4071
4071
|
failureThreshold: 5,
|
|
@@ -4074,19 +4074,19 @@ const breaker = new CircuitBreaker({
|
|
|
4074
4074
|
|
|
4075
4075
|
const result = await breaker.execute(async () => {
|
|
4076
4076
|
return await fetch('https://api.stripe.com/v1/charges');
|
|
4077
|
-
});`})]}),Uo("div",{className:"space-y-4",children:[fa("h2",{className:"font-bold text-2xl",children:"Retry"}),fa("p",{className:"text-muted-foreground",children:"Automatically retry transient failures with exponential backoff."}),fa(
|
|
4077
|
+
});`})]}),Uo("div",{className:"space-y-4",children:[fa("h2",{className:"font-bold text-2xl",children:"Retry"}),fa("p",{className:"text-muted-foreground",children:"Automatically retry transient failures with exponential backoff."}),fa(yn,{language:"typescript",code:`import { retry } from '@contractspec/lib.resilience/retry';
|
|
4078
4078
|
|
|
4079
4079
|
const result = await retry(
|
|
4080
4080
|
async () => fetchUser(id),
|
|
4081
4081
|
3, // retries
|
|
4082
4082
|
1000, // initial delay
|
|
4083
4083
|
true // backoff
|
|
4084
|
-
);`})]}),Uo("div",{className:"space-y-4",children:[fa("h2",{className:"font-bold text-2xl",children:"Timeout & Fallback"}),fa("p",{className:"text-muted-foreground",children:"Set hard limits on execution time and provide default values on failure."}),fa(
|
|
4084
|
+
);`})]}),Uo("div",{className:"space-y-4",children:[fa("h2",{className:"font-bold text-2xl",children:"Timeout & Fallback"}),fa("p",{className:"text-muted-foreground",children:"Set hard limits on execution time and provide default values on failure."}),fa(yn,{language:"typescript",code:`import { timeout, fallback } from '@contractspec/lib.resilience';
|
|
4085
4085
|
|
|
4086
4086
|
const result = await fallback(
|
|
4087
4087
|
() => timeout(slowOperation, 5000),
|
|
4088
4088
|
defaultValue
|
|
4089
|
-
);`})]}),Uo("div",{className:"flex items-center gap-4 pt-4",children:[fa(
|
|
4089
|
+
);`})]}),Uo("div",{className:"flex items-center gap-4 pt-4",children:[fa(hd,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),Uo(hd,{href:"/docs/libraries/testing",className:"btn-primary",children:["Next: Testing ",fa(uh,{size:16})]})]})]})}import{CodeBlock as fh,InstallCommand as hh}from"@contractspec/lib.design-system";import bn from"@contractspec/lib.ui-link";import{ChevronRight as yh}from"lucide-react";import{jsx as Me,jsxs as Ve}from"react/jsx-runtime";function bh(){return Ve("div",{className:"space-y-8",children:[Ve("div",{className:"space-y-4",children:[Me("h1",{className:"font-bold text-4xl",children:"Runtime Libraries"}),Me("p",{className:"text-muted-foreground",children:"The presentation runtime libraries provide the engine for rendering ContractSpec-defined UIs. They handle state management, validation, step navigation, and component rendering for Workflows and DataViews."})]}),Ve("div",{className:"space-y-4",children:[Me("h2",{className:"font-bold text-2xl",children:"Installation"}),Me(hh,{package:"@contractspec/lib.presentation-runtime-react"})]}),Ve("div",{className:"space-y-4",children:[Me("h2",{className:"font-bold text-2xl",children:"Libraries"}),Ve("div",{className:"space-y-6",children:[Ve("div",{className:"card-subtle p-6",children:[Me("h3",{className:"font-bold text-lg",children:"@contractspec/lib.presentation-runtime-core"}),Ve("p",{className:"mt-2 text-muted-foreground text-sm",children:[Me("strong",{children:"Framework-Agnostic Core"}),". Contains the state machines, validation logic, and navigation rules for workflows. Can be used to build renderers for any platform (Vue, Svelte, CLI)."]})]}),Ve("div",{className:"card-subtle p-6",children:[Me("h3",{className:"font-bold text-lg",children:"@contractspec/lib.presentation-runtime-react"}),Ve("p",{className:"mt-2 text-muted-foreground text-sm",children:[Me("strong",{children:"React Bindings"}),". Hooks (`useWorkflow`) and components (`WorkflowStepper`, `WorkflowStepRenderer`) for React Web applications. Integrates with `ui-kit-web`."]})]}),Ve("div",{className:"card-subtle p-6",children:[Me("h3",{className:"font-bold text-lg",children:"@contractspec/lib.presentation-runtime-react-native"}),Ve("p",{className:"mt-2 text-muted-foreground text-sm",children:[Me("strong",{children:"React Native Bindings"}),". Optimized for mobile experiences. Handles native navigation integration and uses universal components from `ui-kit`."]})]})]})]}),Ve("div",{className:"space-y-4",children:[Me("h2",{className:"font-bold text-2xl",children:"Example: React Workflow"}),Me(fh,{language:"tsx",code:`import { useWorkflow, WorkflowStepRenderer } from '@contractspec/lib.presentation-runtime-react';
|
|
4090
4090
|
import { OnboardingFlow } from './specs/onboarding';
|
|
4091
4091
|
|
|
4092
4092
|
export function OnboardingPage() {
|
|
@@ -4126,7 +4126,7 @@ export function OnboardingPage() {
|
|
|
4126
4126
|
</div>
|
|
4127
4127
|
</div>
|
|
4128
4128
|
);
|
|
4129
|
-
}`})]}),Ve("div",{className:"space-y-4",children:[Me("h2",{className:"font-bold text-2xl",children:"Architecture"}),Me("p",{className:"text-muted-foreground",children:'The runtime follows a "render-loop" pattern:'}),Ve("ol",{className:"list-inside list-decimal space-y-2 text-muted-foreground",children:[Ve("li",{children:[Me("strong",{children:"Spec"}),": Defines the flow, fields, and validation rules."]}),Ve("li",{children:[Me("strong",{children:"Core"}),": Tracks current step, data state, and validation errors."]}),Ve("li",{children:[Me("strong",{children:"Renderer"}),": Maps spec fields to UI components (Input, Select, etc.)."]}),Ve("li",{children:[Me("strong",{children:"User"}),": Interacts with components, updating core state."]}),Ve("li",{children:[Me("strong",{children:"Policy"}),": (Optional) Re-evaluates visibility on every change."]})]})]}),Ve("div",{className:"card-subtle space-y-3 p-6",children:[Me("h2",{className:"font-bold text-2xl",children:"Related reading"}),Ve("p",{className:"text-muted-foreground",children:["For the full React and React Native layering story across runtime, primitives, and composed components, read"," ",Me(
|
|
4129
|
+
}`})]}),Ve("div",{className:"space-y-4",children:[Me("h2",{className:"font-bold text-2xl",children:"Architecture"}),Me("p",{className:"text-muted-foreground",children:'The runtime follows a "render-loop" pattern:'}),Ve("ol",{className:"list-inside list-decimal space-y-2 text-muted-foreground",children:[Ve("li",{children:[Me("strong",{children:"Spec"}),": Defines the flow, fields, and validation rules."]}),Ve("li",{children:[Me("strong",{children:"Core"}),": Tracks current step, data state, and validation errors."]}),Ve("li",{children:[Me("strong",{children:"Renderer"}),": Maps spec fields to UI components (Input, Select, etc.)."]}),Ve("li",{children:[Me("strong",{children:"User"}),": Interacts with components, updating core state."]}),Ve("li",{children:[Me("strong",{children:"Policy"}),": (Optional) Re-evaluates visibility on every change."]})]})]}),Ve("div",{className:"card-subtle space-y-3 p-6",children:[Me("h2",{className:"font-bold text-2xl",children:"Related reading"}),Ve("p",{className:"text-muted-foreground",children:["For the full React and React Native layering story across runtime, primitives, and composed components, read"," ",Me(bn,{href:"/docs/libraries/cross-platform-ui",className:"text-[color:var(--rust)] underline underline-offset-4",children:"Cross-platform UI"}),"."]})]}),Ve("div",{className:"flex items-center gap-4 pt-4",children:[Me(bn,{href:"/docs/libraries/data-backend",className:"btn-ghost",children:"Previous: Data & Backend"}),Ve(bn,{href:"/docs/libraries",className:"btn-primary",children:["Back to Libraries ",Me(yh,{size:16})]})]})]})}import{CodeBlock as yd,InstallCommand as vh}from"@contractspec/lib.design-system";import bd from"@contractspec/lib.ui-link";import{ChevronRight as Nh}from"lucide-react";import{jsx as D,jsxs as Fe}from"react/jsx-runtime";function wh(){return Fe("div",{className:"space-y-8",children:[Fe("div",{className:"space-y-4",children:[D("h1",{className:"font-bold text-4xl",children:"@contractspec/lib.schema"}),D("p",{className:"text-muted-foreground",children:"A small schema dictionary to describe operation I/O once and export to Zod (runtime validation), Pothos (GraphQL type refs), and JSON Schema."})]}),Fe("div",{className:"space-y-4",children:[D("h2",{className:"font-bold text-2xl",children:"Installation"}),D(vh,{package:"@contractspec/lib.schema"})]}),Fe("div",{className:"space-y-4",children:[D("h2",{className:"font-bold text-2xl",children:"Core Exports"}),Fe("ul",{className:"space-y-2 text-muted-foreground",children:[Fe("li",{children:[D("code",{className:"rounded bg-background/50 px-2 py-1",children:"SchemaModel"}),": Compose fields into typed object models"]}),Fe("li",{children:[D("code",{className:"rounded bg-background/50 px-2 py-1",children:"ScalarTypeEnum"}),": Common scalar types (NonEmptyString, Email, DateTime, etc.)"]}),Fe("li",{children:[D("code",{className:"rounded bg-background/50 px-2 py-1",children:"defineEnum"}),": Create type-safe enums"]}),Fe("li",{children:[D("code",{className:"rounded bg-background/50 px-2 py-1",children:"FieldType"}),": Wrap scalars with Zod/GraphQL/JSON Schema"]})]})]}),Fe("div",{className:"space-y-4",children:[D("h2",{className:"font-bold text-2xl",children:"Example: Basic Schema"}),D(yd,{language:"typescript",code:`import { SchemaModel, ScalarTypeEnum } from '@contractspec/lib.schema';
|
|
4130
4130
|
|
|
4131
4131
|
export const CreateSpotInput = new SchemaModel({
|
|
4132
4132
|
name: 'CreateSpotInput',
|
|
@@ -4144,7 +4144,7 @@ const zodSchema = CreateSpotInput.getZod();
|
|
|
4144
4144
|
const pothosName = CreateSpotInput.getPothosInput();
|
|
4145
4145
|
|
|
4146
4146
|
// Get JSON Schema
|
|
4147
|
-
const jsonSchema = CreateSpotInput.getJsonSchema();`})]}),Fe("div",{className:"space-y-4",children:[D("h2",{className:"font-bold text-2xl",children:"Example: Enums"}),D(
|
|
4147
|
+
const jsonSchema = CreateSpotInput.getJsonSchema();`})]}),Fe("div",{className:"space-y-4",children:[D("h2",{className:"font-bold text-2xl",children:"Example: Enums"}),D(yd,{language:"typescript",code:`import { defineEnum, SchemaModel } from '@contractspec/lib.schema';
|
|
4148
4148
|
|
|
4149
4149
|
const Weekday = defineEnum('Weekday', [
|
|
4150
4150
|
'MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU',
|
|
@@ -4159,19 +4159,19 @@ const RecurrenceRule = new SchemaModel({
|
|
|
4159
4159
|
},
|
|
4160
4160
|
byWeekday: { type: Weekday, isOptional: true, isArray: true },
|
|
4161
4161
|
},
|
|
4162
|
-
});`})]}),Fe("div",{className:"space-y-4",children:[D("h2",{className:"font-bold text-2xl",children:"Available Scalars"}),Fe("div",{className:"grid gap-4 md:grid-cols-2",children:[Fe("div",{className:"card-subtle p-4",children:[D("h3",{className:"mb-2 font-semibold",children:"Strings"}),Fe("ul",{className:"space-y-1 text-muted-foreground text-sm",children:[D("li",{children:D("code",{children:"NonEmptyString()"})}),D("li",{children:D("code",{children:"Email()"})}),D("li",{children:D("code",{children:"PhoneNumber()"})}),D("li",{children:D("code",{children:"CountryCode()"})}),D("li",{children:D("code",{children:"Locale()"})}),D("li",{children:D("code",{children:"TimeZone()"})})]})]}),Fe("div",{className:"card-subtle p-4",children:[D("h3",{className:"mb-2 font-semibold",children:"Numbers"}),Fe("ul",{className:"space-y-1 text-muted-foreground text-sm",children:[D("li",{children:D("code",{children:"PositiveNumber()"})}),D("li",{children:D("code",{children:"Latitude()"})}),D("li",{children:D("code",{children:"Longitude()"})})]})]}),Fe("div",{className:"card-subtle p-4",children:[D("h3",{className:"mb-2 font-semibold",children:"Dates & Times"}),Fe("ul",{className:"space-y-1 text-muted-foreground text-sm",children:[D("li",{children:D("code",{children:"Date()"})}),D("li",{children:D("code",{children:"DateTime()"})})]})]}),Fe("div",{className:"card-subtle p-4",children:[D("h3",{className:"mb-2 font-semibold",children:"Generic"}),Fe("ul",{className:"space-y-1 text-muted-foreground text-sm",children:[D("li",{children:D("code",{children:"String()"})}),D("li",{children:D("code",{children:"JSON()"})})]})]})]})]}),Fe("div",{className:"flex items-center gap-4 pt-4",children:[D(
|
|
4162
|
+
});`})]}),Fe("div",{className:"space-y-4",children:[D("h2",{className:"font-bold text-2xl",children:"Available Scalars"}),Fe("div",{className:"grid gap-4 md:grid-cols-2",children:[Fe("div",{className:"card-subtle p-4",children:[D("h3",{className:"mb-2 font-semibold",children:"Strings"}),Fe("ul",{className:"space-y-1 text-muted-foreground text-sm",children:[D("li",{children:D("code",{children:"NonEmptyString()"})}),D("li",{children:D("code",{children:"Email()"})}),D("li",{children:D("code",{children:"PhoneNumber()"})}),D("li",{children:D("code",{children:"CountryCode()"})}),D("li",{children:D("code",{children:"Locale()"})}),D("li",{children:D("code",{children:"TimeZone()"})})]})]}),Fe("div",{className:"card-subtle p-4",children:[D("h3",{className:"mb-2 font-semibold",children:"Numbers"}),Fe("ul",{className:"space-y-1 text-muted-foreground text-sm",children:[D("li",{children:D("code",{children:"PositiveNumber()"})}),D("li",{children:D("code",{children:"Latitude()"})}),D("li",{children:D("code",{children:"Longitude()"})})]})]}),Fe("div",{className:"card-subtle p-4",children:[D("h3",{className:"mb-2 font-semibold",children:"Dates & Times"}),Fe("ul",{className:"space-y-1 text-muted-foreground text-sm",children:[D("li",{children:D("code",{children:"Date()"})}),D("li",{children:D("code",{children:"DateTime()"})})]})]}),Fe("div",{className:"card-subtle p-4",children:[D("h3",{className:"mb-2 font-semibold",children:"Generic"}),Fe("ul",{className:"space-y-1 text-muted-foreground text-sm",children:[D("li",{children:D("code",{children:"String()"})}),D("li",{children:D("code",{children:"JSON()"})})]})]})]})]}),Fe("div",{className:"flex items-center gap-4 pt-4",children:[D(bd,{href:"/docs/libraries/contracts",className:"btn-ghost",children:"Previous: Contracts"}),Fe(bd,{href:"/docs/libraries/ui-kit",className:"btn-primary",children:["Next: UI Kit ",D(Nh,{size:16})]})]})]})}import{CodeBlock as vd,InstallCommand as kh}from"@contractspec/lib.design-system";import Nd from"@contractspec/lib.ui-link";import{ChevronRight as Sh}from"lucide-react";import{jsx as _a,jsxs as So}from"react/jsx-runtime";function Ch(){return So("div",{className:"space-y-8",children:[So("div",{className:"space-y-4",children:[_a("h1",{className:"font-bold text-4xl",children:"SLO Library"}),So("p",{className:"text-lg text-muted-foreground",children:[_a("code",{children:"@contractspec/lib.slo"})," keeps service level objectives front and center—declarative definitions, rolling snapshots, burn-rate math, and automated incidents."]})]}),So("div",{className:"space-y-4",children:[_a("h2",{className:"font-bold text-2xl",children:"Installation"}),_a(kh,{package:"@contractspec/lib.slo"})]}),So("div",{className:"space-y-4",children:[_a("h2",{className:"font-bold text-2xl",children:"Define Targets"}),_a(vd,{language:"typescript",code:`const definition: SLODefinition = {
|
|
4163
4163
|
id: 'billing.createInvoice.availability',
|
|
4164
4164
|
targetAvailability: 0.999,
|
|
4165
4165
|
latencyP99TargetMs: 500,
|
|
4166
4166
|
rollingWindowMs: 7 * 24 * 60 * 60 * 1000,
|
|
4167
4167
|
alerts: { fastBurnThreshold: 14, slowBurnThreshold: 6 },
|
|
4168
|
-
};`})]}),So("div",{className:"space-y-4",children:[_a("h2",{className:"font-bold text-2xl",children:"Monitor Burn Rate"}),_a(
|
|
4168
|
+
};`})]}),So("div",{className:"space-y-4",children:[_a("h2",{className:"font-bold text-2xl",children:"Monitor Burn Rate"}),_a(vd,{language:"typescript",code:`const monitor = new SLOMonitor({ definition, incidentManager });
|
|
4169
4169
|
const { snapshot, burnRate } = monitor.recordWindow({
|
|
4170
4170
|
good: 12500,
|
|
4171
4171
|
bad: 3,
|
|
4172
4172
|
latencyP99: 420,
|
|
4173
4173
|
latencyP95: 210,
|
|
4174
|
-
});`}),So("p",{className:"text-muted-foreground text-sm",children:["When burn rate exceeds the configured thresholds the monitor calls your",_a("code",{children:"IncidentManager"}),", providing the snapshot that triggered the alert."]})]}),So("div",{className:"space-y-4",children:[_a("h2",{className:"font-bold text-2xl",children:"History & Reporting"}),_a("p",{className:"text-muted-foreground text-sm",children:"`SLOTracker.getHistory()` returns the latest snapshots so dashboards can show trends without hitting a warehouse. Prisma models persist everything for long-term audits."})]}),So("div",{className:"flex items-center gap-4 pt-4",children:[_a(
|
|
4174
|
+
});`}),So("p",{className:"text-muted-foreground text-sm",children:["When burn rate exceeds the configured thresholds the monitor calls your",_a("code",{children:"IncidentManager"}),", providing the snapshot that triggered the alert."]})]}),So("div",{className:"space-y-4",children:[_a("h2",{className:"font-bold text-2xl",children:"History & Reporting"}),_a("p",{className:"text-muted-foreground text-sm",children:"`SLOTracker.getHistory()` returns the latest snapshots so dashboards can show trends without hitting a warehouse. Prisma models persist everything for long-term audits."})]}),So("div",{className:"flex items-center gap-4 pt-4",children:[_a(Nd,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),So(Nd,{href:"/docs/libraries/cost-tracking",className:"btn-primary",children:["Next: Cost Tracking ",_a(Sh,{size:16})]})]})]})}import{CodeBlock as wd,InstallCommand as Ih}from"@contractspec/lib.design-system";import kd from"@contractspec/lib.ui-link";import{ChevronRight as Ph}from"lucide-react";import{jsx as ha,jsxs as za}from"react/jsx-runtime";function Th(){return za("div",{className:"space-y-8",children:[za("div",{className:"space-y-4",children:[ha("h1",{className:"font-bold text-4xl",children:"@contractspec/lib.support-bot"}),ha("p",{className:"text-lg text-muted-foreground",children:"Build AI-first support flows using drop-in classifiers, knowledge-grounded resolvers, and tone-aware responders—all wired into the agent runner."})]}),za("div",{className:"space-y-4",children:[ha("h2",{className:"font-bold text-2xl",children:"Installation"}),ha(Ih,{package:"@contractspec/lib.support-bot"})]}),za("div",{className:"space-y-3",children:[ha("h2",{className:"font-bold text-2xl",children:"Wire the primitives"}),ha(wd,{language:"typescript",code:`import { TicketClassifier, TicketResolver, AutoResponder } from '@contractspec/lib.support-bot';
|
|
4175
4175
|
|
|
4176
4176
|
const classifier = new TicketClassifier();
|
|
4177
4177
|
const resolver = new TicketResolver({ knowledge });
|
|
@@ -4179,10 +4179,10 @@ const responder = new AutoResponder();
|
|
|
4179
4179
|
|
|
4180
4180
|
const classification = await classifier.classify(ticket);
|
|
4181
4181
|
const resolution = await resolver.resolve(ticket);
|
|
4182
|
-
const draft = await responder.draft(ticket, resolution, classification);`})]}),za("div",{className:"space-y-3",children:[ha("h2",{className:"font-bold text-2xl",children:"Expose as agent tools"}),ha(
|
|
4182
|
+
const draft = await responder.draft(ticket, resolution, classification);`})]}),za("div",{className:"space-y-3",children:[ha("h2",{className:"font-bold text-2xl",children:"Expose as agent tools"}),ha(wd,{language:"typescript",code:`import { createSupportTools } from '@contractspec/lib.support-bot/bot';
|
|
4183
4183
|
|
|
4184
4184
|
const tools = createSupportTools({ resolver, classifier, responder });
|
|
4185
|
-
// Pass these tools into your host runtime or agent adapter.`})]}),za("div",{className:"space-y-3",children:[ha("h2",{className:"font-bold text-2xl",children:"Included modules"}),za("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[za("li",{children:[ha("strong",{children:"TicketClassifier"}),": heuristics + optional LLM validation for category/priority."]}),za("li",{children:[ha("strong",{children:"TicketResolver"}),": RAG resolver that can plug into any knowledge retriever."]}),za("li",{children:[ha("strong",{children:"AutoResponder"}),": generates drafts, citations, and tone-aware copy."]}),za("li",{children:[ha("strong",{children:"SupportFeedbackLoop"}),": track auto-resolution rates and sentiment trends."]})]})]}),za("div",{className:"flex items-center gap-4 pt-4",children:[ha(
|
|
4185
|
+
// Pass these tools into your host runtime or agent adapter.`})]}),za("div",{className:"space-y-3",children:[ha("h2",{className:"font-bold text-2xl",children:"Included modules"}),za("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[za("li",{children:[ha("strong",{children:"TicketClassifier"}),": heuristics + optional LLM validation for category/priority."]}),za("li",{children:[ha("strong",{children:"TicketResolver"}),": RAG resolver that can plug into any knowledge retriever."]}),za("li",{children:[ha("strong",{children:"AutoResponder"}),": generates drafts, citations, and tone-aware copy."]}),za("li",{children:[ha("strong",{children:"SupportFeedbackLoop"}),": track auto-resolution rates and sentiment trends."]})]})]}),za("div",{className:"flex items-center gap-4 pt-4",children:[ha(kd,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),za(kd,{href:"/docs/libraries/growth",className:"btn-primary",children:["Next: Growth ",ha(Ph,{size:16})]})]})]})}import{CodeBlock as vn,InstallCommand as Ah}from"@contractspec/lib.design-system";import Sd from"@contractspec/lib.ui-link";import{ChevronRight as Rh}from"lucide-react";import{jsx as ya,jsxs as Wo}from"react/jsx-runtime";function Lh(){return Wo("div",{className:"space-y-8",children:[Wo("div",{className:"space-y-4",children:[ya("h1",{className:"font-bold text-4xl",children:"@contractspec/lib.testing"}),ya("p",{className:"text-lg text-muted-foreground",children:"Golden tests ensure new rollouts behave exactly like the traffic that inspired them. Record requests in production, replay them locally, and ship with confidence."})]}),Wo("div",{className:"space-y-4",children:[ya("h2",{className:"font-bold text-2xl",children:"Installation"}),ya(Ah,{package:"@contractspec/lib.testing"})]}),Wo("div",{className:"space-y-3",children:[ya("h2",{className:"font-bold text-2xl",children:"Record traffic"}),ya(vn,{language:"typescript",code:`import {
|
|
4186
4186
|
TrafficRecorder,
|
|
4187
4187
|
InMemoryTrafficStore,
|
|
4188
4188
|
} from '@contractspec/lib.testing/recorder';
|
|
@@ -4202,7 +4202,7 @@ await recorder.record({
|
|
|
4202
4202
|
output,
|
|
4203
4203
|
success: true,
|
|
4204
4204
|
tenantId: ctx.organizationId ?? undefined,
|
|
4205
|
-
});`})]}),Wo("div",{className:"space-y-3",children:[ya("h2",{className:"font-bold text-2xl",children:"Generate suites"}),ya(
|
|
4205
|
+
});`})]}),Wo("div",{className:"space-y-3",children:[ya("h2",{className:"font-bold text-2xl",children:"Generate suites"}),ya(vn,{language:"typescript",code:`import { GoldenTestGenerator } from '@contractspec/lib.testing';
|
|
4206
4206
|
|
|
4207
4207
|
const generator = new GoldenTestGenerator();
|
|
4208
4208
|
const code = generator.generate(snapshots, {
|
|
@@ -4210,7 +4210,7 @@ const code = generator.generate(snapshots, {
|
|
|
4210
4210
|
runnerImport: './tests/run-operation',
|
|
4211
4211
|
runnerFunction: 'runOrdersCommand',
|
|
4212
4212
|
framework: 'vitest',
|
|
4213
|
-
});`})]}),Wo("div",{className:"space-y-3",children:[ya("h2",{className:"font-bold text-2xl",children:"CLI workflow"}),ya(
|
|
4213
|
+
});`})]}),Wo("div",{className:"space-y-3",children:[ya("h2",{className:"font-bold text-2xl",children:"CLI workflow"}),ya(vn,{language:"bash",code:"contractspec test generate \\\n --operation orders.create \\\n --output tests/orders.create.golden.test.ts \\\n --runner-import ./tests/run-operation \\\n --runner-fn runOrdersCommand \\\n --from-production \\\n --days 7 \\\n --sample-rate 0.05"})]}),ya("div",{className:"grid gap-4 md:grid-cols-2",children:[{title:"Framework agnostic",description:"Vitest by default, Jest via `generateJestSuite`, or call `runGoldenTests` manually inside CI."},{title:"Sanitize & sample",description:"Scrub payloads before persistence and control sample rates per operation to stay within compliance limits."}].map((e)=>Wo("div",{className:"card-subtle space-y-2 p-4",children:[ya("h3",{className:"font-semibold text-lg",children:e.title}),ya("p",{className:"text-muted-foreground text-sm",children:e.description})]},e.title))}),Wo("div",{className:"flex items-center gap-4 pt-4",children:[ya(Sd,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),Wo(Sd,{href:"/docs/libraries/resilience",className:"btn-primary",children:["Next: Resilience ",ya(Rh,{size:16})]})]})]})}import{CodeBlock as Dh,InstallCommand as Eh}from"@contractspec/lib.design-system";import Pr from"@contractspec/lib.ui-link";import{ChevronRight as Oh}from"lucide-react";import{jsx as Z,jsxs as Ue}from"react/jsx-runtime";var Bh=`import { DataTable } from '@contractspec/lib.ui-kit/ui/data-table';
|
|
4214
4214
|
import { useContractTable } from '@contractspec/lib.presentation-runtime-react';
|
|
4215
4215
|
|
|
4216
4216
|
import { SHOWCASE_ROWS } from '@contractspec/example.data-grid-showcase/ui/data-grid-showcase.data';
|
|
@@ -4254,7 +4254,7 @@ export function NativeAccountGrid() {
|
|
|
4254
4254
|
footer={\`Rows \${controller.rows.length}\`}
|
|
4255
4255
|
/>
|
|
4256
4256
|
);
|
|
4257
|
-
}`;function
|
|
4257
|
+
}`;function Mh(){return Ue("div",{className:"space-y-8",children:[Ue("div",{className:"space-y-4",children:[Z("h1",{className:"font-bold text-4xl",children:"@contractspec/lib.ui-kit"}),Ue("p",{className:"text-muted-foreground",children:["Universal UI components for React Native and Web, built on top of",Z("code",{children:"nativewind"})," and ",Z("code",{children:"@rn-primitives"}),"."]})]}),Ue("div",{className:"space-y-4",children:[Z("h2",{className:"font-bold text-2xl",children:"Installation"}),Z(Eh,{package:"@contractspec/lib.ui-kit"})]}),Ue("div",{className:"space-y-4",children:[Z("h2",{className:"font-bold text-2xl",children:"Key Features"}),Ue("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Ue("li",{children:[Z("strong",{children:"Universal"}),": Components render natively on iOS/Android and as standard HTML on web"]}),Ue("li",{children:[Z("strong",{children:"Styled with NativeWind"}),": Uses Tailwind CSS classes for styling"]}),Ue("li",{children:[Z("strong",{children:"Accessible"}),": Leverages ",Z("code",{children:"@rn-primitives"})," ","(Radix UI for Native)"]}),Ue("li",{children:[Z("strong",{children:"Atomic Design"}),": Exports atoms, molecules, and organisms"]})]})]}),Ue("div",{className:"space-y-4",children:[Z("h2",{className:"font-bold text-2xl",children:"Data table example"}),Ue("p",{className:"text-muted-foreground",children:["The canonical"," ",Z(Pr,{href:"/docs/examples/data-grid-showcase",className:"text-[color:var(--rust)] underline underline-offset-4",children:"Data Grid Showcase"})," ","uses ",Z("code",{children:"@contractspec/lib.ui-kit/ui/data-table"})," as the native-first primitive lane. It shares the same controller model as the web renderer while keeping the React Native / Expo surface explicit."]}),Z(Dh,{language:"tsx",code:Bh})]}),Ue("div",{className:"space-y-4",children:[Z("h2",{className:"font-bold text-2xl",children:"Core Components"}),Ue("div",{className:"grid gap-4 md:grid-cols-3",children:[Ue("div",{className:"card-subtle p-4",children:[Z("h3",{className:"mb-2 font-semibold",children:"Form Controls"}),Ue("ul",{className:"space-y-1 text-muted-foreground text-sm",children:[Z("li",{children:"Button"}),Z("li",{children:"Input"}),Z("li",{children:"Checkbox"}),Z("li",{children:"Switch"}),Z("li",{children:"Select"})]})]}),Ue("div",{className:"card-subtle p-4",children:[Z("h3",{className:"mb-2 font-semibold",children:"Layout"}),Ue("ul",{className:"space-y-1 text-muted-foreground text-sm",children:[Z("li",{children:"Card"}),Z("li",{children:"Stack"}),Z("li",{children:"Separator"}),Z("li",{children:"Sheet"})]})]}),Ue("div",{className:"card-subtle p-4",children:[Z("h3",{className:"mb-2 font-semibold",children:"Feedback"}),Ue("ul",{className:"space-y-1 text-muted-foreground text-sm",children:[Z("li",{children:"Alert"}),Z("li",{children:"Skeleton"}),Z("li",{children:"Progress"}),Z("li",{children:"Tooltip"})]})]})]})]}),Ue("div",{className:"card-subtle space-y-3 p-6",children:[Z("h2",{className:"font-bold text-2xl",children:"Where this layer fits"}),Ue("p",{className:"text-muted-foreground",children:["Read"," ",Z(Pr,{href:"/docs/libraries/cross-platform-ui",className:"text-[color:var(--rust)] underline underline-offset-4",children:"Cross-platform UI"})," ","for the full React and React Native compatibility model around this native-first primitive lane."]})]}),Ue("div",{className:"flex items-center gap-4 pt-4",children:[Z(Pr,{href:"/docs/libraries/schema",className:"btn-ghost",children:"Previous: Schema"}),Ue(Pr,{href:"/docs/libraries/ui-kit-web",className:"btn-primary",children:["Next: UI Kit Web ",Z(Oh,{size:16})]})]})]})}import{CodeBlock as Uh,InstallCommand as Wh}from"@contractspec/lib.design-system";import Tr from"@contractspec/lib.ui-link";import{ChevronRight as _h}from"lucide-react";import{jsx as ba,jsxs as no}from"react/jsx-runtime";var zh=`import { DataTable } from '@contractspec/lib.ui-kit-web/ui/data-table';
|
|
4258
4258
|
import { useContractTable } from '@contractspec/lib.presentation-runtime-react';
|
|
4259
4259
|
|
|
4260
4260
|
import { SHOWCASE_ROWS } from '@contractspec/example.data-grid-showcase/ui/data-grid-showcase.data';
|
|
@@ -4299,7 +4299,7 @@ export function WebAccountGrid() {
|
|
|
4299
4299
|
footer={\`Rows \${controller.totalItems}\`}
|
|
4300
4300
|
/>
|
|
4301
4301
|
);
|
|
4302
|
-
}`;function
|
|
4302
|
+
}`;function Gh(){return no("div",{className:"space-y-8",children:[no("div",{className:"space-y-4",children:[ba("h1",{className:"font-bold text-4xl",children:"@contractspec/lib.ui-kit-web"}),ba("p",{className:"text-muted-foreground",children:"Web-first React and Next primitives for ContractSpec. The canonical data-table example uses this package to render the raw browser table layer directly, without the design-system shell on top."})]}),no("div",{className:"space-y-4",children:[ba("h2",{className:"font-bold text-2xl",children:"Installation"}),ba(Wh,{package:"@contractspec/lib.ui-kit-web"})]}),no("div",{className:"space-y-4",children:[ba("h2",{className:"font-bold text-2xl",children:"Data table example"}),no("p",{className:"text-muted-foreground",children:["This is the raw browser lane from the canonical"," ",ba(Tr,{href:"/docs/examples/data-grid-showcase",className:"text-[color:var(--rust)] underline underline-offset-4",children:"Data Grid Showcase"}),". It demonstrates the primitive renderer with sorting, pagination, single selection, column visibility, column resizing, left/right pinning, row expansion, loading, and empty-state slots."]}),ba(Uh,{language:"tsx",filename:"web-account-grid.tsx",code:zh})]}),no("div",{className:"space-y-4",children:[ba("h2",{className:"font-bold text-2xl",children:"What this layer owns"}),no("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[ba("li",{children:"The raw table renderer and browser interaction model."}),ba("li",{children:"Pagination, column visibility menus, pin menus, resize handles, and empty/loading states."}),ba("li",{children:"Accessibility helpers and other web-specific primitives that stay outside the native-first package."})]})]}),no("div",{className:"card-subtle space-y-3 p-6",children:[ba("h2",{className:"font-bold text-2xl",children:"Where this layer fits"}),no("p",{className:"text-muted-foreground",children:["Read"," ",ba(Tr,{href:"/docs/libraries/cross-platform-ui",className:"text-[color:var(--rust)] underline underline-offset-4",children:"Cross-platform UI"})," ","for the shared runtime story behind the web and native render lanes."]})]}),no("div",{className:"flex items-center gap-4 pt-4",children:[ba(Tr,{href:"/docs/libraries/ui-kit",className:"btn-ghost",children:"Previous: UI Kit"}),no(Tr,{href:"/docs/libraries/design-system",className:"btn-primary",children:["Next: Design System ",ba(_h,{size:16})]})]})]})}import{CodeBlock as Cd,InstallCommand as qh}from"@contractspec/lib.design-system";import Id from"@contractspec/lib.ui-link";import{ChevronRight as Hh}from"lucide-react";import{jsx as Co,jsxs as mi}from"react/jsx-runtime";function Vh(){return mi("div",{className:"space-y-8",children:[mi("div",{className:"space-y-4",children:[Co("h1",{className:"font-bold text-4xl",children:"Workflow Composer"}),Co("p",{className:"text-lg text-muted-foreground",children:"`@contractspec/lib.workflow-composer` injects tenant-/role-/device-specific steps into base WorkflowSpecs and keeps transitions valid."})]}),mi("div",{className:"space-y-4",children:[Co("h2",{className:"font-bold text-2xl",children:"Installation"}),Co(qh,{package:"@contractspec/lib.workflow-composer"})]}),mi("div",{className:"space-y-4",children:[Co("h2",{className:"font-bold text-2xl",children:"Register extensions"}),Co(Cd,{language:"typescript",code:`const composer = new WorkflowComposer();
|
|
4303
4303
|
|
|
4304
4304
|
composer.register({
|
|
4305
4305
|
workflow: 'billing.invoiceApproval',
|
|
@@ -4316,12 +4316,12 @@ composer.register({
|
|
|
4316
4316
|
},
|
|
4317
4317
|
],
|
|
4318
4318
|
hiddenSteps: ['internal-audit'],
|
|
4319
|
-
});`})]}),mi("div",{className:"space-y-4",children:[Co("h2",{className:"font-bold text-2xl",children:"Compose at runtime"}),Co(
|
|
4319
|
+
});`})]}),mi("div",{className:"space-y-4",children:[Co("h2",{className:"font-bold text-2xl",children:"Compose at runtime"}),Co(Cd,{language:"typescript",code:`const tenantWorkflow = composer.compose({
|
|
4320
4320
|
base: BaseInvoiceWorkflow,
|
|
4321
4321
|
tenantId: 'acme',
|
|
4322
4322
|
});
|
|
4323
4323
|
|
|
4324
|
-
workflowRunner.execute(tenantWorkflow, ctx);`})]}),mi("div",{className:"flex items-center gap-4 pt-4",children:[Co(
|
|
4324
|
+
workflowRunner.execute(tenantWorkflow, ctx);`})]}),mi("div",{className:"flex items-center gap-4 pt-4",children:[Co(Id,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),mi(Id,{href:"/docs/libraries/workflows",className:"btn-primary",children:["Next: Workflow Runtime ",Co(Hh,{size:16})]})]})]})}import{CodeBlock as Fh,InstallCommand as Kh}from"@contractspec/lib.design-system";import Pd from"@contractspec/lib.ui-link";import{ChevronRight as Qh}from"lucide-react";import{jsx as me,jsxs as Da}from"react/jsx-runtime";function Yh(){return Da("div",{className:"space-y-8",children:[Da("div",{className:"space-y-4",children:[me("h1",{className:"font-bold text-4xl",children:"Workflow Runtime Library"}),Da("p",{className:"text-lg text-muted-foreground",children:["The ",me("code",{children:"@contractspec/lib.contracts-spec/workflow"})," library provides the core ",me("code",{children:"WorkflowRunner"})," for executing stateful, durable workflows."]})]}),Da("div",{className:"space-y-4",children:[me("h2",{className:"font-bold text-2xl",children:"Installation"}),me(Kh,{package:"@contractspec/lib.contracts-spec"})]}),Da("div",{className:"space-y-4",children:[me("h2",{className:"font-bold text-2xl",children:"WorkflowRunner"}),me("p",{className:"text-muted-foreground",children:"The runner manages execution state, step transitions, retries, and compensation."}),me(Fh,{language:"typescript",code:`import { WorkflowRunner } from '@contractspec/lib.contracts-spec/workflow/runner';
|
|
4325
4325
|
import { InMemoryStateStore } from '@contractspec/lib.contracts-spec/workflow/adapters/memory-store';
|
|
4326
4326
|
import { WorkflowRegistry } from '@contractspec/lib.contracts-spec/workflow/spec';
|
|
4327
4327
|
|
|
@@ -4341,7 +4341,7 @@ const runner = new WorkflowRunner({
|
|
|
4341
4341
|
const workflowId = await runner.start('my.workflow', 1, { userId: '123' });
|
|
4342
4342
|
|
|
4343
4343
|
// Execute next step (usually called by a worker or queue consumer)
|
|
4344
|
-
await runner.executeStep(workflowId);`})]}),Da("div",{className:"space-y-4",children:[me("h2",{className:"font-bold text-2xl",children:"State Persistence"}),Da("p",{className:"text-muted-foreground",children:["The runner relies on a ",me("code",{children:"StateStore"})," to persist workflow execution history. ContractSpec ships with:"]}),Da("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[Da("li",{children:[me("code",{children:"InMemoryStateStore"})," - for testing and development."]}),Da("li",{children:[me("code",{children:"PrismaStateStore"})," - for production using Prisma ORM."]})]})]}),Da("div",{className:"space-y-4",children:[me("h2",{className:"font-bold text-2xl",children:"Events"}),me("p",{className:"text-muted-foreground",children:"The runner emits events that you can subscribe to for monitoring:"}),Da("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[me("li",{children:me("code",{children:"workflow.started"})}),me("li",{children:me("code",{children:"workflow.step_completed"})}),me("li",{children:me("code",{children:"workflow.step_failed"})}),me("li",{children:me("code",{children:"workflow.step_retrying"})}),me("li",{children:me("code",{children:"workflow.completed"})}),me("li",{children:me("code",{children:"workflow.cancelled"})}),me("li",{children:me("code",{children:"workflow.compensation_step_completed"})})]})]}),Da("div",{className:"flex items-center gap-4 pt-4",children:[me(
|
|
4344
|
+
await runner.executeStep(workflowId);`})]}),Da("div",{className:"space-y-4",children:[me("h2",{className:"font-bold text-2xl",children:"State Persistence"}),Da("p",{className:"text-muted-foreground",children:["The runner relies on a ",me("code",{children:"StateStore"})," to persist workflow execution history. ContractSpec ships with:"]}),Da("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[Da("li",{children:[me("code",{children:"InMemoryStateStore"})," - for testing and development."]}),Da("li",{children:[me("code",{children:"PrismaStateStore"})," - for production using Prisma ORM."]})]})]}),Da("div",{className:"space-y-4",children:[me("h2",{className:"font-bold text-2xl",children:"Events"}),me("p",{className:"text-muted-foreground",children:"The runner emits events that you can subscribe to for monitoring:"}),Da("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[me("li",{children:me("code",{children:"workflow.started"})}),me("li",{children:me("code",{children:"workflow.step_completed"})}),me("li",{children:me("code",{children:"workflow.step_failed"})}),me("li",{children:me("code",{children:"workflow.step_retrying"})}),me("li",{children:me("code",{children:"workflow.completed"})}),me("li",{children:me("code",{children:"workflow.cancelled"})}),me("li",{children:me("code",{children:"workflow.compensation_step_completed"})})]})]}),Da("div",{className:"flex items-center gap-4 pt-4",children:[me(Pd,{href:"/docs/libraries",className:"btn-ghost",children:"Back to Libraries"}),Da(Pd,{href:"/docs/libraries/data-views",className:"btn-primary",children:["Next: Data Views ",me(Qh,{size:16})]})]})]})}import{jsx as co,jsxs as ui}from"react/jsx-runtime";function Jh(){return ui("div",{className:"space-y-8",children:[ui("div",{className:"space-y-3",children:[co("p",{className:"editorial-kicker",children:"Why ContractSpec"}),co("h1",{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"Open system, explicit contracts, incremental adoption."}),co("p",{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:"ContractSpec exists to make AI-native software more legible and more governable. The system should help teams express durable boundaries, keep generated surfaces aligned, and still own the code and contracts they ship."})]}),ui("div",{className:"space-y-6",children:[ui("section",{className:"editorial-panel space-y-3",children:[co("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Open system, not closed platform"}),co("p",{className:"text-muted-foreground text-sm leading-7",children:"The OSS layer should remain useful on its own. Teams need explicit contracts, readable code, and outputs they can keep. Studio can sit on top of that system, but it should never be the only way to own or understand the behavior."})]}),ui("section",{className:"editorial-panel space-y-3",children:[co("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Contracts before surface sprawl"}),co("p",{className:"text-muted-foreground text-sm leading-7",children:"AI tooling accelerates surface creation faster than most teams can govern it. The answer is not more hidden glue. The answer is a durable contract layer that keeps API, UI, data, workflows, and operator behavior aligned."})]}),ui("section",{className:"editorial-panel space-y-3",children:[co("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Incremental adoption wins"}),co("p",{className:"text-muted-foreground text-sm leading-7",children:"Most teams already have a codebase. The practical path is to stabilize one boundary at a time, prove the loop, and grow from there. That is why the docs and product should lead with one module, one endpoint, one workflow, one unsafe surface at a time."})]}),ui("section",{className:"editorial-panel space-y-3",children:[co("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Studio should stay additive"}),co("p",{className:"text-muted-foreground text-sm leading-7",children:"The best operating product can and should exist on top of the open system. But the OSS foundation must remain strong enough that technical adopters trust it before they ever adopt Studio."})]})]})]})}import{jsx as dt,jsxs as oi}from"react/jsx-runtime";function Zh(){return oi("div",{className:"space-y-8",children:[oi("div",{className:"space-y-4",children:[dt("h1",{className:"font-bold text-4xl",children:"Auto-Evolution Runbook"}),dt("p",{className:"text-lg text-muted-foreground",children:"Configure sampling, approvals, experiments, and golden tests so your app keeps improving without regressions."})]}),oi("div",{className:"space-y-3",children:[dt("h2",{className:"font-bold text-2xl",children:"Pipeline overview"}),oi("ol",{className:"list-decimal space-y-2 pl-6 text-muted-foreground text-sm",children:[dt("li",{children:"Tracing middleware emits telemetry samples with tenant/user context."}),dt("li",{children:"IntentAggregator batches samples (15m window, configurable)."}),dt("li",{children:"IntentDetector raises error/latency/throughput signals."}),dt("li",{children:"SpecGenerator produces proposals with confidence scores."}),dt("li",{children:"ApprovalWorkflow routes low-confidence suggestions to humans."}),dt("li",{children:"SpecExperimentRegistry rolls out approved variants using guardrails."}),dt("li",{children:"TrafficRecorder captures new traffic and GoldenTestGenerator outputs suites."})]})]}),oi("div",{className:"space-y-3",children:[dt("h2",{className:"font-bold text-2xl",children:"Key environment variables"}),dt("pre",{className:"rounded-lg border bg-muted p-4 text-sm",children:`# Telemetry sampling
|
|
4345
4345
|
AUTO_EVOLUTION_SAMPLE_RATE=0.02
|
|
4346
4346
|
AUTO_EVOLUTION_WINDOW_MS=900000
|
|
4347
4347
|
|
|
@@ -4351,15 +4351,15 @@ AUTO_EVOLUTION_AUTO_APPROVE=0.2
|
|
|
4351
4351
|
|
|
4352
4352
|
# Guardrails (fallback defaults)
|
|
4353
4353
|
AUTO_EVOLUTION_MAX_ERROR_RATE=0.02
|
|
4354
|
-
AUTO_EVOLUTION_MAX_P99_MS=500`})]}),oi("div",{className:"space-y-3",children:[dt("h2",{className:"font-bold text-2xl",children:"Operations checklist"}),oi("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground text-sm",children:[dt("li",{children:"Review new `SpecSuggestion` records every morning (UI coming soon; Prisma view today)."}),dt("li",{children:"Keep at least one reviewer per domain on-call for approvals."}),dt("li",{children:"Attach `SpecExperimentAdapter.trackOutcome` to every runtime adapter."}),dt("li",{children:"Schedule `contractspec test generate` nightly (or on deploy) to refresh golden suites."}),dt("li",{children:"Feed `runGoldenTests` into CI to gate merges touching evolved specs."})]})]}),dt("div",{className:"grid gap-4 md:grid-cols-3",children:[{title:"Sampling",description:"Start at 1–2% of traffic. Increase only after sanitization is verified."},{title:"Approvals",description:"High-risk ops (money, compliance) should never auto-approve. Use ApprovalWorkflow notes for audit."},{title:"On-call alerts",description:"Tie SpecExperimentController rollbacks into PagerDuty/Slack so engineers see guardrail trips immediately."}].map((e)=>oi("div",{className:"card-subtle space-y-2 p-4",children:[dt("h3",{className:"font-semibold text-lg",children:e.title}),dt("p",{className:"text-muted-foreground text-sm",children:e.description})]},e.title))})]})}import{jsx as lo,jsxs as xi}from"react/jsx-runtime";function
|
|
4354
|
+
AUTO_EVOLUTION_MAX_P99_MS=500`})]}),oi("div",{className:"space-y-3",children:[dt("h2",{className:"font-bold text-2xl",children:"Operations checklist"}),oi("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground text-sm",children:[dt("li",{children:"Review new `SpecSuggestion` records every morning (UI coming soon; Prisma view today)."}),dt("li",{children:"Keep at least one reviewer per domain on-call for approvals."}),dt("li",{children:"Attach `SpecExperimentAdapter.trackOutcome` to every runtime adapter."}),dt("li",{children:"Schedule `contractspec test generate` nightly (or on deploy) to refresh golden suites."}),dt("li",{children:"Feed `runGoldenTests` into CI to gate merges touching evolved specs."})]})]}),dt("div",{className:"grid gap-4 md:grid-cols-3",children:[{title:"Sampling",description:"Start at 1–2% of traffic. Increase only after sanitization is verified."},{title:"Approvals",description:"High-risk ops (money, compliance) should never auto-approve. Use ApprovalWorkflow notes for audit."},{title:"On-call alerts",description:"Tie SpecExperimentController rollbacks into PagerDuty/Slack so engineers see guardrail trips immediately."}].map((e)=>oi("div",{className:"card-subtle space-y-2 p-4",children:[dt("h3",{className:"font-semibold text-lg",children:e.title}),dt("p",{className:"text-muted-foreground text-sm",children:e.description})]},e.title))})]})}import{jsx as lo,jsxs as xi}from"react/jsx-runtime";function $h(){return xi("div",{className:"space-y-8",children:[xi("div",{className:"space-y-4",children:[lo("h1",{className:"font-bold text-4xl",children:"Distributed Tracing"}),lo("p",{className:"text-lg text-muted-foreground",children:"ContractSpec uses OpenTelemetry (OTel) for distributed tracing. This guide explains how to configure exporters and collectors."})]}),xi("div",{className:"space-y-4",children:[lo("h2",{className:"font-bold text-2xl",children:"Configuration"}),lo("p",{children:"Configure the OTel SDK via environment variables:"}),lo("pre",{className:"rounded-lg border bg-muted p-4 text-sm",children:`OTEL_SERVICE_NAME=my-service
|
|
4355
4355
|
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
|
|
4356
4356
|
OTEL_TRACES_SAMPLER=parentbased_traceidratio
|
|
4357
|
-
OTEL_TRACES_SAMPLER_ARG=0.1`})]}),xi("div",{className:"space-y-4",children:[lo("h2",{className:"font-bold text-2xl",children:"Exporters"}),lo("p",{children:"By default, the OTLP exporter is used. You can point it to:"}),xi("ul",{className:"list-disc space-y-2 pl-6",children:[lo("li",{children:"Jaeger"}),lo("li",{children:"Tempo (Grafana)"}),lo("li",{children:"Honeycomb"}),lo("li",{children:"Datadog (via OTel Collector)"})]})]})]})}import{DocsIndexDataView as
|
|
4357
|
+
OTEL_TRACES_SAMPLER_ARG=0.1`})]}),xi("div",{className:"space-y-4",children:[lo("h2",{className:"font-bold text-2xl",children:"Exporters"}),lo("p",{children:"By default, the OTLP exporter is used. You can point it to:"}),xi("ul",{className:"list-disc space-y-2 pl-6",children:[lo("li",{children:"Jaeger"}),lo("li",{children:"Tempo (Grafana)"}),lo("li",{children:"Honeycomb"}),lo("li",{children:"Datadog (via OTel Collector)"})]})]})]})}import{DocsIndexDataView as Xh,DocsSearchForm as xh}from"@contractspec/lib.contracts-spec/docs";import{DataViewList as jh,formRenderer as ey,StatusChip as Nn}from"@contractspec/lib.design-system";import{HStack as ty,VStack as wn}from"@contractspec/lib.ui-kit-web/ui/stack";import{H1 as ay,Muted as Td}from"@contractspec/lib.ui-kit-web/ui/typography";import{useMemo as Ad,useState as oy}from"react";import{jsx as ii,jsxs as kn}from"react/jsx-runtime";function iy(e){if(!e)return;return e.replace(/<!--.*?-->/g,"").replace(/[ \t]+/g," ").replace(/\n{3,}/g,`
|
|
4358
4358
|
|
|
4359
|
-
`).trim()}function
|
|
4360
|
-
`)});continue}if(/^#{1,4}\s+/.test(b)){let v=b.match(/^#{1,4}/)?.[0].length??2;a.push({type:"heading",level:v,text:b.replace(/^#{1,4}\s+/,"")}),r+=1;continue}if(/^>\s+/.test(b)){let v=[];while(r<t.length&&/^>\s+/.test((t[r]??"").trim()))v.push((t[r]??"").trim().replace(/^>\s+/,"")),r+=1;a.push({type:"quote",text:v.join(" ")});continue}if(/^[-*]\s+/.test(b)||/^\d+\.\s+/.test(b)){let v=/^\d+\.\s+/.test(b),V=[];while(r<t.length&&
|
|
4359
|
+
`).trim()}function ry(e){let t=iy(e.summary),a=e.kind??(e.source==="generated"?"reference":void 0),r=e.visibility??(e.source==="generated"?"public":void 0);return{...e,summary:t,kind:a,visibility:r}}function ny(e,t){if(!t)return!0;return[e.title,e.summary,e.id,...e.tags??[]].filter(Boolean).join(" ").toLowerCase().includes(t.toLowerCase())}function Rd({entries:e}){let[t,a]=oy({}),r=Ad(()=>e.map(ry),[e]),l=Ad(()=>{let h=t.query?.trim()??"";return r.filter((v)=>{if(t.kind&&v.kind!==t.kind)return!1;if(t.visibility&&v.visibility!==t.visibility)return!1;return ny(v,h)})},[t,r]),b=ey.render(xh,{defaultValues:{query:t.query??"",visibility:t.visibility??"",kind:t.kind??""},overrides:{onSubmitOverride:(h)=>{let v=h;a({query:v.query??"",visibility:v.visibility??"",kind:v.kind??""})}}});return kn(wn,{gap:"xl",children:[kn(wn,{gap:"sm",children:[ii(ay,{children:"Reference"}),ii(Td,{children:"Generated reference material for public contract surfaces, versions, owners, and example-backed implementations. Use this when you need the repo truth, not just the narrative docs layer."})]}),ii(wn,{gap:"sm",className:"max-w-2xl",children:b}),ii(jh,{spec:Xh,items:l,emptyState:ii(Td,{children:"No reference docs match your filters."}),onSelect:(h)=>{if(h.route)window.location.assign(h.route)},renderActions:(h)=>{return kn(ty,{gap:"xs",justify:"end",children:[h.kind?ii(Nn,{size:"sm",label:h.kind}):null,h.visibility?ii(Nn,{size:"sm",label:h.visibility}):null,h.version?ii(Nn,{size:"sm",label:`v${h.version}`}):null]})}})]})}import{jsx as ly}from"react/jsx-runtime";async function cy(){let e=await Gc();return ly(Rd,{entries:e})}var dy=/^##\s+Metadata[\s\S]*?(?=^##\s|^#\s|Z)/m;function sy(e){return e.replace(/^#\s+.*\n+/m,"").replace(dy,"")}function Ld(e){return/^#{1,4}\s+/.test(e)||/^```/.test(e)||/^\s*[-*]\s+/.test(e)||/^\s*\d+\.\s+/.test(e)||/^>\s+/.test(e)}function Dd(e){let t=sy(e).split(/\r?\n/),a=[],r=0;while(r<t.length){let l=t[r]??"";if(l.startsWith("<!-- @generated")){r+=1;continue}let b=l.trim();if(!b){r+=1;continue}if(b.startsWith("```")){let v=b.slice(3).trim(),V=[];r+=1;while(r<t.length&&!(t[r]??"").trim().startsWith("```"))V.push(t[r]??""),r+=1;r+=1,a.push({type:"code",language:v||"text",code:V.join(`
|
|
4360
|
+
`)});continue}if(/^#{1,4}\s+/.test(b)){let v=b.match(/^#{1,4}/)?.[0].length??2;a.push({type:"heading",level:v,text:b.replace(/^#{1,4}\s+/,"")}),r+=1;continue}if(/^>\s+/.test(b)){let v=[];while(r<t.length&&/^>\s+/.test((t[r]??"").trim()))v.push((t[r]??"").trim().replace(/^>\s+/,"")),r+=1;a.push({type:"quote",text:v.join(" ")});continue}if(/^[-*]\s+/.test(b)||/^\d+\.\s+/.test(b)){let v=/^\d+\.\s+/.test(b),V=[];while(r<t.length&&Ld((t[r]??"").trim())){let g=(t[r]??"").trim();if(v&&/^\d+\.\s+/.test(g))V.push(g.replace(/^\d+\.\s+/,""));else if(!v&&/^[-*]\s+/.test(g))V.push(g.replace(/^[-*]\s+/,""));else break;r+=1}a.push({type:"list",ordered:v,items:V});continue}let h=[];while(r<t.length&&!Ld((t[r]??"").trim())){let v=(t[r]??"").trim();if(!v)break;h.push(v),r+=1}a.push({type:"paragraph",text:h.join(" ")})}return a}import{CodeBlock as py}from"@contractspec/lib.design-system";import{HStack as my,VStack as Sn}from"@contractspec/lib.ui-kit-web/ui/stack";import{BlockQuote as uy,H2 as gy,H3 as fy,H4 as hy,Muted as Ed,P as Od}from"@contractspec/lib.ui-kit-web/ui/typography";import{jsx as Za,jsxs as Ny}from"react/jsx-runtime";var yy=new Set(["typescript","tsx","javascript","jsx","bash","shell","json","yaml","graphql","sql","python","go","rust","css","scss","html","markdown","text"]);function by(e){if(!e)return"text";let t=e.toLowerCase();return yy.has(t)?t:"text"}function vy(e,t){if(e<=2)return Za(gy,{children:t});if(e===3)return Za(fy,{children:t});return Za(hy,{children:t})}function Bd({content:e}){let t=Dd(e);if(!t.length)return Za(Ed,{children:"No reference content available."});return Za(Sn,{gap:"md",children:t.map((a,r)=>{switch(a.type){case"heading":return Za(Sn,{children:vy(a.level,a.text)},r);case"paragraph":return Za(Od,{children:a.text},r);case"quote":return Za(uy,{children:a.text},r);case"code":return Za(py,{language:by(a.language),code:a.code},r);case"list":return Za(Sn,{gap:"xs",children:a.items.map((l,b)=>Ny(my,{gap:"sm",align:"start",children:[Za(Ed,{children:a.ordered?`${b+1}.`:"•"}),Za(Od,{className:"leading-relaxed",children:l})]},b))},r);default:return null}})})}import{ContractReferenceDataView as Ar}from"@contractspec/lib.contracts-spec/docs";import{DataViewRenderer as wy}from"@contractspec/lib.design-system";import{VStack as ky}from"@contractspec/lib.ui-kit-web/ui/stack";import{jsx as Md,jsxs as Cy}from"react/jsx-runtime";function ji(e,t){return e.match(new RegExp(`- \\*\\*${t}\\*\\*: (.+)`,"i"))?.[1]?.trim()}function Sy(e){if(!e)return;return e.replace(/<!--.*?-->/g,"").replace(/[ \t]+/g," ").replace(/\n{3,}/g,`
|
|
4361
4361
|
|
|
4362
|
-
`).trim()}function
|
|
4362
|
+
`).trim()}function Ud({entry:e,content:t}){let a=Sy(e.summary),r=ji(t,"Type"),l=ji(t,"Version")??e.version,b=ji(t,"Tags")?.split(",").map((tt)=>tt.trim()).filter(Boolean),h=ji(t,"Owners")?.split(",").map((tt)=>tt.trim()).filter(Boolean),v=ji(t,"Stability")??e.visibility,V={reference:{key:e.title??e.id,version:l,type:r,title:e.title??e.id,description:a,tags:b??e.tags,owners:h??e.owners,stability:v}},g={...Ar,meta:{...Ar.meta,title:e.title??Ar.meta.title,description:a??Ar.meta.description}};return Cy(ky,{gap:"xl",children:[Md(wy,{spec:g,item:V}),Md(Bd,{content:t})]})}import{jsx as Py}from"react/jsx-runtime";function Iy({entry:e,content:t}){return Py(Ud,{entry:e,content:t})}import Cn from"@contractspec/lib.ui-link";import{ChevronRight as Ty}from"lucide-react";import{jsx as L,jsxs as oe}from"react/jsx-runtime";function Ay(){return oe("div",{className:"space-y-8",children:[oe("div",{className:"space-y-4",children:[L("h1",{className:"font-bold text-4xl",children:"Audit Logs"}),oe("p",{className:"text-muted-foreground",children:["An ",L("strong",{children:"audit log"})," (also called an audit trail) is a chronological record of system activities. According to"," ",L("a",{href:"https://www.sumologic.com/glossary/audit-log/",target:"_blank",rel:"noopener noreferrer",className:"text-violet-400 hover:text-violet-300",children:"Sumo Logic"}),', audit logs "provide a detailed record of events and changes within a system, enabling organizations to track user actions, system changes, and access to sensitive data."']})]}),oe("div",{className:"space-y-4",children:[L("h2",{className:"font-bold text-2xl",children:"Why audit logs matter"}),oe("div",{className:"space-y-3",children:[oe("div",{children:[L("h3",{className:"font-semibold text-lg",children:"Accountability"}),L("p",{className:"text-muted-foreground",children:'Audit logs answer the question "who did what, when?" This is essential for holding users and administrators accountable for their actions. If data is deleted or modified, the audit log shows exactly who made the change.'})]}),oe("div",{children:[L("h3",{className:"font-semibold text-lg",children:"Security"}),L("p",{className:"text-muted-foreground",children:"Audit logs help detect and investigate security incidents. For example, if an attacker gains unauthorized access, the logs reveal which resources they accessed and what actions they performed. This information is critical for incident response and forensics."})]}),oe("div",{children:[L("h3",{className:"font-semibold text-lg",children:"Compliance"}),L("p",{className:"text-muted-foreground",children:"Many regulations (GDPR, HIPAA, SOC 2, PCI DSS) require organizations to maintain audit logs. These logs must be tamper-evident, retained for a specified period, and available for inspection by auditors."})]}),oe("div",{children:[L("h3",{className:"font-semibold text-lg",children:"Debugging"}),L("p",{className:"text-muted-foreground",children:"When something goes wrong in production, audit logs provide a detailed timeline of events leading up to the failure. This makes it much easier to diagnose and fix issues."})]})]})]}),oe("div",{className:"space-y-4",children:[L("h2",{className:"font-bold text-2xl",children:"What ContractSpec logs"}),L("p",{className:"text-muted-foreground",children:"ContractSpec automatically logs every significant operation, including:"}),oe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[oe("li",{children:[L("strong",{children:"API calls"})," – Every invocation of a capability, including inputs, outputs, and the user who made the call."]}),oe("li",{children:[L("strong",{children:"Policy decisions"})," – Every decision made by the"," ",L(Cn,{href:"/docs/safety/pdp",className:"text-violet-400 hover:text-violet-300",children:"Policy Decision Point"}),", including the rule that matched and the reason for the decision."]}),oe("li",{children:[L("strong",{children:"Data access"})," – Every query to a data view, including which fields were accessed and whether any were redacted."]}),oe("li",{children:[L("strong",{children:"Workflow execution"})," – Every step in a workflow, including retries, compensations, and failures."]}),oe("li",{children:[L("strong",{children:"Administrative actions"})," – Spec deployments, configuration changes, user role assignments, and other privileged operations."]}),oe("li",{children:[L("strong",{children:"Authentication events"})," – Login attempts, password resets, and session expirations."]})]})]}),oe("div",{className:"space-y-4",children:[L("h2",{className:"font-bold text-2xl",children:"Audit log format"}),L("p",{className:"text-muted-foreground",children:"Each audit log entry is a structured JSON object containing:"}),L("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:L("pre",{children:`{
|
|
4363
4363
|
"timestamp": "2025-11-13T14:32:15.123Z",
|
|
4364
4364
|
"eventId": "evt_abc123",
|
|
4365
4365
|
"eventType": "capability.invoked",
|
|
@@ -4390,7 +4390,7 @@ OTEL_TRACES_SAMPLER_ARG=0.1`})]}),xi("div",{className:"space-y-4",children:[lo("
|
|
|
4390
4390
|
"ruleId": "allow-admin-transfers",
|
|
4391
4391
|
"reason": "User has admin role"
|
|
4392
4392
|
}
|
|
4393
|
-
}`})})]}),oe("div",{className:"space-y-4",children:[L("h2",{className:"font-bold text-2xl",children:"Storage and retention"}),L("p",{className:"text-muted-foreground",children:"Audit logs are stored in a tamper-evident append-only log. Once written, entries cannot be modified or deleted. This ensures the integrity of the audit trail."}),L("p",{className:"text-muted-foreground",children:"ContractSpec supports multiple storage backends:"}),oe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[oe("li",{children:[L("strong",{children:"Local file system"})," – For development and testing."]}),oe("li",{children:[L("strong",{children:"Cloud object storage"})," – S3, GCS, or Azure Blob Storage for production."]}),oe("li",{children:[L("strong",{children:"SIEM integration"})," – Forward logs to Splunk, Datadog, or other security information and event management systems."]})]}),L("p",{className:"text-muted-foreground",children:"You can configure retention policies to automatically archive or delete old logs after a specified period (e.g., 7 years for GDPR compliance)."})]}),oe("div",{className:"space-y-4",children:[L("h2",{className:"font-bold text-2xl",children:"Querying audit logs"}),L("p",{className:"text-muted-foreground",children:"ContractSpec provides a query API for searching audit logs. You can filter by:"}),oe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[L("li",{children:"Time range"}),L("li",{children:"Event type"}),L("li",{children:"Actor (user ID, role, IP address)"}),L("li",{children:"Resource (capability, data view, workflow)"}),L("li",{children:"Result (success, failure, denied)"})]}),L("p",{className:"text-muted-foreground",children:'Example query: "Show all failed login attempts from IP address 203.0.113.42 in the last 24 hours."'})]}),oe("div",{className:"space-y-4",children:[L("h2",{className:"font-bold text-2xl",children:"Best practices"}),oe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[oe("li",{children:[L("strong",{children:"Review logs regularly"})," – Set up alerts for suspicious activity (e.g., repeated failed login attempts, unauthorized access attempts)."]}),oe("li",{children:[L("strong",{children:"Protect log access"})," – Only authorized personnel should be able to view audit logs. Use role-based access control to restrict access."]}),oe("li",{children:[L("strong",{children:"Retain logs long enough"})," – Check your compliance requirements and configure retention policies accordingly."]}),oe("li",{children:[L("strong",{children:"Test log integrity"})," – Periodically verify that logs have not been tampered with by checking cryptographic signatures."]})]})]}),oe("div",{className:"flex items-center gap-4 pt-4",children:[L(
|
|
4393
|
+
}`})})]}),oe("div",{className:"space-y-4",children:[L("h2",{className:"font-bold text-2xl",children:"Storage and retention"}),L("p",{className:"text-muted-foreground",children:"Audit logs are stored in a tamper-evident append-only log. Once written, entries cannot be modified or deleted. This ensures the integrity of the audit trail."}),L("p",{className:"text-muted-foreground",children:"ContractSpec supports multiple storage backends:"}),oe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[oe("li",{children:[L("strong",{children:"Local file system"})," – For development and testing."]}),oe("li",{children:[L("strong",{children:"Cloud object storage"})," – S3, GCS, or Azure Blob Storage for production."]}),oe("li",{children:[L("strong",{children:"SIEM integration"})," – Forward logs to Splunk, Datadog, or other security information and event management systems."]})]}),L("p",{className:"text-muted-foreground",children:"You can configure retention policies to automatically archive or delete old logs after a specified period (e.g., 7 years for GDPR compliance)."})]}),oe("div",{className:"space-y-4",children:[L("h2",{className:"font-bold text-2xl",children:"Querying audit logs"}),L("p",{className:"text-muted-foreground",children:"ContractSpec provides a query API for searching audit logs. You can filter by:"}),oe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[L("li",{children:"Time range"}),L("li",{children:"Event type"}),L("li",{children:"Actor (user ID, role, IP address)"}),L("li",{children:"Resource (capability, data view, workflow)"}),L("li",{children:"Result (success, failure, denied)"})]}),L("p",{className:"text-muted-foreground",children:'Example query: "Show all failed login attempts from IP address 203.0.113.42 in the last 24 hours."'})]}),oe("div",{className:"space-y-4",children:[L("h2",{className:"font-bold text-2xl",children:"Best practices"}),oe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[oe("li",{children:[L("strong",{children:"Review logs regularly"})," – Set up alerts for suspicious activity (e.g., repeated failed login attempts, unauthorized access attempts)."]}),oe("li",{children:[L("strong",{children:"Protect log access"})," – Only authorized personnel should be able to view audit logs. Use role-based access control to restrict access."]}),oe("li",{children:[L("strong",{children:"Retain logs long enough"})," – Check your compliance requirements and configure retention policies accordingly."]}),oe("li",{children:[L("strong",{children:"Test log integrity"})," – Periodically verify that logs have not been tampered with by checking cryptographic signatures."]})]})]}),oe("div",{className:"flex items-center gap-4 pt-4",children:[L(Cn,{href:"/docs/safety/pdp",className:"btn-ghost",children:"Previous: Policy Decision Points"}),oe(Cn,{href:"/docs/safety/migrations",className:"btn-primary",children:["Next: Migrations ",L(Ty,{size:16})]})]})]})}import Wd from"@contractspec/lib.ui-link";import{ChevronRight as Ry}from"lucide-react";import{jsx as I,jsxs as ce}from"react/jsx-runtime";function Ly(){return ce("div",{className:"space-y-8",children:[ce("div",{className:"space-y-4",children:[I("h1",{className:"font-bold text-4xl",children:"Migrations"}),ce("p",{className:"text-muted-foreground",children:["A ",I("strong",{children:"schema migration"})," (also called a database migration) is a set of incremental, reversible changes to a database schema. According to"," ",I("a",{href:"https://en.wikipedia.org/wiki/Schema_migration",target:"_blank",rel:"noopener noreferrer",className:"text-violet-400 hover:text-violet-300",children:"Wikipedia"}),`, schema migrations "allow the database schema to evolve as the application's requirements change, while preserving existing data."`]})]}),ce("div",{className:"space-y-4",children:[I("h2",{className:"font-bold text-2xl",children:"Why migrations matter"}),I("p",{className:"text-muted-foreground",children:"As your application evolves, you'll need to change your data model—adding new fields, renaming tables, changing data types, or restructuring relationships. Without a disciplined approach, these changes can lead to:"}),ce("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[I("li",{children:"Data loss or corruption"}),I("li",{children:"Downtime during deployments"}),I("li",{children:"Inconsistencies between environments (dev, staging, production)"}),I("li",{children:"Difficulty rolling back failed changes"})]}),I("p",{className:"text-muted-foreground",children:"Migrations solve these problems by treating schema changes as versioned, tested, and reversible operations."})]}),ce("div",{className:"space-y-4",children:[I("h2",{className:"font-bold text-2xl",children:"How MigrationSpec works"}),ce("p",{className:"text-muted-foreground",children:["In ContractSpec, migrations are defined using"," ",I("strong",{children:"MigrationSpec"}),". Each migration has:"]}),ce("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[ce("li",{children:[I("strong",{children:"Version"}),' – A unique identifier (e.g., "2025-11-13-001") that determines the order of execution.']}),ce("li",{children:[I("strong",{children:"Up function"}),` – The forward migration that applies the change (e.g., "add column 'email_verified'").`]}),ce("li",{children:[I("strong",{children:"Down function"}),` – The reverse migration that undoes the change (e.g., "drop column 'email_verified'").`]}),ce("li",{children:[I("strong",{children:"Dependencies"})," – Other migrations that must run before this one."]}),ce("li",{children:[I("strong",{children:"Validation"}),' – Optional checks to ensure the migration succeeded (e.g., "verify all users have an email address").']})]})]}),ce("div",{className:"space-y-4",children:[I("h2",{className:"font-bold text-2xl",children:"Example MigrationSpec"}),I("p",{className:"text-muted-foreground",children:"Here's a migration that adds an email verification field to the users table:"}),I("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:I("pre",{children:`migrationId: add-email-verified
|
|
4394
4394
|
version: 2025-11-13-001
|
|
4395
4395
|
dependencies: []
|
|
4396
4396
|
|
|
@@ -4413,7 +4413,7 @@ validation:
|
|
|
4413
4413
|
- sql: |
|
|
4414
4414
|
SELECT COUNT(*) FROM users
|
|
4415
4415
|
WHERE email_verified IS NULL;
|
|
4416
|
-
expectZeroRows: true`})})]}),ce("div",{className:"space-y-4",children:[I("h2",{className:"font-bold text-2xl",children:"Running migrations"}),I("p",{className:"text-muted-foreground",children:"Migrations are applied automatically during deployment. The ContractSpec runtime:"}),ce("ol",{className:"list-inside list-decimal space-y-2 text-muted-foreground",children:[I("li",{children:"Checks which migrations have already been applied (stored in a migrations table)."}),I("li",{children:"Identifies new migrations that need to run."}),I("li",{children:"Executes them in order, respecting dependencies."}),I("li",{children:"Runs validation checks to ensure success."}),I("li",{children:"Records the migration as applied."})]}),I("p",{className:"text-muted-foreground",children:"If a migration fails, the deployment is aborted, and the system remains in its previous state. You can then fix the migration and redeploy."})]}),ce("div",{className:"space-y-4",children:[I("h2",{className:"font-bold text-2xl",children:"Rolling back migrations"}),ce("p",{className:"text-muted-foreground",children:["If you need to roll back a deployment, ContractSpec automatically runs the ",I("strong",{children:"down"})," functions of any migrations that were applied. This restores the database to its previous state."]}),I("p",{className:"text-muted-foreground",children:"Note that rollbacks are not always possible—for example, if you've deleted a column, you cannot recover the data unless you have a backup. For destructive changes, it's best to use a multi-step migration:"}),ce("ol",{className:"list-inside list-decimal space-y-2 text-muted-foreground",children:[I("li",{children:"Add the new column (reversible)."}),I("li",{children:"Backfill data from the old column to the new column (reversible)."}),I("li",{children:"Update application code to use the new column (reversible)."}),I("li",{children:"Drop the old column (irreversible—only do this after confirming the new column works)."})]})]}),ce("div",{className:"space-y-4",children:[I("h2",{className:"font-bold text-2xl",children:"Best practices"}),ce("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[ce("li",{children:[I("strong",{children:"Test migrations locally"})," – Run them against a copy of production data to catch issues before deploying."]}),ce("li",{children:[I("strong",{children:"Keep migrations small"})," – Each migration should do one thing. This makes them easier to understand and roll back."]}),ce("li",{children:[I("strong",{children:"Write reversible migrations"})," – Always provide a down function, even if you don't plan to roll back."]}),ce("li",{children:[I("strong",{children:"Use transactions"})," – Wrap migrations in database transactions so they either fully succeed or fully fail."]}),ce("li",{children:[I("strong",{children:"Avoid destructive changes"})," – Prefer additive changes (adding columns) over destructive ones (dropping columns). If you must delete data, archive it first."]}),ce("li",{children:[I("strong",{children:"Version your migrations"})," – Use timestamps or sequential numbers to ensure migrations run in the correct order."]}),ce("li",{children:[I("strong",{children:"Document breaking changes"})," – If a migration requires application code changes, note this in the migration description."]})]})]}),ce("div",{className:"space-y-4",children:[I("h2",{className:"font-bold text-2xl",children:"Zero-downtime migrations"}),I("p",{className:"text-muted-foreground",children:"Some migrations can cause downtime if not handled carefully. For example, adding a NOT NULL column to a large table can lock the table for minutes. To avoid this, use a multi-step approach:"}),ce("ol",{className:"list-inside list-decimal space-y-2 text-muted-foreground",children:[I("li",{children:"Add the column as nullable."}),I("li",{children:"Backfill the column in batches (without locking the table)."}),I("li",{children:"Add the NOT NULL constraint once all rows are populated."})]}),I("p",{className:"text-muted-foreground",children:"ContractSpec's migration system supports this pattern by allowing you to split a logical change into multiple versioned migrations."})]}),ce("div",{className:"flex items-center gap-4 pt-4",children:[I(Bd,{href:"/docs/safety/auditing",className:"btn-ghost",children:"Previous: Audit Logs"}),ce(Bd,{href:"/docs/advanced/renderers",className:"btn-primary",children:["Next: Advanced Topics ",I(Cy,{size:16})]})]})]})}import Py from"@contractspec/lib.ui-link";import{jsx as _o,jsxs as er}from"react/jsx-runtime";var Ty=[{title:"Spec signing",body:"Protect the integrity of what gets deployed and make changes verifiable.",href:"/docs/safety/signing"},{title:"Policy decision points",body:"Apply governance consistently across operations, data access, and generated surfaces.",href:"/docs/safety/pdp"},{title:"Audit trails",body:"Record operational and policy decisions with enough context to inspect and explain them later.",href:"/docs/safety/auditing"},{title:"Migrations",body:"Evolve data and schema boundaries without losing control of the system.",href:"/docs/safety/migrations"},{title:"Tenant isolation",body:"Keep configuration, access rules, and sensitive data bounded by tenant.",href:"/docs/safety/tenant-isolation"},{title:"Security and trust",body:"Understand the trust model, release process, and security expectations around the OSS system.",href:"/docs/safety/security-trust"}];function Ay(){return er("div",{className:"space-y-10",children:[er("div",{className:"space-y-3",children:[_o("p",{className:"editorial-kicker",children:"Operate"}),_o("h1",{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"Safety is part of the system model, not an afterthought."}),_o("p",{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:"ContractSpec is meant to survive real change: new generated surfaces, policy updates, migrations, integration churn, and operator handoffs. The safety layer makes those changes inspectable, reversible, and governed."})]}),er("div",{className:"editorial-proof-strip",children:[er("div",{className:"editorial-stat",children:[_o("span",{className:"editorial-label",children:"Operating rule"}),_o("span",{className:"editorial-stat-value",children:"explicit change beats hidden mutation"})]}),_o("p",{className:"max-w-2xl text-muted-foreground text-sm leading-7",children:"Use policies, signing, audit trails, and migrations to keep the system legible even as AI-assisted workflows accelerate change volume."})]}),_o("div",{className:"grid gap-4 md:grid-cols-2",children:Ty.map((e)=>er(Py,{href:e.href,className:"editorial-panel",children:[_o("h2",{className:"font-semibold text-xl",children:e.title}),_o("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:e.body})]},e.href))})]})}import Sn from"@contractspec/lib.ui-link";import{ChevronRight as Ry}from"lucide-react";import{jsx as _,jsxs as Pe}from"react/jsx-runtime";function Ly(){return Pe("div",{className:"space-y-8",children:[Pe("div",{className:"space-y-4",children:[_("h1",{className:"font-bold text-4xl",children:"Policy Decision Points"}),Pe("p",{className:"text-muted-foreground",children:["A ",_("strong",{children:"Policy Decision Point (PDP)"})," is a centralized component that evaluates access control policies and makes authorization decisions. According to"," ",_("a",{href:"https://www.strongdm.com/blog/policy-decision-point",target:"_blank",rel:"noopener noreferrer",className:"text-violet-400 hover:text-violet-300",children:"StrongDM"}),', the PDP "receives requests for access to resources, evaluates them against policies, and returns a decision (permit or deny)."']})]}),Pe("div",{className:"space-y-4",children:[_("h2",{className:"font-bold text-2xl",children:"How the PDP works in ContractSpec"}),_("p",{className:"text-muted-foreground",children:"In ContractSpec, the PDP is invoked on every operation—whether it's rendering a UI component, executing a capability, or querying a data view. The flow is:"}),Pe("ol",{className:"list-inside list-decimal space-y-3 text-muted-foreground",children:[Pe("li",{children:[_("strong",{children:"Request evaluation"})," – The runtime sends a request to the PDP containing:",Pe("ul",{className:"mt-2 ml-6 list-inside list-disc space-y-1",children:[_("li",{children:"The user's identity and attributes (roles, groups, location, etc.)"}),_("li",{children:"The resource being accessed (capability, field, workflow step)"}),_("li",{children:"The action being performed (read, write, execute)"}),_("li",{children:"Contextual information (time of day, device type, IP address)"})]})]}),Pe("li",{children:[_("strong",{children:"Policy evaluation"})," – The PDP evaluates the request against all applicable ",_("strong",{children:"PolicySpecs"}),". These specs define rules using attribute-based access control (ABAC) and can reference:",Pe("ul",{className:"mt-2 ml-6 list-inside list-disc space-y-1",children:[_("li",{children:`User attributes (e.g., "role == 'admin'")`}),_("li",{children:`Resource attributes (e.g., "field.sensitivity == 'PII'")`}),_("li",{children:'Environmental attributes (e.g., "time.hour >= 9 AND time.hour < 17")'})]})]}),Pe("li",{children:[_("strong",{children:"Decision return"})," – The PDP returns one of:",Pe("ul",{className:"mt-2 ml-6 list-inside list-disc space-y-1",children:[Pe("li",{children:[_("code",{className:"rounded bg-background/50 px-2 py-1",children:"PERMIT"})," ","– The operation is allowed."]}),Pe("li",{children:[_("code",{className:"rounded bg-background/50 px-2 py-1",children:"DENY"})," ","– The operation is blocked."]}),Pe("li",{children:[_("code",{className:"rounded bg-background/50 px-2 py-1",children:"REDACT"})," ","– The operation is allowed, but sensitive fields are masked."]})]})]}),Pe("li",{children:[_("strong",{children:"Enforcement"})," – The runtime enforces the decision. If denied, the operation fails with a clear error message. If redacted, sensitive fields are replaced with placeholders."]}),Pe("li",{children:[_("strong",{children:"Auditing"})," – Every PDP decision is logged to the"," ",_(Sn,{href:"/docs/safety/auditing",className:"text-violet-400 hover:text-violet-300",children:"audit log"}),", including the request, decision, and reasoning."]})]})]}),Pe("div",{className:"space-y-4",children:[_("h2",{className:"font-bold text-2xl",children:"Example PolicySpec"}),_("p",{className:"text-muted-foreground",children:"Here's a simple policy that restricts access to PII fields:"}),_("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:_("pre",{children:`policyId: pii-access-control
|
|
4416
|
+
expectZeroRows: true`})})]}),ce("div",{className:"space-y-4",children:[I("h2",{className:"font-bold text-2xl",children:"Running migrations"}),I("p",{className:"text-muted-foreground",children:"Migrations are applied automatically during deployment. The ContractSpec runtime:"}),ce("ol",{className:"list-inside list-decimal space-y-2 text-muted-foreground",children:[I("li",{children:"Checks which migrations have already been applied (stored in a migrations table)."}),I("li",{children:"Identifies new migrations that need to run."}),I("li",{children:"Executes them in order, respecting dependencies."}),I("li",{children:"Runs validation checks to ensure success."}),I("li",{children:"Records the migration as applied."})]}),I("p",{className:"text-muted-foreground",children:"If a migration fails, the deployment is aborted, and the system remains in its previous state. You can then fix the migration and redeploy."})]}),ce("div",{className:"space-y-4",children:[I("h2",{className:"font-bold text-2xl",children:"Rolling back migrations"}),ce("p",{className:"text-muted-foreground",children:["If you need to roll back a deployment, ContractSpec automatically runs the ",I("strong",{children:"down"})," functions of any migrations that were applied. This restores the database to its previous state."]}),I("p",{className:"text-muted-foreground",children:"Note that rollbacks are not always possible—for example, if you've deleted a column, you cannot recover the data unless you have a backup. For destructive changes, it's best to use a multi-step migration:"}),ce("ol",{className:"list-inside list-decimal space-y-2 text-muted-foreground",children:[I("li",{children:"Add the new column (reversible)."}),I("li",{children:"Backfill data from the old column to the new column (reversible)."}),I("li",{children:"Update application code to use the new column (reversible)."}),I("li",{children:"Drop the old column (irreversible—only do this after confirming the new column works)."})]})]}),ce("div",{className:"space-y-4",children:[I("h2",{className:"font-bold text-2xl",children:"Best practices"}),ce("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[ce("li",{children:[I("strong",{children:"Test migrations locally"})," – Run them against a copy of production data to catch issues before deploying."]}),ce("li",{children:[I("strong",{children:"Keep migrations small"})," – Each migration should do one thing. This makes them easier to understand and roll back."]}),ce("li",{children:[I("strong",{children:"Write reversible migrations"})," – Always provide a down function, even if you don't plan to roll back."]}),ce("li",{children:[I("strong",{children:"Use transactions"})," – Wrap migrations in database transactions so they either fully succeed or fully fail."]}),ce("li",{children:[I("strong",{children:"Avoid destructive changes"})," – Prefer additive changes (adding columns) over destructive ones (dropping columns). If you must delete data, archive it first."]}),ce("li",{children:[I("strong",{children:"Version your migrations"})," – Use timestamps or sequential numbers to ensure migrations run in the correct order."]}),ce("li",{children:[I("strong",{children:"Document breaking changes"})," – If a migration requires application code changes, note this in the migration description."]})]})]}),ce("div",{className:"space-y-4",children:[I("h2",{className:"font-bold text-2xl",children:"Zero-downtime migrations"}),I("p",{className:"text-muted-foreground",children:"Some migrations can cause downtime if not handled carefully. For example, adding a NOT NULL column to a large table can lock the table for minutes. To avoid this, use a multi-step approach:"}),ce("ol",{className:"list-inside list-decimal space-y-2 text-muted-foreground",children:[I("li",{children:"Add the column as nullable."}),I("li",{children:"Backfill the column in batches (without locking the table)."}),I("li",{children:"Add the NOT NULL constraint once all rows are populated."})]}),I("p",{className:"text-muted-foreground",children:"ContractSpec's migration system supports this pattern by allowing you to split a logical change into multiple versioned migrations."})]}),ce("div",{className:"flex items-center gap-4 pt-4",children:[I(Wd,{href:"/docs/safety/auditing",className:"btn-ghost",children:"Previous: Audit Logs"}),ce(Wd,{href:"/docs/advanced/renderers",className:"btn-primary",children:["Next: Advanced Topics ",I(Ry,{size:16})]})]})]})}import Dy from"@contractspec/lib.ui-link";import{jsx as _o,jsxs as er}from"react/jsx-runtime";var Ey=[{title:"Spec signing",body:"Protect the integrity of what gets deployed and make changes verifiable.",href:"/docs/safety/signing"},{title:"Policy decision points",body:"Apply governance consistently across operations, data access, and generated surfaces.",href:"/docs/safety/pdp"},{title:"Audit trails",body:"Record operational and policy decisions with enough context to inspect and explain them later.",href:"/docs/safety/auditing"},{title:"Migrations",body:"Evolve data and schema boundaries without losing control of the system.",href:"/docs/safety/migrations"},{title:"Tenant isolation",body:"Keep configuration, access rules, and sensitive data bounded by tenant.",href:"/docs/safety/tenant-isolation"},{title:"Security and trust",body:"Understand the trust model, release process, and security expectations around the OSS system.",href:"/docs/safety/security-trust"}];function Oy(){return er("div",{className:"space-y-10",children:[er("div",{className:"space-y-3",children:[_o("p",{className:"editorial-kicker",children:"Operate"}),_o("h1",{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"Safety is part of the system model, not an afterthought."}),_o("p",{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:"ContractSpec is meant to survive real change: new generated surfaces, policy updates, migrations, integration churn, and operator handoffs. The safety layer makes those changes inspectable, reversible, and governed."})]}),er("div",{className:"editorial-proof-strip",children:[er("div",{className:"editorial-stat",children:[_o("span",{className:"editorial-label",children:"Operating rule"}),_o("span",{className:"editorial-stat-value",children:"explicit change beats hidden mutation"})]}),_o("p",{className:"max-w-2xl text-muted-foreground text-sm leading-7",children:"Use policies, signing, audit trails, and migrations to keep the system legible even as AI-assisted workflows accelerate change volume."})]}),_o("div",{className:"grid gap-4 md:grid-cols-2",children:Ey.map((e)=>er(Dy,{href:e.href,className:"editorial-panel",children:[_o("h2",{className:"font-semibold text-xl",children:e.title}),_o("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:e.body})]},e.href))})]})}import In from"@contractspec/lib.ui-link";import{ChevronRight as By}from"lucide-react";import{jsx as _,jsxs as Pe}from"react/jsx-runtime";function My(){return Pe("div",{className:"space-y-8",children:[Pe("div",{className:"space-y-4",children:[_("h1",{className:"font-bold text-4xl",children:"Policy Decision Points"}),Pe("p",{className:"text-muted-foreground",children:["A ",_("strong",{children:"Policy Decision Point (PDP)"})," is a centralized component that evaluates access control policies and makes authorization decisions. According to"," ",_("a",{href:"https://www.strongdm.com/blog/policy-decision-point",target:"_blank",rel:"noopener noreferrer",className:"text-violet-400 hover:text-violet-300",children:"StrongDM"}),', the PDP "receives requests for access to resources, evaluates them against policies, and returns a decision (permit or deny)."']})]}),Pe("div",{className:"space-y-4",children:[_("h2",{className:"font-bold text-2xl",children:"How the PDP works in ContractSpec"}),_("p",{className:"text-muted-foreground",children:"In ContractSpec, the PDP is invoked on every operation—whether it's rendering a UI component, executing a capability, or querying a data view. The flow is:"}),Pe("ol",{className:"list-inside list-decimal space-y-3 text-muted-foreground",children:[Pe("li",{children:[_("strong",{children:"Request evaluation"})," – The runtime sends a request to the PDP containing:",Pe("ul",{className:"mt-2 ml-6 list-inside list-disc space-y-1",children:[_("li",{children:"The user's identity and attributes (roles, groups, location, etc.)"}),_("li",{children:"The resource being accessed (capability, field, workflow step)"}),_("li",{children:"The action being performed (read, write, execute)"}),_("li",{children:"Contextual information (time of day, device type, IP address)"})]})]}),Pe("li",{children:[_("strong",{children:"Policy evaluation"})," – The PDP evaluates the request against all applicable ",_("strong",{children:"PolicySpecs"}),". These specs define rules using attribute-based access control (ABAC) and can reference:",Pe("ul",{className:"mt-2 ml-6 list-inside list-disc space-y-1",children:[_("li",{children:`User attributes (e.g., "role == 'admin'")`}),_("li",{children:`Resource attributes (e.g., "field.sensitivity == 'PII'")`}),_("li",{children:'Environmental attributes (e.g., "time.hour >= 9 AND time.hour < 17")'})]})]}),Pe("li",{children:[_("strong",{children:"Decision return"})," – The PDP returns one of:",Pe("ul",{className:"mt-2 ml-6 list-inside list-disc space-y-1",children:[Pe("li",{children:[_("code",{className:"rounded bg-background/50 px-2 py-1",children:"PERMIT"})," ","– The operation is allowed."]}),Pe("li",{children:[_("code",{className:"rounded bg-background/50 px-2 py-1",children:"DENY"})," ","– The operation is blocked."]}),Pe("li",{children:[_("code",{className:"rounded bg-background/50 px-2 py-1",children:"REDACT"})," ","– The operation is allowed, but sensitive fields are masked."]})]})]}),Pe("li",{children:[_("strong",{children:"Enforcement"})," – The runtime enforces the decision. If denied, the operation fails with a clear error message. If redacted, sensitive fields are replaced with placeholders."]}),Pe("li",{children:[_("strong",{children:"Auditing"})," – Every PDP decision is logged to the"," ",_(In,{href:"/docs/safety/auditing",className:"text-violet-400 hover:text-violet-300",children:"audit log"}),", including the request, decision, and reasoning."]})]})]}),Pe("div",{className:"space-y-4",children:[_("h2",{className:"font-bold text-2xl",children:"Example PolicySpec"}),_("p",{className:"text-muted-foreground",children:"Here's a simple policy that restricts access to PII fields:"}),_("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:_("pre",{children:`policyId: pii-access-control
|
|
4417
4417
|
version: '1.0.0'.0.0
|
|
4418
4418
|
rules:
|
|
4419
4419
|
- id: allow-admin-full-access
|
|
@@ -4431,11 +4431,11 @@ rules:
|
|
|
4431
4431
|
effect: DENY
|
|
4432
4432
|
condition: |
|
|
4433
4433
|
user.role NOT IN ['admin', 'support'] AND
|
|
4434
|
-
field.sensitivity == 'PII'`})}),_("p",{className:"text-muted-foreground",children:"With this policy, admins see all data, support staff see redacted PII, and other users cannot access PII at all."})]}),Pe("div",{className:"space-y-4",children:[_("h2",{className:"font-bold text-2xl",children:"Benefits of centralized decision-making"}),Pe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Pe("li",{children:[_("strong",{children:"Consistency"})," – Policies are enforced uniformly across all surfaces (API, UI, workflows)."]}),Pe("li",{children:[_("strong",{children:"Auditability"})," – Every decision is logged, making it easy to trace why access was granted or denied."]}),Pe("li",{children:[_("strong",{children:"Flexibility"})," – Policies can be updated without changing application code."]}),Pe("li",{children:[_("strong",{children:"Security"})," – Reduces the risk of authorization bugs by removing ad-hoc checks scattered throughout the codebase."]})]})]}),Pe("div",{className:"space-y-4",children:[_("h2",{className:"font-bold text-2xl",children:"Performance considerations"}),_("p",{className:"text-muted-foreground",children:"Because the PDP is invoked on every operation, performance is critical. ContractSpec optimizes this by:"}),Pe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[_("li",{children:"Caching policy decisions for identical requests"}),_("li",{children:"Compiling policies into efficient bytecode"}),_("li",{children:"Evaluating only the minimal set of rules needed for each request"}),_("li",{children:"Running the PDP in-process to avoid network latency"})]}),_("p",{className:"text-muted-foreground",children:"In practice, PDP overhead is typically less than 1ms per request."})]}),Pe("div",{className:"flex items-center gap-4 pt-4",children:[_(
|
|
4434
|
+
field.sensitivity == 'PII'`})}),_("p",{className:"text-muted-foreground",children:"With this policy, admins see all data, support staff see redacted PII, and other users cannot access PII at all."})]}),Pe("div",{className:"space-y-4",children:[_("h2",{className:"font-bold text-2xl",children:"Benefits of centralized decision-making"}),Pe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Pe("li",{children:[_("strong",{children:"Consistency"})," – Policies are enforced uniformly across all surfaces (API, UI, workflows)."]}),Pe("li",{children:[_("strong",{children:"Auditability"})," – Every decision is logged, making it easy to trace why access was granted or denied."]}),Pe("li",{children:[_("strong",{children:"Flexibility"})," – Policies can be updated without changing application code."]}),Pe("li",{children:[_("strong",{children:"Security"})," – Reduces the risk of authorization bugs by removing ad-hoc checks scattered throughout the codebase."]})]})]}),Pe("div",{className:"space-y-4",children:[_("h2",{className:"font-bold text-2xl",children:"Performance considerations"}),_("p",{className:"text-muted-foreground",children:"Because the PDP is invoked on every operation, performance is critical. ContractSpec optimizes this by:"}),Pe("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[_("li",{children:"Caching policy decisions for identical requests"}),_("li",{children:"Compiling policies into efficient bytecode"}),_("li",{children:"Evaluating only the minimal set of rules needed for each request"}),_("li",{children:"Running the PDP in-process to avoid network latency"})]}),_("p",{className:"text-muted-foreground",children:"In practice, PDP overhead is typically less than 1ms per request."})]}),Pe("div",{className:"flex items-center gap-4 pt-4",children:[_(In,{href:"/docs/safety/signing",className:"btn-ghost",children:"Previous: Spec Signing"}),Pe(In,{href:"/docs/safety/auditing",className:"btn-primary",children:["Next: Audit Logs ",_(By,{size:16})]})]})]})}import Pn from"@contractspec/lib.ui-link";import{ChevronRight as Tn}from"lucide-react";import{jsx as fe,jsxs as Lt}from"react/jsx-runtime";function Uy(){return Lt("div",{className:"space-y-8",children:[Lt("div",{className:"space-y-4",children:[fe("h1",{className:"font-bold text-4xl",children:"Security & Trust"}),fe("p",{className:"text-muted-foreground",children:"ContractSpec focuses on deterministic, auditable software delivery. This page summarizes our security posture and trust commitments so teams can adopt with clarity."})]}),Lt("div",{className:"card-subtle space-y-4 p-6",children:[fe("h2",{className:"font-bold text-2xl",children:"Security policy"}),fe("p",{className:"text-muted-foreground text-sm",children:"We publish a dedicated security policy that explains how to report vulnerabilities and how we respond."}),Lt(Pn,{href:"/SECURITY.md",className:"btn-primary",children:["Read the security policy ",fe(Tn,{size:16})]})]}),Lt("div",{className:"grid gap-4 md:grid-cols-2",children:[Lt("div",{className:"card-subtle space-y-3 p-6",children:[fe("h3",{className:"font-semibold text-lg",children:"Release hygiene"}),fe("p",{className:"text-muted-foreground text-sm",children:"We ship with deterministic CI, changesets, and contract validation so teams can trust every release."}),Lt("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[fe("li",{children:"Changesets required for published packages."}),fe("li",{children:"CI gate for contract validation and drift detection."}),fe("li",{children:"Rollback-friendly release process."})]})]}),Lt("div",{className:"card-subtle space-y-3 p-6",children:[fe("h3",{className:"font-semibold text-lg",children:"Data handling"}),fe("p",{className:"text-muted-foreground text-sm",children:"ContractSpec promotes strict data classification and policy-driven access. Specs can tag sensitive fields for enforcement."}),Lt("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[fe("li",{children:"Schema-level sensitivity tags."}),fe("li",{children:"Policy Decision Point enforcement."}),fe("li",{children:"Audit logs for operational traceability."})]})]})]}),Lt("div",{className:"grid gap-4 md:grid-cols-2",children:[Lt("div",{className:"card-subtle space-y-3 p-6",children:[fe("h3",{className:"font-semibold text-lg",children:"Supply chain"}),fe("p",{className:"text-muted-foreground text-sm",children:"We track dependency updates and keep the monorepo build reproducible."}),Lt("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[fe("li",{children:"Dependabot + Renovate-style updates where available."}),fe("li",{children:"Signed release artifacts planned for Studio release cycles."}),fe("li",{children:"Transparent changelogs for every package."})]})]}),Lt("div",{className:"card-subtle space-y-3 p-6",children:[fe("h3",{className:"font-semibold text-lg",children:"Responsible disclosure"}),fe("p",{className:"text-muted-foreground text-sm",children:"We respond quickly to security reports and coordinate fixes before public disclosure."}),Lt("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[fe("li",{children:"Security response within 5 business days."}),fe("li",{children:"Private disclosure via security@contractspec.io."}),fe("li",{children:"Credit for researchers (with permission)."})]})]})]}),Lt("div",{className:"space-y-4",children:[fe("h2",{className:"font-bold text-2xl",children:"Next steps"}),fe("p",{className:"text-muted-foreground",children:"Explore the broader safety controls or read the roadmap to see upcoming trust investments."}),Lt("div",{className:"flex flex-wrap gap-4 pt-4",children:[Lt(Pn,{href:"/docs/safety",className:"btn-ghost",children:["Safety overview ",fe(Tn,{size:16})]}),Lt(Pn,{href:"/ROADMAP.md",className:"btn-ghost",children:["Roadmap ",fe(Tn,{size:16})]})]})]})]})}import Wy from"@contractspec/lib.ui-link";import{ChevronRight as _y}from"lucide-react";import{jsx as $a,jsxs as gi}from"react/jsx-runtime";function zy(){return gi("div",{className:"space-y-8",children:[gi("div",{className:"space-y-2",children:[$a("h1",{className:"font-bold text-4xl",children:"Spec Signing"}),$a("p",{className:"text-lg text-muted-foreground",children:"Signing ensures specs haven't been tampered with and provides an audit trail of all changes."})]}),gi("div",{className:"space-y-6",children:[gi("div",{className:"space-y-3",children:[$a("h2",{className:"font-bold text-2xl",children:"How it works"}),$a("p",{className:"text-muted-foreground",children:"Every spec is cryptographically signed before deployment. The signature proves that the spec hasn't been modified since it was signed and creates a permanent record of who deployed it and when."})]}),gi("div",{className:"space-y-3",children:[$a("h2",{className:"font-bold text-2xl",children:"Signing a spec"}),$a("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:$a("pre",{children:`contractspec sign app.spec.ts --key ~/.contractspec/key.pem
|
|
4435
4435
|
contractspec deploy --signed app.spec.ts.signed`})})]}),gi("div",{className:"space-y-3",children:[$a("h2",{className:"font-bold text-2xl",children:"Verifying signatures"}),$a("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:$a("pre",{children:`contractspec verify app.spec.ts.signed
|
|
4436
4436
|
# Output: ✓ Signature valid
|
|
4437
4437
|
# Signed by: alice@example.com
|
|
4438
|
-
# Timestamp: 2024-11-08T10:30:00Z`})})]}),$a("div",{className:"flex items-center gap-4 pt-4",children:gi(
|
|
4438
|
+
# Timestamp: 2024-11-08T10:30:00Z`})})]}),$a("div",{className:"flex items-center gap-4 pt-4",children:gi(Wy,{href:"/docs/safety/pdp",className:"btn-primary",children:["Next: Policy Decision Points ",$a(_y,{size:16})]})})]})]})}import{jsx as zo,jsxs as fi}from"react/jsx-runtime";function Gy(){return fi("div",{className:"space-y-8",children:[fi("div",{className:"space-y-4",children:[zo("h1",{className:"font-bold text-4xl",children:"Tenant Isolation"}),zo("p",{className:"text-lg text-muted-foreground",children:'Preventing cross-tenant data leaks is the #1 security priority for any SaaS. ContractSpec employs "Defense in Depth" to ensure safety.'})]}),fi("div",{className:"space-y-4",children:[zo("h2",{className:"font-bold text-2xl",children:"Layer 1: RLS Middleware"}),fi("p",{children:["The primary defense is the Prisma middleware that rewrites queries to include ",zo("code",{children:"WHERE tenantId = ?"}),". This protects against developer error (forgetting to filter)."]})]}),fi("div",{className:"space-y-4",children:[zo("h2",{className:"font-bold text-2xl",children:"Layer 2: Isolation Validator"}),fi("p",{children:["For high-security environments, you can use the"," ",zo("code",{children:"IsolationValidator"})," in your test suite to verify that every query generated by your operations actually includes the tenant ID."]}),zo("pre",{className:"rounded-lg border bg-muted p-4 text-sm",children:`import { IsolationValidator } from '@contractspec/lib.multi-tenancy/isolation';
|
|
4439
4439
|
|
|
4440
4440
|
test('findUser query is isolated', () => {
|
|
4441
4441
|
const isValid = IsolationValidator.validateQuery(
|
|
@@ -4445,7 +4445,7 @@ test('findUser query is isolated', () => {
|
|
|
4445
4445
|
'tenant-123'
|
|
4446
4446
|
);
|
|
4447
4447
|
expect(isValid).toBe(true);
|
|
4448
|
-
});`})]}),fi("div",{className:"space-y-4",children:[zo("h2",{className:"font-bold text-2xl",children:"Layer 3: Policy Engine"}),zo("p",{children:"The Policy Decision Point (PDP) verifies that the authenticated user actually belongs to the requested tenant before any operation logic runs."})]})]})}import{CodeBlock as
|
|
4448
|
+
});`})]}),fi("div",{className:"space-y-4",children:[zo("h2",{className:"font-bold text-2xl",children:"Layer 3: Policy Engine"}),zo("p",{children:"The Policy Decision Point (PDP) verifies that the authenticated user actually belongs to the requested tenant before any operation logic runs."})]})]})}import{CodeBlock as An}from"@contractspec/lib.design-system";import _d from"@contractspec/lib.ui-link";import{jsx as G,jsxs as We}from"react/jsx-runtime";var qy=[{title:"Managed",body:"Best when the team wants the platform to own setup, routing, readiness, API defaults, and mobile-safe operator flows."},{title:"Local",body:"Best for power users who want local-daemon registration, tenant-local execution providers, and tighter data-locality control."},{title:"Hybrid",body:"Best when some work should stay local while preview, review, export, or mobile operator flows still use managed coordination."}],Hy=["Bootstrap managed, local-daemon, or hybrid presets explicitly instead of inventing provider posture ad hoc per host.","Capture prompts, files, voice, and other inbound sources into a typed workspace instead of relying on a single chat transcript.","Fuse the sources into decisions, assumptions, and blueprint updates with provenance and approval memory.","Compile authoring work into execution lanes, then route the work to explicit provider profiles and runtime targets.","Create previews, run readiness gates, and record receipts before export becomes an operator action.","Keep mobile review parity so approvals, incidents, and patch proposals can be inspected away from the desktop workbench."],Vy=["local trust and lease posture for registered local runtimes","channel-action and comparison posture data in the shared Builder snapshot","preview, readiness, export, and mobile-review state derived from the same workspace snapshot"];function Fy(){return We("div",{className:"space-y-10",children:[We("section",{className:"space-y-3",children:[G("p",{className:"editorial-kicker",children:"Spec pack"}),G("h1",{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"Builder is a governed authoring control plane, not a frontier coding agent."}),We("p",{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:["The implemented Builder stack sits across"," ",G("code",{children:"@contractspec/lib.builder-spec"}),","," ",G("code",{children:"@contractspec/lib.builder-runtime"}),","," ",G("code",{children:"@contractspec/lib.provider-spec"}),", and the reusable workbench/mobile modules. It orchestrates inputs, provider routing, readiness, and export decisions on top of the OSS ContractSpec foundation and the Studio operating layer."]})]}),We("section",{className:"editorial-proof-strip",children:[We("div",{className:"editorial-stat",children:[G("span",{className:"editorial-label",children:"What Builder owns"}),G("span",{className:"editorial-stat-value",children:"fusion, routing, readiness, export"})]}),G("p",{className:"max-w-2xl text-muted-foreground text-sm leading-7",children:"Builder delegates synthesis and coding to external execution providers. Its job is to keep those runs policy-aware, provenance-rich, and usable from both desktop and mobile operator surfaces."})]}),We("section",{className:"editorial-panel space-y-5",children:[We("div",{className:"space-y-2",children:[G("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Implemented stack and entrypoints"}),G("p",{className:"text-muted-foreground text-sm leading-7",children:"You can use the type surfaces directly in code, or start from the already wired workbench and mobile review routes in the public app shell."})]}),G(An,{language:"text",filename:"builder-stack",code:`Packages
|
|
4449
4449
|
- @contractspec/lib.builder-spec
|
|
4450
4450
|
- @contractspec/lib.builder-runtime
|
|
4451
4451
|
- @contractspec/lib.provider-spec
|
|
@@ -4459,7 +4459,7 @@ Web app routes
|
|
|
4459
4459
|
Operate API proxy
|
|
4460
4460
|
- /api/operate/builder/queries/builder.workspace.snapshot
|
|
4461
4461
|
- /api/operate/builder/commands/builder.blueprint.patch
|
|
4462
|
-
- /api/operate/builder/commands/builder.export.execute`})]}),G("section",{className:"grid gap-4 md:grid-cols-3",children:
|
|
4462
|
+
- /api/operate/builder/commands/builder.export.execute`})]}),G("section",{className:"grid gap-4 md:grid-cols-3",children:qy.map((e)=>We("article",{className:"editorial-panel space-y-3",children:[G("h2",{className:"font-semibold text-xl",children:e.title}),G("p",{className:"text-muted-foreground text-sm leading-7",children:e.body})]},e.title))}),We("section",{className:"grid gap-5 lg:grid-cols-2",children:[We("article",{className:"editorial-panel space-y-4",children:[G("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Typical Builder loop"}),G("ol",{className:"list-inside list-decimal space-y-3 text-muted-foreground text-sm leading-7",children:Hy.map((e)=>G("li",{children:e},e))})]}),We("article",{className:"editorial-panel space-y-4",children:[G("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"What Builder should not become"}),We("ul",{className:"editorial-list",children:[We("li",{children:[G("span",{className:"editorial-list-marker"}),G("span",{children:"Not a competitor to specialized coding agents such as Codex or Claude Code."})]}),We("li",{children:[G("span",{className:"editorial-list-marker"}),G("span",{children:"Not a managed-only product that traps teams away from OSS-local runtime paths."})]}),We("li",{children:[G("span",{className:"editorial-list-marker"}),G("span",{children:"Not a hidden routing layer that obscures provider provenance, receipts, or runtime mode."})]}),We("li",{children:[G("span",{className:"editorial-list-marker"}),G("span",{children:"Not a desktop-only surface. Mobile review parity is part of the control-plane contract."})]})]})]})]}),We("section",{className:"editorial-panel space-y-5",children:[We("div",{className:"space-y-2",children:[G("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Workspace config carries the current Builder defaults"}),G("p",{className:"text-muted-foreground text-sm leading-7",children:"Builder setup is no longer just an app-shell concern. The shared workspace config now carries runtime mode, bootstrap preset, control plane API defaults, and local runtime registration metadata so the CLI, editors, and web shells resolve the same posture."})]}),G(An,{language:"json",filename:".contractsrc.json",code:`{
|
|
4463
4463
|
"builder": {
|
|
4464
4464
|
"enabled": true,
|
|
4465
4465
|
"runtimeMode": "local",
|
|
@@ -4474,7 +4474,7 @@ Operate API proxy
|
|
|
4474
4474
|
"providerIds": ["provider.codex", "provider.local.model"]
|
|
4475
4475
|
}
|
|
4476
4476
|
}
|
|
4477
|
-
}`})]}),We("section",{className:"editorial-panel space-y-4",children:[G("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Operator posture stays visible"}),G("ul",{className:"editorial-list",children:
|
|
4477
|
+
}`})]}),We("section",{className:"editorial-panel space-y-4",children:[G("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Operator posture stays visible"}),G("ul",{className:"editorial-list",children:Vy.map((e)=>We("li",{children:[G("span",{className:"editorial-list-marker"}),G("span",{children:e})]},e))})]}),We("section",{className:"editorial-panel space-y-5",children:[We("div",{className:"space-y-2",children:[G("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Use the workbench UI as the host surface"}),G("p",{className:"text-muted-foreground text-sm leading-7",children:"The reusable module already exposes the desktop workbench shell. Your host app keeps control of action wiring, runtime mode selection, and approval flows."})]}),G(An,{language:"tsx",filename:"BuilderWorkbenchHost.tsx",code:`import { BuilderWorkbench, useBuilderWorkbenchState } from "@contractspec/module.builder-workbench";
|
|
4478
4478
|
|
|
4479
4479
|
const state = useBuilderWorkbenchState({
|
|
4480
4480
|
workspace: initialSnapshot.workspace,
|
|
@@ -4492,7 +4492,7 @@ const state = useBuilderWorkbenchState({
|
|
|
4492
4492
|
onRunReadiness={runReadiness}
|
|
4493
4493
|
onExecuteExport={executeExport}
|
|
4494
4494
|
selectedExportRuntimeMode="hybrid"
|
|
4495
|
-
/>;`})]}),We("section",{className:"editorial-panel space-y-4",children:[G("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Read this with the Studio bridge in mind"}),G("p",{className:"text-muted-foreground text-sm leading-7",children:"Builder is where the OSS foundation meets the richer operating layer. Use the Studio overview when you want the higher-level product posture and team workflows on top of these contracts."}),We("div",{className:"flex flex-wrap gap-3",children:[G(
|
|
4495
|
+
/>;`})]}),We("section",{className:"editorial-panel space-y-4",children:[G("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Read this with the Studio bridge in mind"}),G("p",{className:"text-muted-foreground text-sm leading-7",children:"Builder is where the OSS foundation meets the richer operating layer. Use the Studio overview when you want the higher-level product posture and team workflows on top of these contracts."}),We("div",{className:"flex flex-wrap gap-3",children:[G(_d,{href:"/docs/studio",className:"btn-primary",children:"Studio overview"}),G(_d,{href:"/docs/architecture/control-plane",className:"btn-ghost",children:"Control-plane runtime"})]})]})]})}import Ky from"@contractspec/lib.ui-link";import{ChevronRight as Qy}from"lucide-react";import{jsx as jt,jsxs as Ea}from"react/jsx-runtime";function Yy(){return Ea("div",{className:"space-y-8",children:[Ea("div",{className:"space-y-2",children:[jt("h1",{className:"font-bold text-4xl",children:"Capabilities"}),jt("p",{className:"text-lg text-muted-foreground",children:"Capabilities are the core building block of ContractSpec. They define what your app can do."})]}),Ea("div",{className:"space-y-6",children:[Ea("div",{className:"space-y-3",children:[jt("h2",{className:"font-bold text-2xl",children:"Overview"}),jt("p",{className:"text-muted-foreground",children:"A ContractSpec (or Capability) is a typed, declarative description of an operation. It defines the operation's name, version, inputs, outputs, policies, and side effects. Runtime adapters automatically serve these as REST/GraphQL/MCP endpoints with full validation and policy enforcement."})]}),Ea("div",{className:"space-y-3",children:[jt("h2",{className:"font-bold text-2xl",children:"Defining a Command (Write)"}),jt("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:jt("pre",{children:`import { defineCommand } from '@contractspec/lib.contracts-spec';
|
|
4496
4496
|
import { SchemaModel, ScalarTypeEnum } from '@contractspec/lib.schema';
|
|
4497
4497
|
|
|
4498
4498
|
const TransferFundsInput = new SchemaModel({
|
|
@@ -4530,7 +4530,7 @@ export const TransferFunds = defineCommand({
|
|
|
4530
4530
|
auth: 'user',
|
|
4531
4531
|
flags: ['payments_enabled'],
|
|
4532
4532
|
},
|
|
4533
|
-
});`})})]}),Ea("div",{className:"space-y-3",children:[jt("h2",{className:"font-bold text-2xl",children:"Schema Types"}),Ea("p",{className:"text-muted-foreground",children:["ContractSpec uses ",jt("code",{children:"@contractspec/lib.schema"})," for I/O definitions. This provides Zod validation, GraphQL types, and JSON Schema from a single source."]}),Ea("ul",{className:"space-y-2 text-muted-foreground",children:[Ea("li",{children:["•"," ",jt("code",{className:"rounded bg-background/50 px-2 py-1",children:"ScalarTypeEnum.NonEmptyString()"})," ","- Non-empty text"]}),Ea("li",{children:["•"," ",jt("code",{className:"rounded bg-background/50 px-2 py-1",children:"ScalarTypeEnum.PositiveNumber()"})," ","- Positive numbers"]}),Ea("li",{children:["•"," ",jt("code",{className:"rounded bg-background/50 px-2 py-1",children:"ScalarTypeEnum.DateTime()"})," ","- ISO 8601 timestamps"]}),Ea("li",{children:["•"," ",jt("code",{className:"rounded bg-background/50 px-2 py-1",children:"ScalarTypeEnum.Email()"})," ","- Valid email addresses"]}),Ea("li",{children:["•"," ",jt("code",{className:"rounded bg-background/50 px-2 py-1",children:"defineEnum(...)"})," ","- Type-safe enums"]})]})]}),jt("div",{className:"flex items-center gap-4 pt-4",children:Ea(
|
|
4533
|
+
});`})})]}),Ea("div",{className:"space-y-3",children:[jt("h2",{className:"font-bold text-2xl",children:"Schema Types"}),Ea("p",{className:"text-muted-foreground",children:["ContractSpec uses ",jt("code",{children:"@contractspec/lib.schema"})," for I/O definitions. This provides Zod validation, GraphQL types, and JSON Schema from a single source."]}),Ea("ul",{className:"space-y-2 text-muted-foreground",children:[Ea("li",{children:["•"," ",jt("code",{className:"rounded bg-background/50 px-2 py-1",children:"ScalarTypeEnum.NonEmptyString()"})," ","- Non-empty text"]}),Ea("li",{children:["•"," ",jt("code",{className:"rounded bg-background/50 px-2 py-1",children:"ScalarTypeEnum.PositiveNumber()"})," ","- Positive numbers"]}),Ea("li",{children:["•"," ",jt("code",{className:"rounded bg-background/50 px-2 py-1",children:"ScalarTypeEnum.DateTime()"})," ","- ISO 8601 timestamps"]}),Ea("li",{children:["•"," ",jt("code",{className:"rounded bg-background/50 px-2 py-1",children:"ScalarTypeEnum.Email()"})," ","- Valid email addresses"]}),Ea("li",{children:["•"," ",jt("code",{className:"rounded bg-background/50 px-2 py-1",children:"defineEnum(...)"})," ","- Type-safe enums"]})]})]}),jt("div",{className:"flex items-center gap-4 pt-4",children:Ea(Ky,{href:"/docs/specs/dataviews",className:"btn-primary",children:["Next: DataViews ",jt(Qy,{size:16})]})})]})]})}import{CodeBlock as Jy}from"@contractspec/lib.design-system";import zd from"@contractspec/lib.ui-link";import{jsx as ue,jsxs as Dt}from"react/jsx-runtime";var Zy=[{title:"ContextPack",body:"Projects the current repo state, impacted contracts, canon packs, policy bindings, and acceptance checks into one task-scoped envelope."},{title:"PlanPacket",body:"Compiles a candidate objective into ACP-aware steps plus explicit refs back to control-plane intent, plan compile, and plan verify contracts."},{title:"PatchVerdict",body:"Classifies one file edit or shell command as permit, rewrite, require_review, or deny, with runtime-linked control-plane state when available."},{title:"ReviewPacket",body:"Persists the evidence a human needs when Connect escalates, while keeping the local artifact trail authoritative in OSS mode."}],$y=["`.contractspec/adoption/catalog.json` mirrored from the bundled ContractSpec catalog","family-aware reuse recommendations for `ui`, `contracts`, `integrations`, `runtime`, `sharedLibs`, and `solutions`","verdict thresholds that can prefer workspace reuse, ContractSpec reuse, review, or explicit denial before a new implementation starts"],Xy=["Enable `connect` in `.contractsrc.json` and keep your protected, immutable, generated, and smoke-check policies explicit.","Run `contractspec connect context` and `contractspec connect plan` before risky work so the agent is operating on task-scoped evidence, not ambient repo assumptions.","Gate file and shell mutations through `contractspec connect verify` or the host hook commands instead of inventing editor-specific approval logic.","Inspect pending review packets locally first, then sync them to the Studio bridge only if your team wants centralized operator workflows.","Use replay and harness evaluation to prove whether a prior decision stayed safe when the workspace changed."],xy=["Connect is not a second control plane or a second package family.","Verdicts are projections over existing `controlPlane.*`, ACP, workspace, and harness primitives.","Studio is optional for baseline enforcement. Local artifacts remain the OSS source of truth.","Destructive commands, protected paths, drift, and unknown impact stay visible instead of being hidden behind adapter magic."];function jy(){return Dt("div",{className:"space-y-10",children:[Dt("section",{className:"space-y-3",children:[ue("p",{className:"editorial-kicker",children:"Spec pack"}),ue("h1",{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"ContractSpec Connect puts coding-agent actions behind explicit, local-first governance."}),ue("p",{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:"Connect is the adapter layer between agent-native actions and the existing ContractSpec stack. It reuses control-plane, ACP, workspace, knowledge, and harness primitives to explain what the agent is trying to do before a file edit or shell command lands."})]}),Dt("section",{className:"editorial-proof-strip",children:[Dt("div",{className:"editorial-stat",children:[ue("span",{className:"editorial-label",children:"Authoritative surfaces"}),ue("span",{className:"editorial-stat-value",children:"control plane, ACP, workspace, harness"})]}),ue("p",{className:"max-w-2xl text-muted-foreground text-sm leading-7",children:"Connect stays narrow on purpose. It projects local evidence, maps its verdicts back to runtime semantics, and leaves the canonical system contracts where they already live."})]}),Dt("section",{className:"editorial-panel space-y-5",children:[Dt("div",{className:"space-y-2",children:[ue("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"What you use in practice"}),ue("p",{className:"text-muted-foreground text-sm leading-7",children:"The CLI and the workspace service already implement the pack. The main workflow is local initialization, task projection, verification, then optional review sync."})]}),ue(Jy,{language:"bash",filename:"contractspec-connect",code:`contractspec connect init --scope workspace
|
|
4534
4534
|
contractspec connect adoption sync --json
|
|
4535
4535
|
printf '{"goal":"Prefer an existing release helper before adding a new one"}' | contractspec connect adoption resolve --family sharedLibs --stdin --json
|
|
4536
4536
|
contractspec connect context --task refactor-docs --paths packages/libs/contracts-spec/src/control-plane/contracts.ts --json
|
|
@@ -4538,7 +4538,7 @@ printf '{"objective":"Document the control-plane contract surface","commands":["
|
|
|
4538
4538
|
printf '{"operation":"edit","path":"packages/libs/contracts-spec/src/control-plane/contracts.ts"}' | contractspec connect verify --task refactor-docs --tool acp.fs.access --stdin --json
|
|
4539
4539
|
printf 'bun run typecheck' | contractspec connect verify --task refactor-docs --tool acp.terminal.exec --stdin --json
|
|
4540
4540
|
contractspec connect review list --json
|
|
4541
|
-
contractspec connect replay <decisionId> --json`})]}),Dt("section",{className:"space-y-5",children:[Dt("div",{className:"space-y-2",children:[ue("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"The four core artifacts"}),ue("p",{className:"text-muted-foreground text-sm leading-7",children:"Every Connect command is there to emit or inspect one of these reviewable objects under `.contractspec/connect/*`."})]}),ue("div",{className:"grid gap-4 md:grid-cols-2",children:
|
|
4541
|
+
contractspec connect replay <decisionId> --json`})]}),Dt("section",{className:"space-y-5",children:[Dt("div",{className:"space-y-2",children:[ue("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"The four core artifacts"}),ue("p",{className:"text-muted-foreground text-sm leading-7",children:"Every Connect command is there to emit or inspect one of these reviewable objects under `.contractspec/connect/*`."})]}),ue("div",{className:"grid gap-4 md:grid-cols-2",children:Zy.map((e)=>Dt("article",{className:"editorial-panel space-y-3",children:[ue("h3",{className:"font-semibold text-xl",children:e.title}),ue("p",{className:"text-muted-foreground text-sm leading-7",children:e.body})]},e.title))})]}),Dt("section",{className:"editorial-panel space-y-5",children:[Dt("div",{className:"space-y-2",children:[ue("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Reuse-first adoption is part of the workflow"}),ue("p",{className:"text-muted-foreground text-sm leading-7",children:"Connect adoption keeps reuse guidance in the same local control surface. Before a new contract family, helper, or runtime abstraction lands, Connect can mirror the bundled catalog and resolve the best reuse candidate by family."})]}),ue("ul",{className:"editorial-list",children:$y.map((e)=>Dt("li",{children:[ue("span",{className:"editorial-list-marker"}),ue("span",{children:e})]},e))})]}),Dt("section",{className:"grid gap-5 lg:grid-cols-2",children:[Dt("article",{className:"editorial-panel space-y-4",children:[ue("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Adopt Connect in this order"}),ue("ol",{className:"list-inside list-decimal space-y-3 text-muted-foreground text-sm leading-7",children:Xy.map((e)=>ue("li",{children:e},e))})]}),Dt("article",{className:"editorial-panel space-y-4",children:[ue("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Boundaries that keep it trustworthy"}),ue("ul",{className:"editorial-list",children:xy.map((e)=>Dt("li",{children:[ue("span",{className:"editorial-list-marker"}),ue("span",{children:e})]},e))})]})]}),Dt("section",{className:"editorial-panel space-y-4",children:[ue("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Where Connect fits in the rest of the docs"}),ue("p",{className:"text-muted-foreground text-sm leading-7",children:"Read the control-plane runtime page when you want the underlying governance contracts, then use the Studio bridge only if your team wants centralized review queues on top of the OSS-local evidence path."}),Dt("div",{className:"flex flex-wrap gap-3",children:[ue(zd,{href:"/docs/architecture/control-plane",className:"btn-primary",children:"Control-plane runtime"}),ue(zd,{href:"/docs/studio",className:"btn-ghost",children:"Studio bridge"})]})]})]})}import Rr from"@contractspec/lib.ui-link";import{ChevronRight as eb}from"lucide-react";import{jsx as $,jsxs as Re}from"react/jsx-runtime";var tb=`import { defineDataView } from '@contractspec/lib.contracts-spec/data-views';
|
|
4542
4542
|
import { ListDataGridShowcaseRowsQuery } from '@contractspec/example.data-grid-showcase/contracts/data-grid-showcase.operation';
|
|
4543
4543
|
|
|
4544
4544
|
export const DataGridShowcaseDataView = defineDataView({
|
|
@@ -4585,7 +4585,7 @@ export const DataGridShowcaseDataView = defineDataView({
|
|
|
4585
4585
|
{ key: 'notes', label: 'Notes', dataPath: 'notes' },
|
|
4586
4586
|
],
|
|
4587
4587
|
},
|
|
4588
|
-
});`;function
|
|
4588
|
+
});`;function ab(){return Re("div",{className:"space-y-8",children:[Re("div",{className:"space-y-4",children:[$("h1",{className:"font-bold text-4xl",children:"DataViews"}),Re("p",{className:"text-muted-foreground",children:["A ",$("strong",{children:"DataViewSpec"})," describes how data should be queried, filtered, sorted, and presented to users. Runtime adapters execute optimized database queries and serve list views, detail views, and search interfaces while respecting policy constraints."]})]}),Re("div",{className:"space-y-4",children:[$("h2",{className:"font-bold text-2xl",children:"Core concepts"}),Re("div",{className:"space-y-3",children:[Re("div",{children:[$("h3",{className:"font-semibold text-lg",children:"Data sources"}),$("p",{className:"text-muted-foreground",children:"A DataView connects to one or more data sources—databases, APIs, or other capabilities. You specify the source and the fields you want to expose."})]}),Re("div",{children:[$("h3",{className:"font-semibold text-lg",children:"Filtering"}),$("p",{className:"text-muted-foreground",children:`Define filters that users can apply to narrow down results. Filters can be simple (e.g., "status equals 'active'") or complex (e.g., "created within the last 30 days AND assigned to current user").`})]}),Re("div",{children:[$("h3",{className:"font-semibold text-lg",children:"Sorting"}),$("p",{className:"text-muted-foreground",children:"Specify which fields can be sorted and the default sort order. ContractSpec generates efficient database queries with proper indexes."})]}),Re("div",{children:[$("h3",{className:"font-semibold text-lg",children:"Pagination"}),$("p",{className:"text-muted-foreground",children:"DataViews automatically support pagination to handle large datasets. You can configure page size limits and cursor-based or offset-based pagination."})]}),Re("div",{children:[$("h3",{className:"font-semibold text-lg",children:"Aggregations"}),$("p",{className:"text-muted-foreground",children:"Compute aggregates like counts, sums, averages, and group-by operations. These are useful for dashboards and summary views."})]})]})]}),Re("div",{className:"space-y-4",children:[$("h2",{className:"font-bold text-2xl",children:"Example DataViewSpec"}),Re("p",{className:"text-muted-foreground",children:["Here is the canonical table contract used by the live"," ",$(Rr,{href:"/docs/examples/data-grid-showcase",className:"text-[color:var(--rust)] underline underline-offset-4",children:"Data Grid Showcase"}),":"]}),$("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:$("pre",{children:tb})}),$("p",{className:"text-muted-foreground text-sm",children:"This one contract drives the DataView lane, while the same rows and controller also feed the raw web primitive, native-first primitive, and composed design-system demos."})]}),Re("div",{className:"space-y-4",children:[$("h2",{className:"font-bold text-2xl",children:"Policy integration"}),Re("p",{className:"text-muted-foreground",children:["DataViews automatically enforce"," ",$(Rr,{href:"/docs/specs/policy",className:"text-violet-400 hover:text-violet-300",children:"PolicySpecs"}),". If a user doesn't have permission to see certain fields, those fields are automatically filtered out or redacted. If a user can only see their own data, the query is automatically scoped."]}),$("p",{className:"text-muted-foreground",children:"This means you define the data view once, and it works correctly for all users based on their permissions—no need to write separate queries for different roles."})]}),Re("div",{className:"space-y-4",children:[$("h2",{className:"font-bold text-2xl",children:"Served outputs"}),$("p",{className:"text-muted-foreground",children:"From a DataViewSpec, ContractSpec serves:"}),Re("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[Re("li",{children:[$("strong",{children:"Database queries"})," – Optimized SQL or NoSQL queries executed at runtime"]}),Re("li",{children:[$("strong",{children:"API endpoints"})," – RESTful or GraphQL endpoints for fetching data"]}),Re("li",{children:[$("strong",{children:"UI components"})," – List views, tables, cards, and detail views"]}),Re("li",{children:[$("strong",{children:"Search interfaces"})," – Full-text search with autocomplete"]}),Re("li",{children:[$("strong",{children:"Export functions"})," – CSV, JSON, or Excel exports"]})]})]}),Re("div",{className:"space-y-4",children:[$("h2",{className:"font-bold text-2xl",children:"Best practices"}),Re("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[$("li",{children:"Only expose fields that users actually need—this improves performance and security."}),$("li",{children:"Use appropriate indexes for sortable and filterable fields."}),$("li",{children:"Set reasonable pagination limits to prevent performance issues."}),$("li",{children:"Use aggregations sparingly—they can be expensive on large datasets."}),$("li",{children:"Test DataViews with realistic data volumes to ensure they perform well."})]})]}),Re("div",{className:"flex items-center gap-4 pt-4",children:[$(Rr,{href:"/docs/specs/capabilities",className:"btn-ghost",children:"Previous: Capabilities"}),Re(Rr,{href:"/docs/specs/workflows",className:"btn-primary",children:["Next: Workflows ",$(eb,{size:16})]})]})]})}import{CodeBlock as Gd}from"@contractspec/lib.design-system";import qd from"@contractspec/lib.ui-link";import{jsx as de,jsxs as gt}from"react/jsx-runtime";var ob=["declared routes, surfaces, layouts, slots, actions, and data recipes","entity registries and field renderers for relation-heavy workbenches","preference-aware adaptation across guidance, density, data depth, control, media, pace, and narrative","auditable overlays and bounded AI patch proposals instead of free-form JSX generation"],ib=["Define one `ModuleBundleSpec` with `defineModuleBundle` and keep the route and surface map explicit.","Resolve the bundle with `resolveBundle` for a real user, route, device, and preference profile.","Render the plan through `BundleProvider` and `BundleRenderer` so the UI stays downstream of the resolved spec.","Add overlays, policy hooks, planner proposals, and telemetry only after the base route resolves cleanly.","Pilot one dense domain first, such as a PM or operations workbench, before expanding the abstraction across the app."];function rb(){return gt("div",{className:"space-y-10",children:[gt("section",{className:"space-y-3",children:[de("p",{className:"editorial-kicker",children:"Spec pack"}),de("h1",{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"Module bundles turn surface composition into a typed ContractSpec runtime instead of a pile of bespoke page code."}),gt("p",{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:["The implemented package is"," ",de("code",{children:"@contractspec/lib.surface-runtime"}),". It lets you define a bundle spec once, resolve it into a personalized surface plan, then render that plan through React without letting AI or per-route custom code bypass the declared system boundary."]})]}),gt("section",{className:"editorial-proof-strip",children:[gt("div",{className:"editorial-stat",children:[de("span",{className:"editorial-label",children:"Runtime promise"}),de("span",{className:"editorial-stat-value",children:"bundle spec → resolved surface plan"})]}),de("p",{className:"max-w-2xl text-muted-foreground text-sm leading-7",children:"The bundle spec owns what can render, where it can render, which preferences matter, and how overlays and AI proposals stay bounded."})]}),de("section",{className:"grid gap-4 md:grid-cols-2",children:ob.map((e)=>gt("article",{className:"editorial-panel space-y-3",children:[de("h2",{className:"font-semibold text-xl",children:"Bundle capability"}),de("p",{className:"text-muted-foreground text-sm leading-7",children:e})]},e))}),gt("section",{className:"editorial-panel space-y-5",children:[gt("div",{className:"space-y-2",children:[de("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"1) Define the bundle"}),de("p",{className:"text-muted-foreground text-sm leading-7",children:"Start with a typed route and one surface. The runtime validates that you declared routes, surfaces, and verification coverage for all seven preference dimensions."})]}),de(Gd,{language:"typescript",filename:"support.workbench.bundle.ts",code:`import { defineModuleBundle } from "@contractspec/lib.surface-runtime/spec/define-module-bundle";
|
|
4589
4589
|
|
|
4590
4590
|
export const SupportWorkbenchBundle = defineModuleBundle({
|
|
4591
4591
|
meta: {
|
|
@@ -4620,7 +4620,7 @@ export const SupportWorkbenchBundle = defineModuleBundle({
|
|
|
4620
4620
|
},
|
|
4621
4621
|
},
|
|
4622
4622
|
},
|
|
4623
|
-
});`})]}),gt("section",{className:"editorial-panel space-y-5",children:[gt("div",{className:"space-y-2",children:[de("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"2) Resolve and render the plan"}),de("p",{className:"text-muted-foreground text-sm leading-7",children:"The app renders the resolved plan, not the raw spec. That keeps layout choice, data hydration, overlays, and AI proposals auditable."})]}),de(
|
|
4623
|
+
});`})]}),gt("section",{className:"editorial-panel space-y-5",children:[gt("div",{className:"space-y-2",children:[de("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"2) Resolve and render the plan"}),de("p",{className:"text-muted-foreground text-sm leading-7",children:"The app renders the resolved plan, not the raw spec. That keeps layout choice, data hydration, overlays, and AI proposals auditable."})]}),de(Gd,{language:"tsx",filename:"SurfaceHost.tsx",code:`import { BundleProvider, BundleRenderer } from "@contractspec/lib.surface-runtime/react";
|
|
4624
4624
|
import { resolveBundle } from "@contractspec/lib.surface-runtime/runtime/resolve-bundle";
|
|
4625
4625
|
|
|
4626
4626
|
const plan = await resolveBundle(SupportWorkbenchBundle, {
|
|
@@ -4650,7 +4650,7 @@ export function SurfaceHost() {
|
|
|
4650
4650
|
<BundleRenderer assistantSlotId="assistant" />
|
|
4651
4651
|
</BundleProvider>
|
|
4652
4652
|
);
|
|
4653
|
-
}`})]}),gt("section",{className:"grid gap-5 lg:grid-cols-2",children:[gt("article",{className:"editorial-panel space-y-4",children:[de("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Adoption loop"}),de("ol",{className:"list-inside list-decimal space-y-3 text-muted-foreground text-sm leading-7",children:
|
|
4653
|
+
}`})]}),gt("section",{className:"grid gap-5 lg:grid-cols-2",children:[gt("article",{className:"editorial-panel space-y-4",children:[de("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Adoption loop"}),de("ol",{className:"list-inside list-decimal space-y-3 text-muted-foreground text-sm leading-7",children:ib.map((e)=>de("li",{children:e},e))})]}),gt("article",{className:"editorial-panel space-y-4",children:[de("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Guardrails that matter"}),gt("ul",{className:"editorial-list",children:[gt("li",{children:[de("span",{className:"editorial-list-marker"}),de("span",{children:"Do not stuff this behavior back into `lib.ui-kit`."})]}),gt("li",{children:[de("span",{className:"editorial-list-marker"}),de("span",{children:"Do not let AI invent undeclared components or mutate raw DOM state."})]}),gt("li",{children:[de("span",{className:"editorial-list-marker"}),de("span",{children:"Keep third-party UI libraries behind adapter subpaths only."})]}),gt("li",{children:[de("span",{className:"editorial-list-marker"}),de("span",{children:"Every surface still needs explicit verification coverage for the seven preference dimensions."})]})]})]})]}),gt("section",{className:"editorial-panel space-y-4",children:[de("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Continue with overlays and runtime architecture"}),de("p",{className:"text-muted-foreground text-sm leading-7",children:"Once the bundle resolves deterministically, move into safe customization and the wider architecture that surrounds it."}),gt("div",{className:"flex flex-wrap gap-3",children:[de(qd,{href:"/docs/specs/overlays",className:"btn-primary",children:"Overlays"}),de(qd,{href:"/docs/architecture",className:"btn-ghost",children:"Architecture overview"})]})]})]})}import Ei from"@contractspec/lib.ui-link";import{ChevronRight as nb}from"lucide-react";import{jsx as P,jsxs as H}from"react/jsx-runtime";function cb(){return H("div",{className:"space-y-8",children:[H("div",{className:"space-y-4",children:[P("h1",{className:"font-bold text-4xl",children:"Overlays"}),H("p",{className:"text-muted-foreground",children:["An ",P("strong",{children:"OverlaySpec"})," allows tenants or users to customize UI layouts and field visibility without modifying the underlying application code. Overlays are cryptographically signed to ensure they respect policy boundaries and cannot introduce security vulnerabilities."]})]}),H("div",{className:"space-y-4",children:[P("h2",{className:"font-bold text-2xl",children:"Why overlays matter"}),P("p",{className:"text-muted-foreground",children:"Different users have different needs. A power user might want to see all available fields and actions, while a casual user prefers a simplified interface. A tenant in a multi-tenant application might want to brand the UI or hide features they don't use."}),P("p",{className:"text-muted-foreground",children:"Traditional approaches require either building multiple UIs or adding complex configuration logic throughout the codebase. OverlaySpecs provide a safer, more maintainable solution: users can customize their experience, but only within the bounds allowed by the underlying specs and policies."})]}),H("div",{className:"space-y-4",children:[P("h2",{className:"font-bold text-2xl",children:"What overlays can do"}),H("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[H("li",{children:[P("strong",{children:"Hide or show fields"})," – Remove fields from forms or detail views (but only if the user has permission to see them in the first place)"]}),H("li",{children:[P("strong",{children:"Reorder fields"})," – Change the order in which fields appear"]}),H("li",{children:[P("strong",{children:"Rename labels"})," – Use different terminology that's more familiar to the user"]}),H("li",{children:[P("strong",{children:"Change layouts"})," – Switch between list, grid, or card views"]}),H("li",{children:[P("strong",{children:"Add help text"})," – Provide context-specific guidance"]}),H("li",{children:[P("strong",{children:"Set default values"})," – Pre-fill forms with tenant-specific defaults"]}),H("li",{children:[P("strong",{children:"Apply branding"})," – Customize colors, logos, and styling (within approved themes)"]})]})]}),H("div",{className:"space-y-4",children:[P("h2",{className:"font-bold text-2xl",children:"Example OverlaySpec"}),P("p",{className:"text-muted-foreground",children:"Here's an overlay that customizes an order form:"}),P("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:P("pre",{children:`overlayId: acme-order-form
|
|
4654
4654
|
version: '1.0.0'.0.0
|
|
4655
4655
|
appliesTo:
|
|
4656
4656
|
capability: createOrder
|
|
@@ -4687,7 +4687,7 @@ modifications:
|
|
|
4687
4687
|
signature:
|
|
4688
4688
|
algorithm: EdDSA
|
|
4689
4689
|
publicKey: "acme-corp-overlay-key"
|
|
4690
|
-
signature: "base64-encoded-signature"`})})]}),H("div",{className:"space-y-4",children:[P("h2",{className:"font-bold text-2xl",children:"Safety guarantees"}),P("p",{className:"text-muted-foreground",children:"Overlays are powerful, but they must not compromise security or data integrity. ContractSpec enforces several guarantees:"}),H("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[H("li",{children:[P("strong",{children:"Overlays cannot grant new permissions"})," – They can only hide or rearrange what the user is already allowed to see"]}),H("li",{children:[P("strong",{children:"Overlays cannot bypass validation"})," – Field types, constraints, and business rules from the underlying spec still apply"]}),H("li",{children:[P("strong",{children:"Overlays must be signed"})," – Only authorized parties (typically tenant admins) can create overlays"]}),H("li",{children:[P("strong",{children:"Overlays are versioned"})," – Changes to overlays are tracked and can be rolled back"]}),H("li",{children:[P("strong",{children:"Overlays are audited"})," – Every overlay application is logged"]})]})]}),H("div",{className:"space-y-4",children:[P("h2",{className:"font-bold text-2xl",children:"Creating overlays"}),P("p",{className:"text-muted-foreground",children:"Overlays can be created through:"}),H("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[H("li",{children:[P("strong",{children:"Visual editor"})," – A drag-and-drop interface for non-technical users"]}),H("li",{children:[P("strong",{children:"TypeScript/JSON"})," – For developers who prefer code"]}),H("li",{children:[P("strong",{children:"API"})," – Programmatically create overlays for automation"]})]}),P("p",{className:"text-muted-foreground",children:"Once created, overlays must be signed using a private key. The corresponding public key is registered with ContractSpec, which verifies the signature before applying the overlay."}),H("p",{className:"text-muted-foreground",children:["See"," ",P(Ei,{href:"/docs/libraries/overlay-engine",className:"text-violet-400 underline",children:"Overlay Engine docs"})," ","and the"," ",P(Ei,{href:"/docs/advanced/overlay-editor",className:"text-violet-400 underline",children:"Overlay Editor guide"})," ","for end-to-end workflows."]})]}),H("div",{className:"space-y-4",children:[P("h2",{className:"font-bold text-2xl",children:"Overlay scope"}),P("p",{className:"text-muted-foreground",children:"Overlays can be scoped to:"}),H("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[H("li",{children:[P("strong",{children:"Tenant"})," – All users in a tenant see the same overlay"]}),H("li",{children:[P("strong",{children:"User"})," – Individual users can have personal overlays"]}),H("li",{children:[P("strong",{children:"Role"})," – All users with a specific role see the overlay"]}),H("li",{children:[P("strong",{children:"Device"})," – Different overlays for mobile vs desktop"]})]}),P("p",{className:"text-muted-foreground",children:"If multiple overlays apply to the same user, they are merged in order of specificity (user overlays override role overlays, which override tenant overlays)."})]}),H("div",{className:"space-y-4",children:[P("h2",{className:"font-bold text-2xl",children:"Best practices"}),H("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[P("li",{children:"Start with the default UI and only create overlays when users request specific changes."}),P("li",{children:"Document why each overlay modification was made—this helps when reviewing or updating overlays."}),P("li",{children:"Test overlays thoroughly to ensure they don't break workflows or confuse users."}),P("li",{children:"Use tenant-level overlays for organizational customizations and user-level overlays for personal preferences."}),P("li",{children:"Regularly review overlays to remove ones that are no longer needed."}),P("li",{children:"Protect overlay signing keys carefully—they control what customizations are allowed."})]})]}),H("div",{className:"space-y-4",children:[P("h2",{className:"font-bold text-2xl",children:"Where overlays fit in the runtime"}),P("p",{className:"text-muted-foreground",children:"Overlays are safest when they sit on top of a declared bundle surface instead of ad hoc page code. Use the module-bundles docs first, then apply overlays as auditable customization on top of the resolved surface plan."}),H("div",{className:"flex flex-wrap gap-3",children:[P(Ei,{href:"/docs/specs/module-bundles",className:"btn-primary",children:"Module bundles"}),P(Ei,{href:"/docs/guides/first-module-bundle",className:"btn-ghost",children:"Build a first module bundle"})]})]}),H("div",{className:"flex items-center gap-4 pt-4",children:[P(Ei,{href:"/docs/specs/policy",className:"btn-ghost",children:"Previous: Policy"}),H(Ei,{href:"/docs/safety",className:"btn-primary",children:["Next: Safety ",P(tb,{size:16})]})]})]})}import zd from"@contractspec/lib.ui-link";import{ChevronRight as Gd}from"lucide-react";import{jsx as ke,jsxs as Et}from"react/jsx-runtime";var ob=[{title:"Capabilities",body:"Model operations, events, and presentations as explicit system behavior.",href:"/docs/specs/capabilities"},{title:"Data views",body:"Describe query, filtering, and presentation behavior from the same source model.",href:"/docs/specs/dataviews"},{title:"Workflows",body:"Coordinate multi-step execution, retries, monitoring, and hand-offs.",href:"/docs/specs/workflows"},{title:"Policy",body:"Carry governance and access rules through every generated and runtime-served surface.",href:"/docs/specs/policy"},{title:"Overlays",body:"Customize generated surfaces safely instead of forking them permanently.",href:"/docs/specs/overlays"},{title:"Safety and migration",body:"Keep change safe with signing, audits, rollbacks, and explicit migration behavior.",href:"/docs/safety"}],ib=[{title:"Module bundles",body:"Define typed surface bundles that resolve into auditable runtime plans instead of hand-built page logic.",href:"/docs/specs/module-bundles"},{title:"ContractSpec Connect",body:"Put coding-agent edits and commands behind local-first context, verification, replay, and review artifacts.",href:"/docs/specs/connect"},{title:"Builder control plane",body:"Coordinate multimodal authoring, provider routing, readiness, export, and mobile review on top of OSS and Studio.",href:"/docs/specs/builder-control-plane"}];function rb(){return Et("div",{className:"space-y-10",children:[Et("div",{className:"space-y-3",children:[ke("p",{className:"editorial-kicker",children:"Core model"}),ke("h1",{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"Contracts are the durable system boundary."}),ke("p",{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:"ContractSpec uses explicit TypeScript specs to describe behavior before it spreads across APIs, UI, data models, events, and operator flows. The goal is not to hide implementation. The goal is to make the system boundary explicit enough that generation, validation, runtime enforcement, and regeneration can stay coherent."})]}),Et("div",{className:"editorial-proof-strip",children:[Et("div",{className:"editorial-stat",children:[ke("span",{className:"editorial-label",children:"System promise"}),ke("span",{className:"editorial-stat-value",children:"one contract → many surfaces"})]}),ke("p",{className:"max-w-2xl text-muted-foreground text-sm leading-7",children:"Use the contract layer to keep surface behavior aligned, then let runtimes and generators do the repetitive work without inventing a closed platform."})]}),ke("section",{className:"editorial-panel space-y-5",children:Et("div",{className:"space-y-2",children:[ke("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"What the contract layer owns"}),Et("ul",{className:"editorial-list",children:[Et("li",{children:[ke("span",{className:"editorial-list-marker"}),ke("span",{children:"Behavior: operations, events, presentations, workflows."})]}),Et("li",{children:[ke("span",{className:"editorial-list-marker"}),ke("span",{children:"Validation: input, output, and schema boundaries."})]}),Et("li",{children:[ke("span",{className:"editorial-list-marker"}),ke("span",{children:"Governance: policy, auditability, and migration rules."})]}),Et("li",{children:[ke("span",{className:"editorial-list-marker"}),ke("span",{children:"Surface alignment: generated or served behavior across API, UI, data, and agent-facing interfaces."})]})]})]})}),Et("section",{className:"space-y-5",children:[Et("div",{className:"space-y-2",children:[ke("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Specification types"}),ke("p",{className:"text-muted-foreground text-sm leading-7",children:"You can adopt the model one part at a time. Not every system needs every spec type on day one."})]}),ke("div",{className:"grid gap-4 md:grid-cols-2",children:ob.map((e)=>Et(zd,{href:e.href,className:"editorial-panel",children:[ke("h3",{className:"font-semibold text-xl",children:e.title}),ke("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:e.body}),Et("div",{className:"mt-4 flex items-center gap-2 text-[color:var(--rust)] text-sm",children:["Open section ",ke(Gd,{size:14})]})]},e.title))})]}),Et("section",{className:"space-y-5",children:[Et("div",{className:"space-y-2",children:[ke("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Implemented spec packs"}),ke("p",{className:"text-muted-foreground text-sm leading-7",children:"These packs combine multiple contract surfaces into higher-order systems you can use directly today: agent enforcement, AI-native surface runtime, and governed Builder authoring."})]}),ke("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:ib.map((e)=>Et(zd,{href:e.href,className:"editorial-panel",children:[ke("h3",{className:"font-semibold text-xl",children:e.title}),ke("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:e.body}),Et("div",{className:"mt-4 flex items-center gap-2 text-[color:var(--rust)] text-sm",children:["Open pack ",ke(Gd,{size:14})]})]},e.title))})]})]})}import Oi from"@contractspec/lib.ui-link";import{ChevronRight as nb}from"lucide-react";import{jsx as w,jsxs as X}from"react/jsx-runtime";function cb(){return X("div",{className:"space-y-8",children:[X("div",{className:"space-y-4",children:[w("h1",{className:"font-bold text-4xl",children:"Policy"}),X("p",{className:"text-muted-foreground",children:["A ",w("strong",{children:"PolicySpec"})," defines who can do what, when, and under what conditions. ContractSpec uses attribute-based access control (ABAC) to enforce policies across your entire application—from API endpoints to UI components."]})]}),X("div",{className:"space-y-4",children:[w("h2",{className:"font-bold text-2xl",children:"Why policies matter"}),w("p",{className:"text-muted-foreground",children:"Traditional access control relies on roles (RBAC), which can become unwieldy as applications grow. ABAC is more flexible—it evaluates policies based on attributes of the user, resource, action, and context."}),X("p",{className:"text-muted-foreground",children:["ContractSpec's policy engine ensures that access control is consistent across all surfaces. You don't have to remember to add authorization checks in every API endpoint or UI component—the"," ",w(Oi,{href:"/docs/safety/pdp",className:"text-violet-400 hover:text-violet-300",children:"Policy Decision Point"})," ","enforces policies automatically."]})]}),X("div",{className:"space-y-4",children:[w("h2",{className:"font-bold text-2xl",children:"Policy structure"}),w("p",{className:"text-muted-foreground",children:"A PolicySpec contains one or more rules. Each rule has:"}),X("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[X("li",{children:[w("strong",{children:"Effect"})," – PERMIT, DENY, or REDACT"]}),X("li",{children:[w("strong",{children:"Condition"})," – A boolean expression that determines when the rule applies"]}),X("li",{children:[w("strong",{children:"Scope"})," – Which resources, actions, or fields the rule applies to"]}),X("li",{children:[w("strong",{children:"Priority"})," – Rules are evaluated in priority order; the first matching rule wins"]})]})]}),X("div",{className:"space-y-4",children:[w("h2",{className:"font-bold text-2xl",children:"Example PolicySpec"}),w("p",{className:"text-muted-foreground",children:"Here's a policy that controls access to customer data in TypeScript:"}),w("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:w("pre",{children:`import { definePolicy } from '@contractspec/lib.contracts-spec';
|
|
4690
|
+
signature: "base64-encoded-signature"`})})]}),H("div",{className:"space-y-4",children:[P("h2",{className:"font-bold text-2xl",children:"Safety guarantees"}),P("p",{className:"text-muted-foreground",children:"Overlays are powerful, but they must not compromise security or data integrity. ContractSpec enforces several guarantees:"}),H("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[H("li",{children:[P("strong",{children:"Overlays cannot grant new permissions"})," – They can only hide or rearrange what the user is already allowed to see"]}),H("li",{children:[P("strong",{children:"Overlays cannot bypass validation"})," – Field types, constraints, and business rules from the underlying spec still apply"]}),H("li",{children:[P("strong",{children:"Overlays must be signed"})," – Only authorized parties (typically tenant admins) can create overlays"]}),H("li",{children:[P("strong",{children:"Overlays are versioned"})," – Changes to overlays are tracked and can be rolled back"]}),H("li",{children:[P("strong",{children:"Overlays are audited"})," – Every overlay application is logged"]})]})]}),H("div",{className:"space-y-4",children:[P("h2",{className:"font-bold text-2xl",children:"Creating overlays"}),P("p",{className:"text-muted-foreground",children:"Overlays can be created through:"}),H("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[H("li",{children:[P("strong",{children:"Visual editor"})," – A drag-and-drop interface for non-technical users"]}),H("li",{children:[P("strong",{children:"TypeScript/JSON"})," – For developers who prefer code"]}),H("li",{children:[P("strong",{children:"API"})," – Programmatically create overlays for automation"]})]}),P("p",{className:"text-muted-foreground",children:"Once created, overlays must be signed using a private key. The corresponding public key is registered with ContractSpec, which verifies the signature before applying the overlay."}),H("p",{className:"text-muted-foreground",children:["See"," ",P(Ei,{href:"/docs/libraries/overlay-engine",className:"text-violet-400 underline",children:"Overlay Engine docs"})," ","and the"," ",P(Ei,{href:"/docs/advanced/overlay-editor",className:"text-violet-400 underline",children:"Overlay Editor guide"})," ","for end-to-end workflows."]})]}),H("div",{className:"space-y-4",children:[P("h2",{className:"font-bold text-2xl",children:"Overlay scope"}),P("p",{className:"text-muted-foreground",children:"Overlays can be scoped to:"}),H("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[H("li",{children:[P("strong",{children:"Tenant"})," – All users in a tenant see the same overlay"]}),H("li",{children:[P("strong",{children:"User"})," – Individual users can have personal overlays"]}),H("li",{children:[P("strong",{children:"Role"})," – All users with a specific role see the overlay"]}),H("li",{children:[P("strong",{children:"Device"})," – Different overlays for mobile vs desktop"]})]}),P("p",{className:"text-muted-foreground",children:"If multiple overlays apply to the same user, they are merged in order of specificity (user overlays override role overlays, which override tenant overlays)."})]}),H("div",{className:"space-y-4",children:[P("h2",{className:"font-bold text-2xl",children:"Best practices"}),H("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[P("li",{children:"Start with the default UI and only create overlays when users request specific changes."}),P("li",{children:"Document why each overlay modification was made—this helps when reviewing or updating overlays."}),P("li",{children:"Test overlays thoroughly to ensure they don't break workflows or confuse users."}),P("li",{children:"Use tenant-level overlays for organizational customizations and user-level overlays for personal preferences."}),P("li",{children:"Regularly review overlays to remove ones that are no longer needed."}),P("li",{children:"Protect overlay signing keys carefully—they control what customizations are allowed."})]})]}),H("div",{className:"space-y-4",children:[P("h2",{className:"font-bold text-2xl",children:"Where overlays fit in the runtime"}),P("p",{className:"text-muted-foreground",children:"Overlays are safest when they sit on top of a declared bundle surface instead of ad hoc page code. Use the module-bundles docs first, then apply overlays as auditable customization on top of the resolved surface plan."}),H("div",{className:"flex flex-wrap gap-3",children:[P(Ei,{href:"/docs/specs/module-bundles",className:"btn-primary",children:"Module bundles"}),P(Ei,{href:"/docs/guides/first-module-bundle",className:"btn-ghost",children:"Build a first module bundle"})]})]}),H("div",{className:"flex items-center gap-4 pt-4",children:[P(Ei,{href:"/docs/specs/policy",className:"btn-ghost",children:"Previous: Policy"}),H(Ei,{href:"/docs/safety",className:"btn-primary",children:["Next: Safety ",P(nb,{size:16})]})]})]})}import Hd from"@contractspec/lib.ui-link";import{ChevronRight as Vd}from"lucide-react";import{jsx as ke,jsxs as Et}from"react/jsx-runtime";var lb=[{title:"Capabilities",body:"Model operations, events, and presentations as explicit system behavior.",href:"/docs/specs/capabilities"},{title:"Data views",body:"Describe query, filtering, and presentation behavior from the same source model.",href:"/docs/specs/dataviews"},{title:"Workflows",body:"Coordinate multi-step execution, retries, monitoring, and hand-offs.",href:"/docs/specs/workflows"},{title:"Policy",body:"Carry governance and access rules through every generated and runtime-served surface.",href:"/docs/specs/policy"},{title:"Overlays",body:"Customize generated surfaces safely instead of forking them permanently.",href:"/docs/specs/overlays"},{title:"Safety and migration",body:"Keep change safe with signing, audits, rollbacks, and explicit migration behavior.",href:"/docs/safety"}],db=[{title:"Module bundles",body:"Define typed surface bundles that resolve into auditable runtime plans instead of hand-built page logic.",href:"/docs/specs/module-bundles"},{title:"ContractSpec Connect",body:"Put coding-agent edits and commands behind local-first context, verification, replay, and review artifacts.",href:"/docs/specs/connect"},{title:"Builder control plane",body:"Coordinate multimodal authoring, provider routing, readiness, export, and mobile review on top of OSS and Studio.",href:"/docs/specs/builder-control-plane"}];function sb(){return Et("div",{className:"space-y-10",children:[Et("div",{className:"space-y-3",children:[ke("p",{className:"editorial-kicker",children:"Core model"}),ke("h1",{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"Contracts are the durable system boundary."}),ke("p",{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:"ContractSpec uses explicit TypeScript specs to describe behavior before it spreads across APIs, UI, data models, events, and operator flows. The goal is not to hide implementation. The goal is to make the system boundary explicit enough that generation, validation, runtime enforcement, and regeneration can stay coherent."})]}),Et("div",{className:"editorial-proof-strip",children:[Et("div",{className:"editorial-stat",children:[ke("span",{className:"editorial-label",children:"System promise"}),ke("span",{className:"editorial-stat-value",children:"one contract → many surfaces"})]}),ke("p",{className:"max-w-2xl text-muted-foreground text-sm leading-7",children:"Use the contract layer to keep surface behavior aligned, then let runtimes and generators do the repetitive work without inventing a closed platform."})]}),ke("section",{className:"editorial-panel space-y-5",children:Et("div",{className:"space-y-2",children:[ke("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"What the contract layer owns"}),Et("ul",{className:"editorial-list",children:[Et("li",{children:[ke("span",{className:"editorial-list-marker"}),ke("span",{children:"Behavior: operations, events, presentations, workflows."})]}),Et("li",{children:[ke("span",{className:"editorial-list-marker"}),ke("span",{children:"Validation: input, output, and schema boundaries."})]}),Et("li",{children:[ke("span",{className:"editorial-list-marker"}),ke("span",{children:"Governance: policy, auditability, and migration rules."})]}),Et("li",{children:[ke("span",{className:"editorial-list-marker"}),ke("span",{children:"Surface alignment: generated or served behavior across API, UI, data, and agent-facing interfaces."})]})]})]})}),Et("section",{className:"space-y-5",children:[Et("div",{className:"space-y-2",children:[ke("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Specification types"}),ke("p",{className:"text-muted-foreground text-sm leading-7",children:"You can adopt the model one part at a time. Not every system needs every spec type on day one."})]}),ke("div",{className:"grid gap-4 md:grid-cols-2",children:lb.map((e)=>Et(Hd,{href:e.href,className:"editorial-panel",children:[ke("h3",{className:"font-semibold text-xl",children:e.title}),ke("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:e.body}),Et("div",{className:"mt-4 flex items-center gap-2 text-[color:var(--rust)] text-sm",children:["Open section ",ke(Vd,{size:14})]})]},e.title))})]}),Et("section",{className:"space-y-5",children:[Et("div",{className:"space-y-2",children:[ke("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Implemented spec packs"}),ke("p",{className:"text-muted-foreground text-sm leading-7",children:"These packs combine multiple contract surfaces into higher-order systems you can use directly today: agent enforcement, AI-native surface runtime, and governed Builder authoring."})]}),ke("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:db.map((e)=>Et(Hd,{href:e.href,className:"editorial-panel",children:[ke("h3",{className:"font-semibold text-xl",children:e.title}),ke("p",{className:"mt-2 text-muted-foreground text-sm leading-7",children:e.body}),Et("div",{className:"mt-4 flex items-center gap-2 text-[color:var(--rust)] text-sm",children:["Open pack ",ke(Vd,{size:14})]})]},e.title))})]})]})}import Oi from"@contractspec/lib.ui-link";import{ChevronRight as pb}from"lucide-react";import{jsx as w,jsxs as X}from"react/jsx-runtime";function mb(){return X("div",{className:"space-y-8",children:[X("div",{className:"space-y-4",children:[w("h1",{className:"font-bold text-4xl",children:"Policy"}),X("p",{className:"text-muted-foreground",children:["A ",w("strong",{children:"PolicySpec"})," defines who can do what, when, and under what conditions. ContractSpec uses attribute-based access control (ABAC) to enforce policies across your entire application—from API endpoints to UI components."]})]}),X("div",{className:"space-y-4",children:[w("h2",{className:"font-bold text-2xl",children:"Why policies matter"}),w("p",{className:"text-muted-foreground",children:"Traditional access control relies on roles (RBAC), which can become unwieldy as applications grow. ABAC is more flexible—it evaluates policies based on attributes of the user, resource, action, and context."}),X("p",{className:"text-muted-foreground",children:["ContractSpec's policy engine ensures that access control is consistent across all surfaces. You don't have to remember to add authorization checks in every API endpoint or UI component—the"," ",w(Oi,{href:"/docs/safety/pdp",className:"text-violet-400 hover:text-violet-300",children:"Policy Decision Point"})," ","enforces policies automatically."]})]}),X("div",{className:"space-y-4",children:[w("h2",{className:"font-bold text-2xl",children:"Policy structure"}),w("p",{className:"text-muted-foreground",children:"A PolicySpec contains one or more rules. Each rule has:"}),X("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[X("li",{children:[w("strong",{children:"Effect"})," – PERMIT, DENY, or REDACT"]}),X("li",{children:[w("strong",{children:"Condition"})," – A boolean expression that determines when the rule applies"]}),X("li",{children:[w("strong",{children:"Scope"})," – Which resources, actions, or fields the rule applies to"]}),X("li",{children:[w("strong",{children:"Priority"})," – Rules are evaluated in priority order; the first matching rule wins"]})]})]}),X("div",{className:"space-y-4",children:[w("h2",{className:"font-bold text-2xl",children:"Example PolicySpec"}),w("p",{className:"text-muted-foreground",children:"Here's a policy that controls access to customer data in TypeScript:"}),w("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:w("pre",{children:`import { definePolicy } from '@contractspec/lib.contracts-spec';
|
|
4691
4691
|
|
|
4692
4692
|
export const CustomerDataAccess = definePolicy({
|
|
4693
4693
|
meta: {
|
|
@@ -4742,7 +4742,7 @@ export const CustomerDataAccess = definePolicy({
|
|
|
4742
4742
|
sensitivity: PHI
|
|
4743
4743
|
- name: salary
|
|
4744
4744
|
type: number
|
|
4745
|
-
sensitivity: confidential`})}),w("p",{className:"text-muted-foreground",children:'Policies can then reference these tags to enforce blanket rules like "support staff cannot see PII" or "PHI can only be accessed from approved IP addresses."'})]}),X("div",{className:"space-y-4",children:[w("h2",{className:"font-bold text-2xl",children:"Testing policies"}),w("p",{className:"text-muted-foreground",children:"ContractSpec provides tools for testing policies before deployment:"}),X("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[X("li",{children:[w("strong",{children:"Policy simulator"})," – Test how policies evaluate for different users and scenarios"]}),X("li",{children:[w("strong",{children:"Coverage analysis"})," – Identify resources or actions that aren't covered by any policy"]}),X("li",{children:[w("strong",{children:"Conflict detection"})," – Find rules that might conflict or produce unexpected results"]}),X("li",{children:[w("strong",{children:"Audit mode"})," – Run policies in audit-only mode to see what would be blocked without actually blocking it"]})]})]}),X("div",{className:"space-y-4",children:[w("h2",{className:"font-bold text-2xl",children:"Best practices"}),X("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[w("li",{children:"Start with a deny-by-default policy—explicitly permit what should be allowed."}),w("li",{children:"Use clear, descriptive rule IDs that explain what the rule does."}),w("li",{children:"Set priorities carefully to ensure rules are evaluated in the right order."}),w("li",{children:"Test policies thoroughly with realistic user scenarios before deploying."}),X("li",{children:["Monitor policy decisions in production using"," ",w(Oi,{href:"/docs/safety/auditing",className:"text-violet-400 hover:text-violet-300",children:"audit logs"}),"."]}),w("li",{children:"Review and update policies regularly as your application and requirements evolve."})]})]}),X("div",{className:"flex items-center gap-4 pt-4",children:[w(Oi,{href:"/docs/specs/workflows",className:"btn-ghost",children:"Previous: Workflows"}),X(Oi,{href:"/docs/specs/overlays",className:"btn-primary",children:["Next: Overlays ",w(
|
|
4745
|
+
sensitivity: confidential`})}),w("p",{className:"text-muted-foreground",children:'Policies can then reference these tags to enforce blanket rules like "support staff cannot see PII" or "PHI can only be accessed from approved IP addresses."'})]}),X("div",{className:"space-y-4",children:[w("h2",{className:"font-bold text-2xl",children:"Testing policies"}),w("p",{className:"text-muted-foreground",children:"ContractSpec provides tools for testing policies before deployment:"}),X("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[X("li",{children:[w("strong",{children:"Policy simulator"})," – Test how policies evaluate for different users and scenarios"]}),X("li",{children:[w("strong",{children:"Coverage analysis"})," – Identify resources or actions that aren't covered by any policy"]}),X("li",{children:[w("strong",{children:"Conflict detection"})," – Find rules that might conflict or produce unexpected results"]}),X("li",{children:[w("strong",{children:"Audit mode"})," – Run policies in audit-only mode to see what would be blocked without actually blocking it"]})]})]}),X("div",{className:"space-y-4",children:[w("h2",{className:"font-bold text-2xl",children:"Best practices"}),X("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[w("li",{children:"Start with a deny-by-default policy—explicitly permit what should be allowed."}),w("li",{children:"Use clear, descriptive rule IDs that explain what the rule does."}),w("li",{children:"Set priorities carefully to ensure rules are evaluated in the right order."}),w("li",{children:"Test policies thoroughly with realistic user scenarios before deploying."}),X("li",{children:["Monitor policy decisions in production using"," ",w(Oi,{href:"/docs/safety/auditing",className:"text-violet-400 hover:text-violet-300",children:"audit logs"}),"."]}),w("li",{children:"Review and update policies regularly as your application and requirements evolve."})]})]}),X("div",{className:"flex items-center gap-4 pt-4",children:[w(Oi,{href:"/docs/specs/workflows",className:"btn-ghost",children:"Previous: Workflows"}),X(Oi,{href:"/docs/specs/overlays",className:"btn-primary",children:["Next: Overlays ",w(pb,{size:16})]})]})]})}import Rn from"@contractspec/lib.ui-link";import{ChevronRight as ub}from"lucide-react";import{jsx as M,jsxs as he}from"react/jsx-runtime";function gb(){return he("div",{className:"space-y-8",children:[he("div",{className:"space-y-4",children:[M("h1",{className:"font-bold text-4xl",children:"Workflows"}),he("p",{className:"text-muted-foreground",children:["A ",M("strong",{children:"WorkflowSpec"})," orchestrates multi-step processes. It defines the sequence of operations, handles failures with retries and compensation, and provides observability into long-running tasks."]})]}),he("div",{className:"space-y-4",children:[M("h2",{className:"font-bold text-2xl",children:"Core concepts"}),he("div",{className:"space-y-3",children:[he("div",{children:[M("h3",{className:"font-semibold text-lg",children:"Identifiers"}),he("p",{className:"text-muted-foreground",children:["Each workflow has a unique"," ",M("code",{className:"rounded bg-background/50 px-2 py-1",children:"workflowId"})," ","and a"," ",M("code",{className:"rounded bg-background/50 px-2 py-1",children:"version"}),". This allows you to run multiple versions of the same workflow simultaneously during migrations or A/B tests."]})]}),he("div",{children:[M("h3",{className:"font-semibold text-lg",children:"Steps"}),he("p",{className:"text-muted-foreground",children:["A workflow is composed of ",M("strong",{children:"steps"}),". Each step invokes a"," ",M(Rn,{href:"/docs/specs/capabilities",className:"text-violet-400 hover:text-violet-300",children:"CapabilitySpec"}),", passes inputs, and receives outputs. Steps can run sequentially or in parallel."]})]}),he("div",{children:[M("h3",{className:"font-semibold text-lg",children:"Transitions"}),he("p",{className:"text-muted-foreground",children:[M("strong",{children:"Transitions"}),' define the flow between steps. They can be conditional (e.g., "if payment succeeds, go to step 3; otherwise, go to step 5") or unconditional.']})]}),he("div",{children:[M("h3",{className:"font-semibold text-lg",children:"Retries"}),M("p",{className:"text-muted-foreground",children:"If a step fails, the workflow can retry it with exponential backoff. You specify the maximum number of retries and the backoff strategy in the spec."})]}),he("div",{children:[M("h3",{className:"font-semibold text-lg",children:"Compensation"}),he("p",{className:"text-muted-foreground",children:["When a workflow fails partway through,"," ",M("strong",{children:"compensation"})," steps undo the effects of completed steps (e.g., refunding a payment, releasing a reservation). This ensures consistency even in failure scenarios."]})]}),he("div",{children:[M("h3",{className:"font-semibold text-lg",children:"SLAs"}),M("p",{className:"text-muted-foreground",children:"You can define Service Level Agreements (SLAs) for each step or the entire workflow. If a step exceeds its SLA, the system can trigger alerts or escalations."})]})]})]}),he("div",{className:"space-y-4",children:[M("h2",{className:"font-bold text-2xl",children:"Example WorkflowSpec (TypeScript)"}),M("p",{className:"text-muted-foreground",children:"Here's a simplified example of a payment workflow in TypeScript:"}),he("p",{className:"text-muted-foreground text-sm",children:["For Vercel Workflow and other VM-evaluated runtimes, author workflow specs from"," ",M("code",{className:"rounded bg-background/50 px-2 py-1",children:"@contractspec/lib.contracts-spec/workflow/spec"})," ","rather than the broad workflow barrel."]}),M("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:M("pre",{children:`import { defineWorkflow } from '@contractspec/lib.contracts-spec/workflow/spec';
|
|
4746
4746
|
import { ValidatePaymentMethod, ChargePayment, SendEmail } from './specs';
|
|
4747
4747
|
|
|
4748
4748
|
export const PaymentFlow = defineWorkflow({
|
|
@@ -4794,9 +4794,9 @@ export const PaymentFlow = defineWorkflow({
|
|
|
4794
4794
|
maxDuration: 30000, // milliseconds
|
|
4795
4795
|
alertOnBreach: true,
|
|
4796
4796
|
},
|
|
4797
|
-
});`})})]}),he("div",{className:"space-y-4",children:[M("h2",{className:"font-bold text-2xl",children:"Triggers"}),M("p",{className:"text-muted-foreground",children:"Workflows can be triggered in several ways:"}),he("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[he("li",{children:[M("strong",{children:"Manual invocation"})," – A user or system calls the workflow via an API endpoint."]}),he("li",{children:[M("strong",{children:"Event-driven"})," – The workflow starts automatically when a specific event occurs (e.g., a new order is created)."]}),he("li",{children:[M("strong",{children:"Scheduled"})," – The workflow runs on a cron schedule (e.g., nightly batch processing)."]}),he("li",{children:[M("strong",{children:"Chained"})," – One workflow can invoke another as a step."]})]})]}),he("div",{className:"space-y-4",children:[M("h2",{className:"font-bold text-2xl",children:"Monitoring and versioning"}),M("p",{className:"text-muted-foreground",children:"ContractSpec automatically instruments workflows with telemetry. You can view:"}),he("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[M("li",{children:"Real-time execution status for each step"}),M("li",{children:"Historical run data and success/failure rates"}),M("li",{children:"Latency distributions and SLA compliance"}),M("li",{children:"Compensation events and retry attempts"})]}),M("p",{className:"text-muted-foreground",children:"When you update a workflow, you increment its version. Running workflows continue on their original version, while new invocations use the latest version. This allows safe, zero-downtime deployments."})]}),he("div",{className:"space-y-4",children:[M("h2",{className:"font-bold text-2xl",children:"Best practices"}),he("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[M("li",{children:"Keep steps idempotent – they should be safe to retry without side effects."}),M("li",{children:"Define compensation for any step that modifies external state."}),M("li",{children:"Use meaningful step IDs that describe the operation."}),M("li",{children:"Set realistic SLAs and monitor them in production."}),M("li",{children:"Test failure scenarios locally before deploying."})]})]}),he("div",{className:"flex items-center gap-4 pt-4",children:[M(Tn,{href:"/docs/specs/capabilities",className:"btn-ghost",children:"Previous: Capabilities"}),he(Tn,{href:"/docs/safety",className:"btn-primary",children:["Next: Safety Features ",M(lb,{size:16})]})]})]})}import sb from"@contractspec/lib.ui-link";import{jsx as An,jsxs as mb}from"react/jsx-runtime";function pb(){return mb("main",{className:"space-y-6 py-12",children:[An("h1",{className:"font-bold text-3xl",children:"Studio docs moved"}),An("p",{className:"text-muted-foreground text-sm",children:"Security and BYOK guidance now lives in the Studio app docs."}),An(sb,{href:"https://www.contractspec.studio/docs",className:"btn-primary",children:"Open Studio docs"})]})}import ub from"@contractspec/lib.ui-link";import{jsx as Rn,jsxs as fb}from"react/jsx-runtime";function gb(){return fb("main",{className:"space-y-6 py-12",children:[Rn("h1",{className:"font-bold text-3xl",children:"Studio docs moved"}),Rn("p",{className:"text-muted-foreground text-sm",children:"Deployment guidance now lives in the Studio app docs."}),Rn(ub,{href:"https://www.contractspec.studio/docs",className:"btn-primary",children:"Open Studio docs"})]})}import hb from"@contractspec/lib.ui-link";import{jsx as Ln,jsxs as bb}from"react/jsx-runtime";function yb(){return bb("main",{className:"space-y-6 py-12",children:[Ln("h1",{className:"font-bold text-3xl",children:"Studio docs moved"}),Ln("p",{className:"text-muted-foreground text-sm",children:"The latest getting-started guide now lives in the Studio app docs."}),Ln(hb,{href:"https://www.contractspec.studio/docs",className:"btn-primary",children:"Open Studio docs"})]})}import vb from"@contractspec/lib.ui-link";import{jsx as Dn,jsxs as wb}from"react/jsx-runtime";function Nb(){return wb("main",{className:"space-y-6 py-12",children:[Dn("h1",{className:"font-bold text-3xl",children:"Studio docs moved"}),Dn("p",{className:"text-muted-foreground text-sm",children:"Integration guides now live in the Studio app docs."}),Dn(vb,{href:"https://www.contractspec.studio/docs",className:"btn-primary",children:"Open Studio docs"})]})}import Lr from"@contractspec/lib.ui-link";import{jsx as Le,jsxs as ea}from"react/jsx-runtime";var kb=["decision workflows that turn product evidence into proposed spec changes","governed execution loops and task packs on top of the OSS contract layer","operator surfaces for teams that need a managed workflow instead of raw building blocks","deeper product-facing workflows that sit above the open system without replacing it"];function Sb(){return ea("main",{className:"space-y-10",children:[ea("section",{className:"space-y-3",children:[Le("p",{className:"editorial-kicker",children:"Studio bridge"}),Le("h1",{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"Studio is the operating layer built on top of OSS ContractSpec."}),Le("p",{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:"Start with the open system first: contracts, generated surfaces, runtimes, integrations, and safe regeneration. Move to Studio when a team wants the product-facing workflow, decision loop, and managed operator surface on top of that foundation."})]}),ea("section",{className:"editorial-proof-strip",children:[ea("div",{className:"editorial-stat",children:[Le("span",{className:"editorial-label",children:"What stays open"}),Le("span",{className:"editorial-stat-value",children:"contracts, code, generated surfaces"})]}),Le("p",{className:"max-w-2xl text-muted-foreground text-sm leading-7",children:"Studio is additive. It does not replace the OSS source of truth or ask teams to abandon their contract layer."})]}),ea("section",{className:"grid gap-4 md:grid-cols-2",children:[ea("article",{className:"editorial-panel space-y-4",children:[Le("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Start with OSS when you need:"}),ea("ul",{className:"editorial-list",children:[ea("li",{children:[Le("span",{className:"editorial-list-marker"}),Le("span",{children:"explicit contracts and generated surfaces you still own"})]}),ea("li",{children:[Le("span",{className:"editorial-list-marker"}),Le("span",{children:"incremental adoption inside an existing codebase"})]}),ea("li",{children:[Le("span",{className:"editorial-list-marker"}),Le("span",{children:"runtime governance, integrations, and safe regeneration without a managed operating product"})]})]})]}),ea("article",{className:"editorial-panel space-y-4",children:[Le("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Adopt Studio when you need:"}),Le("ul",{className:"editorial-list",children:kb.map((e)=>ea("li",{children:[Le("span",{className:"editorial-list-marker"}),Le("span",{children:e})]},e))})]})]}),ea("section",{className:"editorial-panel space-y-4",children:[Le("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Builder is the governed authoring layer"}),Le("p",{className:"text-muted-foreground text-sm leading-7",children:"If your team wants a concrete authoring control plane on top of the OSS foundation, start with the Builder control-plane docs and the workbench host guide before you dive into the larger Studio product surface."}),ea("div",{className:"flex flex-wrap gap-3",children:[Le(Lr,{href:"/docs/specs/builder-control-plane",className:"btn-primary",children:"Builder control plane"}),Le(Lr,{href:"/docs/guides/host-builder-workbench",className:"btn-ghost",children:"Host the Builder workbench"})]})]}),ea("section",{className:"editorial-panel space-y-4",children:[Le("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Go to the Studio product docs for the full product surface"}),Le("p",{className:"text-muted-foreground text-sm leading-7",children:"The OSS site keeps this section intentionally short. Deep Studio product guidance belongs in the Studio app docs."}),ea("div",{className:"flex flex-wrap gap-3",children:[Le(Lr,{href:"https://www.contractspec.studio",className:"btn-primary",children:"Open Studio"}),Le(Lr,{href:"https://www.contractspec.studio/docs",className:"btn-ghost",children:"Read Studio docs"})]})]})]})}import Cb from"@contractspec/lib.ui-link";import{jsx as En,jsxs as Pb}from"react/jsx-runtime";function Ib(){return Pb("main",{className:"space-y-6 py-12",children:[En("h1",{className:"font-bold text-3xl",children:"Studio docs moved"}),En("p",{className:"text-muted-foreground text-sm",children:"Visual builder documentation now lives in the Studio app docs."}),En(Cb,{href:"https://www.contractspec.studio/docs",className:"btn-primary",children:"Open Studio docs"})]})}import{Button as On}from"@contractspec/lib.design-system";import{PlugZap as Tb,ToggleRight as Ab}from"lucide-react";import{jsx as hi,jsxs as Go}from"react/jsx-runtime";function qd({id:e,provider:t,name:a,category:r,enabled:l=!0,lastSyncAt:b,status:h="connected",onToggle:v,onConfigure:V}){return Go("div",{className:"flex flex-col gap-4 rounded-2xl border border-border bg-card p-4 shadow-sm",children:[Go("header",{className:"flex items-center justify-between",children:[Go("div",{children:[hi("p",{className:"font-semibold text-xl",children:a}),hi("p",{className:"text-muted-foreground text-sm",children:t})]}),Go(On,{variant:"outline",size:"sm",className:`inline-flex items-center gap-2 rounded-full border px-3 py-1 font-semibold text-xs uppercase tracking-wide ${h==="connected"?"text-emerald-500 bg-emerald-500/10 border-emerald-500/30":h==="error"?"text-red-500 bg-red-500/10 border-red-500/30":"text-gray-500 bg-gray-500/10 border-gray-500/30"}`,onPress:()=>v?.(e,!l),children:[hi(Ab,{className:"h-3.5 w-3.5"}),l?"Enabled":"Disabled"]})]}),Go("div",{className:"text-muted-foreground text-sm",children:[r&&hi("span",{className:"font-medium",children:r}),Go("div",{className:"mt-2 flex flex-wrap items-center gap-3 text-xs uppercase tracking-wide",children:[Go("span",{className:"inline-flex items-center gap-1",children:[hi(Tb,{className:"h-3 w-3"}),h]}),Go("span",{children:["Last sync:"," ",b?new Date(b).toLocaleString():"Not synced yet"]})]})]}),Go("footer",{className:"flex items-center gap-2",children:[hi(On,{className:"flex-1",onPress:()=>V?.(e),children:"Configure"}),hi(On,{variant:"ghost",className:"flex-1",onPress:()=>v?.(e,!l),children:l?"Disconnect":"Connect"})]})]})}import{Input as Rb}from"@contractspec/lib.design-system";import{Select as Lb,SelectContent as Db,SelectItem as Hd,SelectTrigger as Eb,SelectValue as Ob}from"@contractspec/lib.ui-kit-web/ui/select";import{Boxes as Bb,Search as Mb}from"lucide-react";import*as tr from"react";import{jsx as Xa,jsxs as yi}from"react/jsx-runtime";function GL({integrations:e,onToggle:t,onConfigure:a}){let[r,l]=tr.useState(""),[b,h]=tr.useState("all"),v=tr.useMemo(()=>Array.from(new Set(e.map((g)=>g.category))),[e]),V=e.filter((g)=>{let tt=g.name.toLowerCase().includes(r.toLowerCase())||g.provider.toLowerCase().includes(r.toLowerCase()),va=b==="all"?!0:g.category===b;return tt&&va});return yi("div",{className:"space-y-4 rounded-2xl border border-border bg-card p-4",children:[yi("header",{className:"flex flex-wrap items-center justify-between gap-3",children:[yi("div",{children:[Xa("p",{className:"font-semibold text-sm uppercase tracking-wide",children:"Integration marketplace"}),Xa("p",{className:"text-muted-foreground text-sm",children:"Connect AI providers, payments, analytics, and internal tools with BYOK controls."})]}),Xa(Bb,{className:"h-5 w-5 text-muted-foreground"})]}),yi("div",{className:"flex flex-wrap gap-3",children:[yi("div",{className:"relative min-w-[200px] flex-1",children:[Xa(Mb,{className:"pointer-events-none absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),Xa(Rb,{type:"search","aria-label":"Search providers",className:"w-full py-2 pr-3 pl-9 text-sm",value:r,onChange:(g)=>l(g.target.value),placeholder:"Search providers"})]}),yi(Lb,{value:b,onValueChange:h,children:[Xa(Eb,{className:"w-[200px]",children:Xa(Ob,{placeholder:"All categories"})}),yi(Db,{children:[Xa(Hd,{value:"all",children:"All categories"}),v.map((g)=>Xa(Hd,{value:g,children:g},g))]})]})]}),Xa("div",{className:"grid gap-4 md:grid-cols-2",children:V.length?V.map((g)=>Xa(qd,{id:g.id,provider:g.provider,name:g.name,category:g.category,enabled:g.enabled,status:g.status,lastSyncAt:g.lastSyncAt,onToggle:t,onConfigure:a},g.id)):Xa("div",{className:"rounded-xl border border-border border-dashed p-6 text-center text-muted-foreground text-sm md:col-span-2",children:"No integrations match your filters."})})]})}import{Button as Vd,Input as Bn,Textarea as Ub}from"@contractspec/lib.design-system";import{Checkbox as Wb}from"@contractspec/lib.ui-kit-web/ui/checkbox";import{Label as Bi}from"@contractspec/lib.ui-kit-web/ui/label";import{Select as Fd,SelectContent as Kd,SelectItem as Dr,SelectTrigger as Qd,SelectValue as Yd}from"@contractspec/lib.ui-kit-web/ui/select";import{Key as _b,ShieldCheck as zb,TestTube2 as Gb}from"lucide-react";import*as Jd from"react";import{jsx as Se,jsxs as et}from"react/jsx-runtime";function JL({provider:e,initialValues:t,onTestConnection:a,onSave:r,isSaving:l,isTesting:b}){let[h,v]=Jd.useState({apiKey:t?.apiKey??"",secret:t?.secret??"",ownershipMode:t?.ownershipMode??"managed",secretProvider:t?.secretProvider??"env",secretRef:t?.secretRef??"",config:t?.config??`{
|
|
4797
|
+
});`})})]}),he("div",{className:"space-y-4",children:[M("h2",{className:"font-bold text-2xl",children:"Triggers"}),M("p",{className:"text-muted-foreground",children:"Workflows can be triggered in several ways:"}),he("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[he("li",{children:[M("strong",{children:"Manual invocation"})," – A user or system calls the workflow via an API endpoint."]}),he("li",{children:[M("strong",{children:"Event-driven"})," – The workflow starts automatically when a specific event occurs (e.g., a new order is created)."]}),he("li",{children:[M("strong",{children:"Scheduled"})," – The workflow runs on a cron schedule (e.g., nightly batch processing)."]}),he("li",{children:[M("strong",{children:"Chained"})," – One workflow can invoke another as a step."]})]})]}),he("div",{className:"space-y-4",children:[M("h2",{className:"font-bold text-2xl",children:"Monitoring and versioning"}),M("p",{className:"text-muted-foreground",children:"ContractSpec automatically instruments workflows with telemetry. You can view:"}),he("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[M("li",{children:"Real-time execution status for each step"}),M("li",{children:"Historical run data and success/failure rates"}),M("li",{children:"Latency distributions and SLA compliance"}),M("li",{children:"Compensation events and retry attempts"})]}),M("p",{className:"text-muted-foreground",children:"When you update a workflow, you increment its version. Running workflows continue on their original version, while new invocations use the latest version. This allows safe, zero-downtime deployments."})]}),he("div",{className:"space-y-4",children:[M("h2",{className:"font-bold text-2xl",children:"Best practices"}),he("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[M("li",{children:"Keep steps idempotent – they should be safe to retry without side effects."}),M("li",{children:"Define compensation for any step that modifies external state."}),M("li",{children:"Use meaningful step IDs that describe the operation."}),M("li",{children:"Set realistic SLAs and monitor them in production."}),M("li",{children:"Test failure scenarios locally before deploying."})]})]}),he("div",{className:"flex items-center gap-4 pt-4",children:[M(Rn,{href:"/docs/specs/capabilities",className:"btn-ghost",children:"Previous: Capabilities"}),he(Rn,{href:"/docs/safety",className:"btn-primary",children:["Next: Safety Features ",M(ub,{size:16})]})]})]})}import fb from"@contractspec/lib.ui-link";import{jsx as Ln,jsxs as yb}from"react/jsx-runtime";function hb(){return yb("main",{className:"space-y-6 py-12",children:[Ln("h1",{className:"font-bold text-3xl",children:"Studio docs moved"}),Ln("p",{className:"text-muted-foreground text-sm",children:"Security and BYOK guidance now lives in the Studio app docs."}),Ln(fb,{href:"https://www.contractspec.studio/docs",className:"btn-primary",children:"Open Studio docs"})]})}import bb from"@contractspec/lib.ui-link";import{jsx as Dn,jsxs as Nb}from"react/jsx-runtime";function vb(){return Nb("main",{className:"space-y-6 py-12",children:[Dn("h1",{className:"font-bold text-3xl",children:"Studio docs moved"}),Dn("p",{className:"text-muted-foreground text-sm",children:"Deployment guidance now lives in the Studio app docs."}),Dn(bb,{href:"https://www.contractspec.studio/docs",className:"btn-primary",children:"Open Studio docs"})]})}import wb from"@contractspec/lib.ui-link";import{jsx as En,jsxs as Sb}from"react/jsx-runtime";function kb(){return Sb("main",{className:"space-y-6 py-12",children:[En("h1",{className:"font-bold text-3xl",children:"Studio docs moved"}),En("p",{className:"text-muted-foreground text-sm",children:"The latest getting-started guide now lives in the Studio app docs."}),En(wb,{href:"https://www.contractspec.studio/docs",className:"btn-primary",children:"Open Studio docs"})]})}import Cb from"@contractspec/lib.ui-link";import{jsx as On,jsxs as Pb}from"react/jsx-runtime";function Ib(){return Pb("main",{className:"space-y-6 py-12",children:[On("h1",{className:"font-bold text-3xl",children:"Studio docs moved"}),On("p",{className:"text-muted-foreground text-sm",children:"Integration guides now live in the Studio app docs."}),On(Cb,{href:"https://www.contractspec.studio/docs",className:"btn-primary",children:"Open Studio docs"})]})}import Lr from"@contractspec/lib.ui-link";import{jsx as Le,jsxs as ea}from"react/jsx-runtime";var Tb=["decision workflows that turn product evidence into proposed spec changes","governed execution loops and task packs on top of the OSS contract layer","operator surfaces for teams that need a managed workflow instead of raw building blocks","deeper product-facing workflows that sit above the open system without replacing it"];function Ab(){return ea("main",{className:"space-y-10",children:[ea("section",{className:"space-y-3",children:[Le("p",{className:"editorial-kicker",children:"Studio bridge"}),Le("h1",{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"Studio is the operating layer built on top of OSS ContractSpec."}),Le("p",{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:"Start with the open system first: contracts, generated surfaces, runtimes, integrations, and safe regeneration. Move to Studio when a team wants the product-facing workflow, decision loop, and managed operator surface on top of that foundation."})]}),ea("section",{className:"editorial-proof-strip",children:[ea("div",{className:"editorial-stat",children:[Le("span",{className:"editorial-label",children:"What stays open"}),Le("span",{className:"editorial-stat-value",children:"contracts, code, generated surfaces"})]}),Le("p",{className:"max-w-2xl text-muted-foreground text-sm leading-7",children:"Studio is additive. It does not replace the OSS source of truth or ask teams to abandon their contract layer."})]}),ea("section",{className:"grid gap-4 md:grid-cols-2",children:[ea("article",{className:"editorial-panel space-y-4",children:[Le("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Start with OSS when you need:"}),ea("ul",{className:"editorial-list",children:[ea("li",{children:[Le("span",{className:"editorial-list-marker"}),Le("span",{children:"explicit contracts and generated surfaces you still own"})]}),ea("li",{children:[Le("span",{className:"editorial-list-marker"}),Le("span",{children:"incremental adoption inside an existing codebase"})]}),ea("li",{children:[Le("span",{className:"editorial-list-marker"}),Le("span",{children:"runtime governance, integrations, and safe regeneration without a managed operating product"})]})]})]}),ea("article",{className:"editorial-panel space-y-4",children:[Le("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Adopt Studio when you need:"}),Le("ul",{className:"editorial-list",children:Tb.map((e)=>ea("li",{children:[Le("span",{className:"editorial-list-marker"}),Le("span",{children:e})]},e))})]})]}),ea("section",{className:"editorial-panel space-y-4",children:[Le("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Builder is the governed authoring layer"}),Le("p",{className:"text-muted-foreground text-sm leading-7",children:"If your team wants a concrete authoring control plane on top of the OSS foundation, start with the Builder control-plane docs and the workbench host guide before you dive into the larger Studio product surface."}),ea("div",{className:"flex flex-wrap gap-3",children:[Le(Lr,{href:"/docs/specs/builder-control-plane",className:"btn-primary",children:"Builder control plane"}),Le(Lr,{href:"/docs/guides/host-builder-workbench",className:"btn-ghost",children:"Host the Builder workbench"})]})]}),ea("section",{className:"editorial-panel space-y-4",children:[Le("h2",{className:"font-serif text-3xl tracking-[-0.03em]",children:"Go to the Studio product docs for the full product surface"}),Le("p",{className:"text-muted-foreground text-sm leading-7",children:"The OSS site keeps this section intentionally short. Deep Studio product guidance belongs in the Studio app docs."}),ea("div",{className:"flex flex-wrap gap-3",children:[Le(Lr,{href:"https://www.contractspec.studio",className:"btn-primary",children:"Open Studio"}),Le(Lr,{href:"https://www.contractspec.studio/docs",className:"btn-ghost",children:"Read Studio docs"})]})]})]})}import Rb from"@contractspec/lib.ui-link";import{jsx as Bn,jsxs as Db}from"react/jsx-runtime";function Lb(){return Db("main",{className:"space-y-6 py-12",children:[Bn("h1",{className:"font-bold text-3xl",children:"Studio docs moved"}),Bn("p",{className:"text-muted-foreground text-sm",children:"Visual builder documentation now lives in the Studio app docs."}),Bn(Rb,{href:"https://www.contractspec.studio/docs",className:"btn-primary",children:"Open Studio docs"})]})}import{Button as Mn}from"@contractspec/lib.design-system";import{PlugZap as Eb,ToggleRight as Ob}from"lucide-react";import{jsx as hi,jsxs as Go}from"react/jsx-runtime";function Fd({id:e,provider:t,name:a,category:r,enabled:l=!0,lastSyncAt:b,status:h="connected",onToggle:v,onConfigure:V}){return Go("div",{className:"flex flex-col gap-4 rounded-2xl border border-border bg-card p-4 shadow-sm",children:[Go("header",{className:"flex items-center justify-between",children:[Go("div",{children:[hi("p",{className:"font-semibold text-xl",children:a}),hi("p",{className:"text-muted-foreground text-sm",children:t})]}),Go(Mn,{variant:"outline",size:"sm",className:`inline-flex items-center gap-2 rounded-full border px-3 py-1 font-semibold text-xs uppercase tracking-wide ${h==="connected"?"text-emerald-500 bg-emerald-500/10 border-emerald-500/30":h==="error"?"text-red-500 bg-red-500/10 border-red-500/30":"text-gray-500 bg-gray-500/10 border-gray-500/30"}`,onPress:()=>v?.(e,!l),children:[hi(Ob,{className:"h-3.5 w-3.5"}),l?"Enabled":"Disabled"]})]}),Go("div",{className:"text-muted-foreground text-sm",children:[r&&hi("span",{className:"font-medium",children:r}),Go("div",{className:"mt-2 flex flex-wrap items-center gap-3 text-xs uppercase tracking-wide",children:[Go("span",{className:"inline-flex items-center gap-1",children:[hi(Eb,{className:"h-3 w-3"}),h]}),Go("span",{children:["Last sync:"," ",b?new Date(b).toLocaleString():"Not synced yet"]})]})]}),Go("footer",{className:"flex items-center gap-2",children:[hi(Mn,{className:"flex-1",onPress:()=>V?.(e),children:"Configure"}),hi(Mn,{variant:"ghost",className:"flex-1",onPress:()=>v?.(e,!l),children:l?"Disconnect":"Connect"})]})]})}import{Input as Bb}from"@contractspec/lib.design-system";import{Select as Mb,SelectContent as Ub,SelectItem as Kd,SelectTrigger as Wb,SelectValue as _b}from"@contractspec/lib.ui-kit-web/ui/select";import{Boxes as zb,Search as Gb}from"lucide-react";import*as tr from"react";import{jsx as Xa,jsxs as yi}from"react/jsx-runtime";function QL({integrations:e,onToggle:t,onConfigure:a}){let[r,l]=tr.useState(""),[b,h]=tr.useState("all"),v=tr.useMemo(()=>Array.from(new Set(e.map((g)=>g.category))),[e]),V=e.filter((g)=>{let tt=g.name.toLowerCase().includes(r.toLowerCase())||g.provider.toLowerCase().includes(r.toLowerCase()),va=b==="all"?!0:g.category===b;return tt&&va});return yi("div",{className:"space-y-4 rounded-2xl border border-border bg-card p-4",children:[yi("header",{className:"flex flex-wrap items-center justify-between gap-3",children:[yi("div",{children:[Xa("p",{className:"font-semibold text-sm uppercase tracking-wide",children:"Integration marketplace"}),Xa("p",{className:"text-muted-foreground text-sm",children:"Connect AI providers, payments, analytics, and internal tools with BYOK controls."})]}),Xa(zb,{className:"h-5 w-5 text-muted-foreground"})]}),yi("div",{className:"flex flex-wrap gap-3",children:[yi("div",{className:"relative min-w-[200px] flex-1",children:[Xa(Gb,{className:"pointer-events-none absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),Xa(Bb,{type:"search","aria-label":"Search providers",className:"w-full py-2 pr-3 pl-9 text-sm",value:r,onChange:(g)=>l(g.target.value),placeholder:"Search providers"})]}),yi(Mb,{value:b,onValueChange:h,children:[Xa(Wb,{className:"w-[200px]",children:Xa(_b,{placeholder:"All categories"})}),yi(Ub,{children:[Xa(Kd,{value:"all",children:"All categories"}),v.map((g)=>Xa(Kd,{value:g,children:g},g))]})]})]}),Xa("div",{className:"grid gap-4 md:grid-cols-2",children:V.length?V.map((g)=>Xa(Fd,{id:g.id,provider:g.provider,name:g.name,category:g.category,enabled:g.enabled,status:g.status,lastSyncAt:g.lastSyncAt,onToggle:t,onConfigure:a},g.id)):Xa("div",{className:"rounded-xl border border-border border-dashed p-6 text-center text-muted-foreground text-sm md:col-span-2",children:"No integrations match your filters."})})]})}import{Button as Qd,Input as Un,Textarea as qb}from"@contractspec/lib.design-system";import{Checkbox as Hb}from"@contractspec/lib.ui-kit-web/ui/checkbox";import{Label as Bi}from"@contractspec/lib.ui-kit-web/ui/label";import{Select as Yd,SelectContent as Jd,SelectItem as Dr,SelectTrigger as Zd,SelectValue as $d}from"@contractspec/lib.ui-kit-web/ui/select";import{Key as Vb,ShieldCheck as Fb,TestTube2 as Kb}from"lucide-react";import*as Xd from"react";import{jsx as Se,jsxs as et}from"react/jsx-runtime";function eD({provider:e,initialValues:t,onTestConnection:a,onSave:r,isSaving:l,isTesting:b}){let[h,v]=Xd.useState({apiKey:t?.apiKey??"",secret:t?.secret??"",ownershipMode:t?.ownershipMode??"managed",secretProvider:t?.secretProvider??"env",secretRef:t?.secretRef??"",config:t?.config??`{
|
|
4798
4798
|
"region": "eu-west-1"
|
|
4799
|
-
}`}),V=(g)=>{let tt=g.target,{name:va,value:ye}=tt;v((Ke)=>({...Ke,[va]:ye}))};return et("div",{className:"space-y-4 rounded-2xl border border-border bg-card p-4",children:[et("header",{className:"flex flex-wrap items-center justify-between gap-3",children:[et("div",{children:[et("p",{className:"font-semibold text-sm uppercase tracking-wide",children:[e," credentials"]}),Se("p",{className:"text-muted-foreground text-sm",children:"Store encrypted keys with BYOK and run safe connection tests."})]}),Se(zb,{className:"h-5 w-5 text-muted-foreground"})]}),Se("div",{className:"grid gap-4 md:grid-cols-2",children:et("div",{className:"space-y-2",children:[Se(Bi,{htmlFor:"ownershipMode",children:"Ownership"}),et(Fd,{value:h.ownershipMode??"managed",onValueChange:(g)=>v((tt)=>({...tt,ownershipMode:g})),children:[Se(Qd,{id:"ownershipMode",className:"w-full",children:Se(Yd,{})}),et(Kd,{children:[Se(Dr,{value:"managed",children:"Managed (store encrypted)"}),Se(Dr,{value:"byok",children:"BYOK (store secret reference)"})]})]})]})}),et("div",{className:"grid gap-4 md:grid-cols-2",children:[et("div",{className:"space-y-1 text-sm",children:[Se(Bi,{htmlFor:"apiKey",className:"font-semibold",children:"API key"}),et("div",{className:"relative",children:[Se(_b,{className:"pointer-events-none absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),Se(Bn,{type:"text",name:"apiKey",id:"apiKey",className:"w-full py-2 pr-3 pl-9",value:h.apiKey,onChange:V,required:!0})]})]}),et("div",{className:"space-y-1 text-sm",children:[Se(Bi,{htmlFor:"secret",className:"font-semibold",children:"Secret"}),Se(Bn,{type:"password",id:"secret",name:"secret",className:"w-full px-3 py-2",value:h.secret,onChange:V})]})]}),h.ownershipMode==="byok"?et("div",{className:"space-y-4 rounded-xl border border-blue-500/20 bg-blue-500/5 p-4",children:[Se("p",{className:"font-semibold text-sm",children:"BYOK secret reference"}),et("div",{className:"grid gap-4 md:grid-cols-2",children:[et("div",{className:"space-y-2",children:[Se(Bi,{htmlFor:"secretProvider",children:"Secret provider"}),et(Fd,{value:h.secretProvider??"env",onValueChange:(g)=>v((tt)=>({...tt,secretProvider:g})),children:[Se(Qd,{id:"secretProvider",className:"w-full",children:Se(Yd,{})}),et(Kd,{children:[Se(Dr,{value:"env",children:"Environment"}),Se(Dr,{value:"gcp",children:"GCP Secret Manager"})]})]})]}),et("div",{className:"space-y-2",children:[Se(Bi,{htmlFor:"secretRef",children:"Secret reference"}),Se(Bn,{id:"secretRef",name:"secretRef",placeholder:h.secretProvider==="gcp"?"gcp://projects/.../secrets/...":"env://MY_TOKEN_ENV_VAR",value:h.secretRef??"",onChange:V})]})]})]}):et("div",{className:"flex items-center gap-3 rounded-xl border border-emerald-500/20 bg-emerald-500/5 p-4 text-sm",children:[Se(Wb,{checked:!0,onCheckedChange:()=>{},"aria-label":"Managed"}),et("div",{children:[Se("p",{className:"font-semibold",children:"Managed encryption enabled"}),Se("p",{className:"text-muted-foreground",children:"Secrets are encrypted server-side for this tenant."})]})]}),et("div",{className:"space-y-1 text-sm",children:[Se(Bi,{htmlFor:"config",className:"font-semibold",children:"Configuration (JSON)"}),Se(Ub,{id:"config",name:"config",className:"min-h-[140px] w-full font-mono text-sm",value:h.config,onChange:V})]}),et("div",{className:"flex flex-wrap items-center gap-3",children:[et(Vd,{variant:"ghost",onPress:()=>a?.(h),disabled:b,children:[Se(Gb,{className:"h-4 w-4"}),"Test connection"]}),Se(Vd,{variant:"default",onPress:()=>r?.(h),disabled:l,children:"Save settings"})]})]})}import{BookCopy as qb,Plus as Hb,RefreshCcw as Vb}from"lucide-react";import{jsx as so,jsxs as qo}from"react/jsx-runtime";function xL({sources:e,onRefresh:t,onDelete:a,onAdd:r}){return qo("div",{className:"space-y-4 rounded-2xl border border-border bg-card p-4",children:[qo("header",{className:"flex flex-wrap items-center justify-between gap-3",children:[qo("div",{children:[so("p",{className:"font-semibold text-sm uppercase tracking-wide",children:"Knowledge sources"}),so("p",{className:"text-muted-foreground text-sm",children:"Manage documentation, specs, and repos powering Studio RAG flows."})]}),qo("button",{type:"button",className:"btn-primary inline-flex items-center gap-2",onClick:r,children:[so(Hb,{className:"h-4 w-4"}),"Add source"]})]}),so("div",{className:"space-y-3",children:e.length?e.map((l)=>qo("div",{className:"flex flex-wrap items-center justify-between gap-3 rounded-xl border border-border bg-background p-4",children:[qo("div",{className:"flex items-center gap-3",children:[so(qb,{className:"h-8 w-8 text-muted-foreground"}),qo("div",{children:[so("p",{className:"font-semibold text-base",children:l.name}),so("p",{className:"text-muted-foreground text-sm",children:l.type}),so("p",{className:"text-muted-foreground text-xs",children:l.indexed?`Indexed ${l.lastIndexed?new Date(l.lastIndexed).toLocaleString():""}`:"Pending indexing"})]})]}),qo("div",{className:"flex items-center gap-2",children:[qo("button",{type:"button",className:"btn-ghost inline-flex items-center gap-1 text-sm",onClick:()=>t?.(l.id),children:[so(Vb,{className:"h-3.5 w-3.5"}),"Reindex"]}),so("button",{type:"button",className:"btn-ghost text-destructive text-sm",onClick:()=>a?.(l.id),children:"Remove"})]})]},l.id)):so("div",{className:"rounded-xl border border-border border-dashed p-6 text-center text-muted-foreground text-sm",children:"No knowledge sources added yet."})})]})}import{jsx as o,jsxs as d}from"react/jsx-runtime";var nD={title:"Privacy Policy | ContractSpec",description:"Learn how ContractSpec collects, uses, and protects your personal data in compliance with GDPR."};function Fb(){return o("main",{className:"flex grow flex-col items-center justify-center pt-24",children:o("section",{className:"section-padding",children:d("div",{className:"prose prose-invert mx-auto max-w-3xl",children:[o("h1",{className:"mb-4 font-bold text-4xl",children:"Privacy Policy"}),o("p",{className:"mb-8 text-muted-foreground",children:"Last updated: December 18, 2025"}),d("section",{className:"space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"1. Who We Are"}),d("p",{className:"text-muted-foreground",children:[o("strong",{className:"text-foreground",children:"ContractSpec"})," is a brand of"," ",o("strong",{className:"text-foreground",children:"CHAMAN VENTURES"}),", a simplified joint-stock company (SASU) registered in France."]}),d("div",{className:"rounded-lg border border-white/10 bg-white/5 p-4 text-muted-foreground",children:[o("p",{className:"mb-2",children:o("strong",{className:"text-foreground",children:"Data Controller:"})}),d("ul",{className:"list-none space-y-1 pl-0",children:[o("li",{children:"CHAMAN VENTURES, SASU"}),o("li",{children:"RCS Paris • SIREN 989 498 902"}),o("li",{children:"229 rue Saint-Honoré, 75001 Paris, France"}),d("li",{children:["Contact:"," ",o("a",{href:"mailto:privacy@contractspec.io",className:"text-primary hover:underline",children:"privacy@contractspec.io"})]})]})]}),o("p",{className:"text-muted-foreground",children:"We are responsible for deciding how we hold and use personal data about you. We are required under data protection legislation to notify you of the information contained in this privacy policy."})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"2. What This Policy Covers"}),o("p",{className:"text-muted-foreground",children:"This privacy policy explains:"}),d("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[o("li",{children:"What personal data we collect through the ContractSpec website and services"}),o("li",{children:"Why we collect and process your data"}),o("li",{children:"How we store and protect your data"}),o("li",{children:"Who we may share your data with"}),o("li",{children:"Your rights under the General Data Protection Regulation (GDPR)"})]}),o("p",{className:"text-muted-foreground",children:"This policy applies to visitors of our website, users who sign up for our waitlist or contact us, and customers who use our services."})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"3. Data We Collect"}),o("p",{className:"text-muted-foreground",children:"We collect different types of data depending on how you interact with ContractSpec:"}),o("div",{className:"overflow-x-auto",children:d("table",{className:"w-full border-collapse text-muted-foreground text-sm",children:[o("thead",{children:d("tr",{className:"border-white/20 border-b",children:[o("th",{className:"py-3 pr-4 text-left font-semibold text-foreground",children:"Category"}),o("th",{className:"py-3 pr-4 text-left font-semibold text-foreground",children:"Data Collected"}),o("th",{className:"py-3 text-left font-semibold text-foreground",children:"When Collected"})]})}),d("tbody",{children:[d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Website Analytics"}),o("td",{className:"py-3 pr-4",children:"Page views, click events, device type, browser, approximate location (country level), session duration, referral source"}),o("td",{className:"py-3",children:"When browsing our website (with consent in EU/EEA)"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Contact / Waitlist"}),o("td",{className:"py-3 pr-4",children:"Name, email address, message content"}),o("td",{className:"py-3",children:"When you submit a form or join our waitlist"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Account Data"}),d("td",{className:"py-3 pr-4",children:[o("em",{children:"Not yet applicable"})," — We do not currently offer user accounts. This section will be updated when accounts are introduced."]}),o("td",{className:"py-3",children:"—"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Billing Data"}),d("td",{className:"py-3 pr-4",children:[o("em",{children:"Not yet applicable"})," — We do not currently process payments. This section will be updated when billing is introduced."]}),o("td",{className:"py-3",children:"—"})]})]})]})})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"4. Why We Process Data (Purposes & Legal Bases)"}),o("p",{className:"text-muted-foreground",children:"Under GDPR, we must have a lawful basis for processing your personal data. We rely on the following:"}),o("div",{className:"overflow-x-auto",children:d("table",{className:"w-full border-collapse text-muted-foreground text-sm",children:[o("thead",{children:d("tr",{className:"border-white/20 border-b",children:[o("th",{className:"py-3 pr-4 text-left font-semibold text-foreground",children:"Purpose"}),o("th",{className:"py-3 pr-4 text-left font-semibold text-foreground",children:"Legal Basis"}),o("th",{className:"py-3 text-left font-semibold text-foreground",children:"Details"})]})}),d("tbody",{children:[d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Website operation & security"}),o("td",{className:"py-3 pr-4",children:"Legitimate interest"}),o("td",{className:"py-3",children:"Ensuring our website functions correctly, preventing abuse, and maintaining security"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Analytics & improvement"}),o("td",{className:"py-3 pr-4",children:"Consent"}),o("td",{className:"py-3",children:"Understanding how users interact with our site to improve our services (gated behind consent in EU/EEA)"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Responding to enquiries"}),o("td",{className:"py-3 pr-4",children:"Legitimate interest / Contract"}),o("td",{className:"py-3",children:"Responding to your questions, processing waitlist requests, or pre-contractual discussions"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Service delivery"}),o("td",{className:"py-3 pr-4",children:"Contract"}),o("td",{className:"py-3",children:"If/when you become a customer, processing your data is necessary to fulfil our contractual obligations"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Legal compliance"}),o("td",{className:"py-3 pr-4",children:"Legal obligation"}),o("td",{className:"py-3",children:"Complying with applicable laws, regulations, or legal processes"})]})]})]})})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"5. Cookies & Tracking"}),d("p",{className:"text-muted-foreground",children:["We use ",o("strong",{className:"text-foreground",children:"PostHog"})," for product analytics to understand how visitors use our website. PostHog may use cookies or similar technologies to collect this information."]}),o("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"Consent in the EU/EEA"}),o("p",{className:"text-muted-foreground",children:"If you are located in the European Union or European Economic Area, we gate analytics tracking behind your explicit consent. Analytics cookies will not be set until you opt-in through our cookie consent mechanism."}),o("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"Withdrawing Consent / Opting Out"}),o("p",{className:"text-muted-foreground",children:"You can withdraw consent or opt out at any time:"}),d("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[d("li",{children:[o("strong",{children:"Cookie settings:"})," Use the cookie preferences link in our website footer to manage your consent"]}),d("li",{children:[o("strong",{children:"Browser settings:"})," Configure your browser to reject cookies or alert you when cookies are being set"]}),d("li",{children:[o("strong",{children:"PostHog opt-out:"}),' PostHog respects "Do Not Track" browser signals where applicable']})]}),o("p",{className:"text-muted-foreground",children:"Note: Rejecting analytics cookies will not affect your ability to use our website."})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"6. Sub-processors & Recipients"}),o("p",{className:"text-muted-foreground",children:"We share data with the following third-party service providers who process data on our behalf:"}),o("div",{className:"overflow-x-auto",children:d("table",{className:"w-full border-collapse text-muted-foreground text-sm",children:[o("thead",{children:d("tr",{className:"border-white/20 border-b",children:[o("th",{className:"py-3 pr-4 text-left font-semibold text-foreground",children:"Provider"}),o("th",{className:"py-3 pr-4 text-left font-semibold text-foreground",children:"Purpose"}),o("th",{className:"py-3 text-left font-semibold text-foreground",children:"Location"})]})}),d("tbody",{children:[d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"PostHog"}),o("td",{className:"py-3 pr-4",children:"Product analytics"}),o("td",{className:"py-3",children:"EU (PostHog Cloud EU) or US"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Vercel"}),o("td",{className:"py-3 pr-4",children:"Website hosting & CDN"}),o("td",{className:"py-3",children:"Global (including EU regions)"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Scaleway"}),o("td",{className:"py-3 pr-4",children:"Cloud infrastructure"}),o("td",{className:"py-3",children:"France / EU"})]}),d("tr",{className:"border-white/10 border-b",children:[d("td",{className:"py-3 pr-4 font-medium",children:["Email provider ",o("em",{children:"(TBD)"})]}),o("td",{className:"py-3 pr-4",children:"Transactional & marketing emails"}),o("td",{className:"py-3",children:o("em",{children:"To be confirmed"})})]}),d("tr",{className:"border-white/10 border-b",children:[d("td",{className:"py-3 pr-4 font-medium",children:["Error tracking ",o("em",{children:"(TBD)"})]}),o("td",{className:"py-3 pr-4",children:"Application error monitoring"}),o("td",{className:"py-3",children:o("em",{children:"To be confirmed"})})]}),d("tr",{className:"border-white/10 border-b",children:[d("td",{className:"py-3 pr-4 font-medium",children:["Payment processor ",o("em",{children:"(TBD)"})]}),o("td",{className:"py-3 pr-4",children:"Billing & subscription management"}),o("td",{className:"py-3",children:o("em",{children:"To be confirmed"})})]})]})]})}),o("p",{className:"mt-4 text-muted-foreground",children:"We carefully select our sub-processors and require them to maintain appropriate security measures and only process data according to our instructions."})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"7. International Data Transfers"}),o("p",{className:"text-muted-foreground",children:"As a France-based company, we aim to keep your data within the European Union wherever possible."}),o("p",{className:"text-muted-foreground",children:"However, some of our service providers may process data outside the EU/EEA. When this occurs, we ensure appropriate safeguards are in place, such as:"}),d("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[d("li",{children:[o("strong",{children:"Standard Contractual Clauses (SCCs)"})," approved by the European Commission"]}),d("li",{children:[o("strong",{children:"Adequacy decisions"})," where the recipient country has been deemed to provide adequate protection"]}),d("li",{children:[o("strong",{children:"Binding Corporate Rules"})," where applicable"]})]}),d("p",{className:"text-muted-foreground",children:["You may request more information about these safeguards by contacting us at"," ",o("a",{href:"mailto:privacy@contractspec.io",className:"text-primary hover:underline",children:"privacy@contractspec.io"}),"."]})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"8. Data Retention"}),o("p",{className:"text-muted-foreground",children:"We retain your personal data only for as long as necessary to fulfil the purposes for which it was collected:"}),o("div",{className:"overflow-x-auto",children:d("table",{className:"w-full border-collapse text-muted-foreground text-sm",children:[o("thead",{children:d("tr",{className:"border-white/20 border-b",children:[o("th",{className:"py-3 pr-4 text-left font-semibold text-foreground",children:"Data Type"}),o("th",{className:"py-3 text-left font-semibold text-foreground",children:"Retention Period"})]})}),d("tbody",{children:[d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Analytics data"}),o("td",{className:"py-3",children:"24 months from collection"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Waitlist / contact form data"}),o("td",{className:"py-3",children:"Until you request deletion or 24 months after last interaction"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Account data (when applicable)"}),o("td",{className:"py-3",children:"Duration of account plus 12 months after closure"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Billing records (when applicable)"}),o("td",{className:"py-3",children:"10 years (French legal requirement)"})]})]})]})}),o("p",{className:"mt-4 text-muted-foreground",children:"We may retain certain data longer if required by law or to establish, exercise, or defend legal claims."})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"9. Your Rights Under GDPR"}),o("p",{className:"text-muted-foreground",children:"As a data subject in the EU, you have the following rights:"}),d("ul",{className:"list-disc space-y-3 pl-6 text-muted-foreground",children:[d("li",{children:[o("strong",{className:"text-foreground",children:"Right to access"})," — Request a copy of the personal data we hold about you"]}),d("li",{children:[o("strong",{className:"text-foreground",children:"Right to rectification"})," ","— Request correction of inaccurate or incomplete data"]}),d("li",{children:[o("strong",{className:"text-foreground",children:'Right to erasure ("right to be forgotten")'})," ","— Request deletion of your personal data in certain circumstances"]}),d("li",{children:[o("strong",{className:"text-foreground",children:"Right to restriction"})," ","— Request that we limit how we use your data"]}),d("li",{children:[o("strong",{className:"text-foreground",children:"Right to data portability"})," ","— Receive your data in a structured, machine-readable format"]}),d("li",{children:[o("strong",{className:"text-foreground",children:"Right to object"})," — Object to processing based on legitimate interests or direct marketing"]}),d("li",{children:[o("strong",{className:"text-foreground",children:"Right to withdraw consent"})," ","— Where processing is based on consent, withdraw it at any time"]})]}),d("p",{className:"mt-4 text-muted-foreground",children:["To exercise any of these rights, please contact us at"," ",o("a",{href:"mailto:privacy@contractspec.io",className:"text-primary hover:underline",children:"privacy@contractspec.io"}),". We will respond within one month as required by GDPR."]})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"10. Security"}),o("p",{className:"text-muted-foreground",children:"We implement appropriate technical and organisational measures to protect your personal data against unauthorised access, alteration, disclosure, or destruction. These measures include:"}),d("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[o("li",{children:"Encryption of data in transit (TLS/HTTPS)"}),o("li",{children:"Encryption of data at rest where appropriate"}),o("li",{children:"Access controls and authentication"}),o("li",{children:"Regular security reviews and updates"}),o("li",{children:"Careful vetting of sub-processors"})]}),o("p",{className:"text-muted-foreground",children:"While we strive to protect your data, no method of transmission over the Internet or electronic storage is 100% secure. We cannot guarantee absolute security but are committed to continuous improvement."})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"11. Contact & Complaints"}),o("p",{className:"text-muted-foreground",children:"If you have any questions, concerns, or requests regarding this privacy policy or our data practices, please contact us:"}),d("div",{className:"rounded-lg border border-white/10 bg-white/5 p-4 text-muted-foreground",children:[d("p",{children:[o("strong",{className:"text-foreground",children:"Email:"})," ",o("a",{href:"mailto:privacy@contractspec.io",className:"text-primary hover:underline",children:"privacy@contractspec.io"})]}),d("p",{className:"mt-2",children:[o("strong",{className:"text-foreground",children:"Address:"})," CHAMAN VENTURES, 229 rue Saint-Honoré, 75001 Paris, France"]})]}),o("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"Supervisory Authority"}),o("p",{className:"text-muted-foreground",children:"If you are not satisfied with our response or believe we are processing your data unlawfully, you have the right to lodge a complaint with a supervisory authority. In France, the relevant authority is:"}),d("div",{className:"rounded-lg border border-white/10 bg-white/5 p-4 text-muted-foreground",children:[o("p",{children:o("strong",{className:"text-foreground",children:"Commission Nationale de l'Informatique et des Libertés (CNIL)"})}),o("p",{children:"3 Place de Fontenoy, TSA 80715, 75334 Paris Cedex 07"}),d("p",{children:["Website:"," ",o("a",{href:"https://www.cnil.fr",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:"www.cnil.fr"})]})]})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"12. Changes to This Policy"}),o("p",{className:"text-muted-foreground",children:'We may update this privacy policy from time to time to reflect changes in our practices, technology, legal requirements, or for other operational reasons. We will notify you of any material changes by updating the "Last updated" date at the top of this page.'}),o("p",{className:"text-muted-foreground",children:"We encourage you to review this policy periodically to stay informed about how we protect your data."})]}),o("div",{className:"mt-12 border-white/10 border-t pt-8",children:d("p",{className:"text-muted-foreground text-sm",children:["For questions about this privacy policy, please contact us at"," ",o("a",{href:"mailto:privacy@contractspec.io",className:"text-primary hover:underline",children:"privacy@contractspec.io"})]})})]})})})}import{jsx as i,jsxs as p}from"react/jsx-runtime";var dD={title:"Terms of Service | ContractSpec",description:"Terms of Service for ContractSpec. Read our terms governing use of the ContractSpec website and services."};function Kb(){return i("main",{className:"flex grow flex-col items-center justify-center pt-24",children:i("section",{className:"section-padding",children:p("div",{className:"prose prose-invert mx-auto max-w-3xl",children:[i("h1",{className:"mb-4 font-bold text-4xl",children:"Terms of Service"}),i("p",{className:"mb-8 text-muted-foreground",children:"Last updated: December 18, 2025"}),p("section",{className:"space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"1. Definitions"}),i("p",{className:"text-muted-foreground",children:'In these Terms of Service ("Terms"), the following definitions apply:'}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[p("li",{children:[i("strong",{className:"text-foreground",children:'"ContractSpec"'}),","," ",i("strong",{className:"text-foreground",children:'"we"'}),","," ",i("strong",{className:"text-foreground",children:'"us"'}),", or"," ",i("strong",{className:"text-foreground",children:'"our"'})," refers to CHAMAN VENTURES, SASU, operating under the ContractSpec brand."]}),p("li",{children:[i("strong",{className:"text-foreground",children:'"Service"'})," or"," ",i("strong",{className:"text-foreground",children:'"Services"'})," refers to the ContractSpec website, ContractSpec Studio, APIs, documentation, and any related products or features we provide."]}),p("li",{children:[i("strong",{className:"text-foreground",children:'"User"'}),","," ",i("strong",{className:"text-foreground",children:'"you"'}),", or"," ",i("strong",{className:"text-foreground",children:'"your"'})," refers to any individual or entity accessing or using the Services."]}),p("li",{children:[i("strong",{className:"text-foreground",children:'"User Content"'})," ","refers to any data, specifications, configurations, or other materials you create, upload, or submit through the Services."]}),p("li",{children:[i("strong",{className:"text-foreground",children:'"ContractSpec Core"'})," ","refers to the open-source components of ContractSpec available under their respective open-source licenses."]}),p("li",{children:[i("strong",{className:"text-foreground",children:'"Design Partner"'})," ","refers to early users who have entered into a separate design partnership arrangement with us."]})]})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"2. Who We Are"}),p("p",{className:"text-muted-foreground",children:["ContractSpec is a brand of"," ",i("strong",{className:"text-foreground",children:"CHAMAN VENTURES"}),", a simplified joint-stock company (SASU) registered in France."]}),i("div",{className:"rounded-lg border border-white/10 bg-white/5 p-4 text-muted-foreground",children:p("ul",{className:"list-none space-y-1 pl-0",children:[i("li",{children:"CHAMAN VENTURES, SASU"}),i("li",{children:"RCS Paris • SIREN 989 498 902"}),i("li",{children:"229 rue Saint-Honoré, 75001 Paris, France"}),p("li",{children:["Contact:"," ",i("a",{href:"mailto:legal@contractspec.io",className:"text-primary hover:underline",children:"legal@contractspec.io"})]})]})})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"3. Acceptance of Terms"}),p("p",{className:"text-muted-foreground",children:["By accessing or using ContractSpec, you agree to be bound by these Terms and our"," ",i("a",{href:"/legal/privacy",className:"text-primary hover:underline",children:"Privacy Policy"}),". If you do not agree to these Terms, you must not use the Services."]}),i("p",{className:"text-muted-foreground",children:'We may update these Terms from time to time. We will notify you of material changes by updating the "Last updated" date. Continued use of the Services after changes constitutes acceptance of the updated Terms.'})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"4. Eligibility"}),i("p",{className:"text-muted-foreground",children:"To use the Services, you must:"}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[i("li",{children:"Be at least 18 years old or the age of majority in your jurisdiction"}),i("li",{children:"Have the legal capacity to enter into binding contracts"}),i("li",{children:"Not be prohibited from using the Services under applicable laws"}),i("li",{children:"If acting on behalf of an organisation, have the authority to bind that organisation to these Terms"})]})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"5. Accounts"}),p("div",{className:"rounded-lg border border-yellow-500/20 bg-yellow-500/5 p-4 text-muted-foreground",children:[i("p",{className:"mb-2 font-medium text-yellow-500",children:"Note"}),i("p",{children:"User accounts are not yet available. When accounts are introduced, the following terms will apply:"})]}),p("ul",{className:"mt-4 list-disc space-y-2 pl-6 text-muted-foreground",children:[i("li",{children:"You are responsible for maintaining the confidentiality of your account credentials"}),i("li",{children:"You are responsible for all activities that occur under your account"}),i("li",{children:"You must notify us immediately of any unauthorised use of your account"}),i("li",{children:"We reserve the right to suspend or terminate accounts that violate these Terms"})]})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"6. License & Intellectual Property"}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"6.1 Our Intellectual Property"}),i("p",{className:"text-muted-foreground",children:"The ContractSpec name, logo, website design, proprietary software, documentation, and all associated intellectual property rights are owned by CHAMAN VENTURES. Subject to these Terms, we grant you a limited, non-exclusive, non-transferable, revocable license to access and use the Services for their intended purpose."}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"6.2 Open-Source Components"}),i("p",{className:"text-muted-foreground",children:'Certain components of ContractSpec ("ContractSpec Core") are made available as open-source software under their respective licenses (e.g., MIT, Apache 2.0). Your use of open-source components is governed by those licenses, which may grant you additional rights not covered by these Terms. In case of conflict between these Terms and an open-source license, the open-source license prevails for the applicable component.'}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"6.3 Your Content"}),p("p",{className:"text-muted-foreground",children:[i("strong",{className:"text-foreground",children:"You retain ownership"})," ","of all User Content you create, upload, or submit through the Services. This includes your specifications, configurations, and any other materials you generate."]}),i("p",{className:"text-muted-foreground",children:"By using the Services, you grant us a limited, non-exclusive, worldwide, royalty-free license to host, store, process, and display your User Content solely to the extent necessary to provide and improve the Services. This license terminates when you delete your User Content or close your account, except where retention is required by law or for legitimate business purposes (e.g., backups, legal compliance)."}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"6.4 Feedback"}),i("p",{className:"text-muted-foreground",children:"If you provide feedback, suggestions, or ideas about the Services, you grant us a perpetual, irrevocable, royalty-free license to use, modify, and incorporate such feedback without obligation to you."})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"7. Acceptable Use"}),i("p",{className:"text-muted-foreground",children:"When using the Services, you agree not to:"}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[p("li",{children:[i("strong",{className:"text-foreground",children:"Abuse the Services:"})," ","Use the Services in a manner that disrupts, damages, or impairs our infrastructure or other users' experience"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Probe security:"})," ","Attempt to gain unauthorised access to our systems, networks, or data; perform security testing without prior written permission"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Distribute harmful content:"})," ","Upload, share, or distribute malware, viruses, or other malicious code"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Engage in illegal activity:"})," ","Use the Services for any purpose that is unlawful, fraudulent, or harmful"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Interfere with operations:"})," ","Attempt to interfere with, disrupt, or circumvent any security or access controls"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Violate rights:"})," ","Infringe upon the intellectual property, privacy, or other rights of third parties"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Misrepresent identity:"})," ","Impersonate any person or entity, or falsely claim affiliation with ContractSpec"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Circumvent limits:"})," ","Attempt to bypass any usage limits, rate limits, or access restrictions"]})]}),i("p",{className:"mt-4 text-muted-foreground",children:"We reserve the right to investigate violations and take appropriate action, including suspension or termination of access."})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"8. Beta & Preview Services"}),p("div",{className:"rounded-lg border border-orange-500/20 bg-orange-500/5 p-4 text-muted-foreground",children:[i("p",{className:"mb-2 font-medium text-orange-400",children:"⚠️ Important"}),i("p",{children:'ContractSpec is currently in active development. Some features may be labelled as "Beta", "Preview", "Alpha", or similar designations.'})]}),i("p",{className:"mt-4 text-muted-foreground",children:"By using beta or preview features, you acknowledge:"}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[p("li",{children:[i("strong",{className:"text-foreground",children:"Things may break:"})," ","Beta features may contain bugs, errors, or unexpected behaviour"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"No availability guarantee:"})," ","We do not guarantee uptime, availability, or continuity of beta features"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Features may change or disappear:"})," ","We may modify, suspend, or discontinue beta features at any time without notice"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Not for production:"})," ","Beta features should not be relied upon for mission-critical or production workloads unless you accept these risks"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Data may be lost:"})," ","We cannot guarantee the preservation of data created using beta features"]})]})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"9. Design Partner Program"}),i("p",{className:"text-muted-foreground",children:"We offer a Design Partner program for early users who wish to collaborate closely with us to shape the product. If you participate as a Design Partner:"}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"9.1 Scope"}),i("p",{className:"text-muted-foreground",children:"Design Partners receive early access to features, provide feedback, and help validate product direction. The specific scope of your participation will be outlined in a separate agreement or communication."}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"9.2 Feedback"}),i("p",{className:"text-muted-foreground",children:"We value your input. Feedback you provide may be used to improve the Services. See Section 6.4 for licensing terms regarding feedback."}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"9.3 Confidentiality"}),i("p",{className:"text-muted-foreground",children:"Design Partners may receive access to confidential or pre-release information. Unless otherwise specified in a separate agreement, you agree to keep such information confidential and not share it publicly without our prior written consent."}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"9.4 Mutual Expectations"}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[p("li",{children:[i("strong",{className:"text-foreground",children:"From us:"})," Regular communications, responsiveness to feedback, and transparency about product direction"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"From you:"})," Timely and honest feedback, reasonable engagement, and adherence to these Terms"]})]})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"10. Fees & Billing"}),p("div",{className:"rounded-lg border border-yellow-500/20 bg-yellow-500/5 p-4 text-muted-foreground",children:[i("p",{className:"mb-2 font-medium text-yellow-500",children:"Note"}),i("p",{children:"Paid plans are not yet available. When paid plans are introduced, the following terms will apply:"})]}),p("ul",{className:"mt-4 list-disc space-y-2 pl-6 text-muted-foreground",children:[i("li",{children:"Fees will be clearly communicated before you commit to a paid plan"}),i("li",{children:"Payment terms, billing cycles, and refund policies will be specified at that time"}),i("li",{children:"We reserve the right to change pricing with reasonable notice"}),i("li",{children:"Failure to pay may result in suspension or termination of paid features"})]})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"11. Third-Party Services"}),i("p",{className:"text-muted-foreground",children:"The Services may integrate with or contain links to third-party services, websites, or content. We do not control and are not responsible for third-party services."}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[i("li",{children:"Your use of third-party services is governed by their respective terms and policies"}),i("li",{children:"We make no warranties or representations about third-party services"}),i("li",{children:"Links to third-party sites do not imply endorsement"}),i("li",{children:"You are responsible for reviewing the terms of any third-party services you use"})]})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"12. Disclaimer of Warranties"}),i("div",{className:"rounded-lg border border-white/10 bg-white/5 p-4 text-muted-foreground",children:i("p",{className:"font-medium uppercase",children:'THE SERVICES ARE PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED.'})}),i("p",{className:"mt-4 text-muted-foreground",children:"To the fullest extent permitted by law, we disclaim:"}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[i("li",{children:"Warranties of merchantability, fitness for a particular purpose, and non-infringement"}),i("li",{children:"Any warranty that the Services will be uninterrupted, secure, or error-free"}),i("li",{children:"Any warranty regarding the accuracy, reliability, or completeness of content"}),i("li",{children:"Any warranty that defects will be corrected or that the Services are free of viruses or harmful components"})]}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"No Professional Advice"}),i("p",{className:"text-muted-foreground",children:"The Services are tools for software development. Nothing in the Services constitutes legal, financial, technical, or other professional advice. You are solely responsible for evaluating the suitability of the Services for your needs and for any decisions you make based on the output."})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"13. Limitation of Liability"}),i("p",{className:"text-muted-foreground",children:"To the maximum extent permitted by applicable law:"}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[p("li",{children:[i("strong",{className:"text-foreground",children:"No indirect damages:"})," ","We shall not be liable for any indirect, incidental, special, consequential, or punitive damages, including loss of profits, data, goodwill, or other intangible losses"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Limited direct liability:"})," ","Our total aggregate liability for any claims arising from or related to the Services shall not exceed the greater of: (a) the amount you paid us in the 12 months preceding the claim, or (b) €100"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Exceptions:"})," These limitations do not apply to liability that cannot be excluded under applicable law, including liability for fraud or wilful misconduct"]})]}),i("p",{className:"mt-4 text-muted-foreground",children:"You acknowledge that these limitations reflect a reasonable allocation of risk and are a fundamental basis of the agreement between us."})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"14. Termination"}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"14.1 By You"}),i("p",{className:"text-muted-foreground",children:"You may stop using the Services at any time. When accounts are available, you may close your account through the account settings or by contacting us."}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"14.2 By Us"}),i("p",{className:"text-muted-foreground",children:"We may suspend or terminate your access to the Services at any time, with or without cause, with or without notice. Reasons for termination may include:"}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[i("li",{children:"Violation of these Terms"}),i("li",{children:"Conduct that we believe is harmful to other users or our business"}),i("li",{children:"Extended inactivity"}),i("li",{children:"Discontinuation of the Services"})]}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"14.3 Effect of Termination"}),i("p",{className:"text-muted-foreground",children:"Upon termination, your right to use the Services ceases immediately. Provisions that by their nature should survive termination will survive, including intellectual property rights, disclaimers, limitations of liability, and dispute resolution."})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"15. Governing Law & Jurisdiction"}),p("p",{className:"text-muted-foreground",children:["These Terms are governed by and construed in accordance with the laws of ",i("strong",{className:"text-foreground",children:"France"}),", without regard to conflict of law principles."]}),p("p",{className:"text-muted-foreground",children:["Any disputes arising from or related to these Terms or the Services shall be subject to the exclusive jurisdiction of the courts of"," ",i("strong",{className:"text-foreground",children:"Paris, France"}),"."]}),i("p",{className:"text-muted-foreground",children:"If you are a consumer in the European Union, nothing in these Terms affects your rights under mandatory consumer protection laws of your country of residence."})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"16. Contact"}),i("p",{className:"text-muted-foreground",children:"If you have any questions about these Terms, please contact us:"}),p("div",{className:"rounded-lg border border-white/10 bg-white/5 p-4 text-muted-foreground",children:[p("p",{children:[i("strong",{className:"text-foreground",children:"Email:"})," ",i("a",{href:"mailto:legal@contractspec.io",className:"text-primary hover:underline",children:"legal@contractspec.io"})]}),p("p",{className:"mt-2",children:[i("strong",{className:"text-foreground",children:"Address:"})," CHAMAN VENTURES, 229 rue Saint-Honoré, 75001 Paris, France"]})]})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"17. Miscellaneous"}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[p("li",{children:[i("strong",{className:"text-foreground",children:"Entire Agreement:"})," ","These Terms, together with our Privacy Policy and any additional agreements, constitute the entire agreement between you and ContractSpec regarding the Services"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Severability:"})," If any provision of these Terms is found unenforceable, the remaining provisions will continue in effect"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Waiver:"})," Our failure to enforce any right or provision does not constitute a waiver of that right or provision"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Assignment:"})," You may not assign or transfer your rights under these Terms without our consent. We may assign our rights freely"]})]})]}),i("div",{className:"mt-12 border-white/10 border-t pt-8",children:p("p",{className:"text-muted-foreground text-sm",children:["For questions about these terms, please contact us at"," ",i("a",{href:"mailto:legal@contractspec.io",className:"text-primary hover:underline",children:"legal@contractspec.io"})]})})]})})})}import{Lock as Qb}from"lucide-react";import{jsx as ar,jsxs as Yb}from"react/jsx-runtime";function hD({title:e,description:t,actionLabel:a,onAction:r}){return Yb("div",{className:"text-center",children:[ar("div",{className:"mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-muted/40",children:ar(Qb,{className:"h-5 w-5 text-muted-foreground"})}),ar("h3",{className:"mt-4 font-semibold text-lg",children:e}),ar("p",{className:"mt-2 text-muted-foreground text-sm",children:t}),a?ar("button",{type:"button",className:"btn-primary mt-4 inline-flex items-center justify-center",onClick:r,children:a}):null]})}import{Select as Jb,SelectContent as Zb,SelectItem as $b,SelectTrigger as Xb,SelectValue as xb}from"@contractspec/lib.ui-kit-web/ui/select";import*as Zd from"react";import{jsx as xa,jsxs as Mi}from"react/jsx-runtime";function Er({title:e,subtitle:t,workspaceSelect:a,projectSelect:r,environmentSelect:l,stickyHeaderOffsetPx:b,headerRight:h}){return xa("div",{className:"sticky top-0 z-10 border-border border-b bg-card",style:{top:b??0},children:Mi("div",{className:"mx-auto flex w-full max-w-7xl flex-col gap-3 px-4 py-3 md:flex-row md:items-center md:justify-between",children:[Mi("div",{className:"min-w-0",children:[Mi("div",{className:"flex items-center gap-2",children:[xa("p",{className:"truncate font-semibold text-base",children:e}),t?xa("p",{className:"hidden text-muted-foreground text-sm md:block",children:t}):null]}),Mi("div",{className:"mt-2 flex flex-wrap gap-2",children:[a?xa(Mn,{select:a}):null,r?xa(Mn,{select:r}):null,l?xa(Mn,{select:l}):null]})]}),xa("div",{className:"flex items-center justify-between gap-2 md:justify-end",children:h})]})})}function Mn({select:e}){let t=Zd.useId();return Mi("div",{className:"flex min-w-[220px] flex-col gap-1",children:[xa("span",{id:t,className:"text-muted-foreground text-xs",children:e.label}),Mi(Jb,{value:e.value,onValueChange:e.onChange,children:[xa(Xb,{"aria-labelledby":t,className:"w-full",children:xa(xb,{placeholder:e.placeholder??e.label})}),xa(Zb,{children:e.options.map((a)=>xa($b,{value:a.value,children:a.label},a.value))})]})]})}import{Sidebar as jb,SidebarContent as ev,SidebarFooter as tv,SidebarHeader as av,SidebarMenu as ov,SidebarMenuButton as $d,SidebarMenuItem as Xd,SidebarRail as iv}from"@contractspec/lib.ui-kit-web/ui/sidebar";import{Settings as rv}from"lucide-react";import{jsx as Io,jsxs as Or}from"react/jsx-runtime";function Br({modules:e,activeModuleId:t,onModuleChange:a,sidebarFooter:r}){return Or(jb,{children:[Io(iv,{}),Io(av,{}),Io(ev,{children:Or(ov,{children:[e.map((l)=>Io(Xd,{children:Or($d,{isActive:l.id===t,onClick:()=>a(l.id),children:[l.icon,Io("span",{children:l.label}),l.badge!=null?Io("span",{className:"ml-auto text-muted-foreground text-xs",children:String(l.badge)}):null]})},l.id)),Io(Xd,{children:Or($d,{isActive:t==="settings",onClick:()=>a("settings"),children:[Io(rv,{className:"size-4"}),Io("span",{children:"Settings"})]})})]})}),Io(tv,{children:r})]})}import{SidebarInset as nv,SidebarProvider as cv}from"@contractspec/lib.ui-kit-web/ui/sidebar";import{cn as lv}from"@contractspec/lib.ui-kit-web/ui/utils";import{jsx as Mr,jsxs as xd}from"react/jsx-runtime";function ED({title:e,subtitle:t,workspaceSelect:a,projectSelect:r,environmentSelect:l,stickyHeaderOffsetPx:b,headerRight:h,modules:v,activeModuleId:V,onModuleChange:g,sidebarFooter:tt,assistant:va,children:ye,className:Ke}){return xd(cv,{children:[Mr(Br,{modules:v,activeModuleId:V,onModuleChange:g,sidebarFooter:tt}),Mr(nv,{children:xd("div",{className:lv("min-h-svh bg-background",Ke),children:[Mr(Er,{title:e,subtitle:t,workspaceSelect:a,projectSelect:r,environmentSelect:l,stickyHeaderOffsetPx:b,headerRight:h}),Mr("main",{className:"m-4",children:ye})]})}),va]})}import{BundleProvider as dv,BundleRenderer as sv}from"@contractspec/lib.surface-runtime/react";import{SidebarProvider as pv}from"@contractspec/lib.ui-kit-web/ui/sidebar";import{jsx as bi}from"react/jsx-runtime";function zD({plan:e,title:t,subtitle:a,workspaceSelect:r,projectSelect:l,environmentSelect:b,stickyHeaderOffsetPx:h,headerRight:v,modules:V,activeModuleId:g,onModuleChange:tt,sidebarFooter:va,assistant:ye,children:Ke,className:Gi}){let Qe={header:bi(Er,{title:t,subtitle:a,workspaceSelect:r,projectSelect:l,environmentSelect:b,stickyHeaderOffsetPx:h,headerRight:v}),sidebar:bi(Br,{modules:V,activeModuleId:g,onModuleChange:tt,sidebarFooter:va}),primary:bi("main",{className:Gi?`m-4 ${Gi}`:"m-4",children:Ke})};if(ye!=null)Qe.assistant=ye;return bi(pv,{children:bi(dv,{plan:e,children:bi("div",{className:"min-h-svh bg-background",children:bi(sv,{slotContent:Qe})})})})}import{gql as mv}from"@apollo/client";import{useQuery as uv}from"@apollo/client/react";import{useTemplateRuntime as gv}from"@contractspec/lib.example-shared-ui";import{MessageCircle as fv,Users as hv}from"lucide-react";import{useMemo as yv}from"react";import{jsx as vi,jsxs as Ui}from"react/jsx-runtime";var bv=mv`
|
|
4799
|
+
}`}),V=(g)=>{let tt=g.target,{name:va,value:ye}=tt;v((Ke)=>({...Ke,[va]:ye}))};return et("div",{className:"space-y-4 rounded-2xl border border-border bg-card p-4",children:[et("header",{className:"flex flex-wrap items-center justify-between gap-3",children:[et("div",{children:[et("p",{className:"font-semibold text-sm uppercase tracking-wide",children:[e," credentials"]}),Se("p",{className:"text-muted-foreground text-sm",children:"Store encrypted keys with BYOK and run safe connection tests."})]}),Se(Fb,{className:"h-5 w-5 text-muted-foreground"})]}),Se("div",{className:"grid gap-4 md:grid-cols-2",children:et("div",{className:"space-y-2",children:[Se(Bi,{htmlFor:"ownershipMode",children:"Ownership"}),et(Yd,{value:h.ownershipMode??"managed",onValueChange:(g)=>v((tt)=>({...tt,ownershipMode:g})),children:[Se(Zd,{id:"ownershipMode",className:"w-full",children:Se($d,{})}),et(Jd,{children:[Se(Dr,{value:"managed",children:"Managed (store encrypted)"}),Se(Dr,{value:"byok",children:"BYOK (store secret reference)"})]})]})]})}),et("div",{className:"grid gap-4 md:grid-cols-2",children:[et("div",{className:"space-y-1 text-sm",children:[Se(Bi,{htmlFor:"apiKey",className:"font-semibold",children:"API key"}),et("div",{className:"relative",children:[Se(Vb,{className:"pointer-events-none absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),Se(Un,{type:"text",name:"apiKey",id:"apiKey",className:"w-full py-2 pr-3 pl-9",value:h.apiKey,onChange:V,required:!0})]})]}),et("div",{className:"space-y-1 text-sm",children:[Se(Bi,{htmlFor:"secret",className:"font-semibold",children:"Secret"}),Se(Un,{type:"password",id:"secret",name:"secret",className:"w-full px-3 py-2",value:h.secret,onChange:V})]})]}),h.ownershipMode==="byok"?et("div",{className:"space-y-4 rounded-xl border border-blue-500/20 bg-blue-500/5 p-4",children:[Se("p",{className:"font-semibold text-sm",children:"BYOK secret reference"}),et("div",{className:"grid gap-4 md:grid-cols-2",children:[et("div",{className:"space-y-2",children:[Se(Bi,{htmlFor:"secretProvider",children:"Secret provider"}),et(Yd,{value:h.secretProvider??"env",onValueChange:(g)=>v((tt)=>({...tt,secretProvider:g})),children:[Se(Zd,{id:"secretProvider",className:"w-full",children:Se($d,{})}),et(Jd,{children:[Se(Dr,{value:"env",children:"Environment"}),Se(Dr,{value:"gcp",children:"GCP Secret Manager"})]})]})]}),et("div",{className:"space-y-2",children:[Se(Bi,{htmlFor:"secretRef",children:"Secret reference"}),Se(Un,{id:"secretRef",name:"secretRef",placeholder:h.secretProvider==="gcp"?"gcp://projects/.../secrets/...":"env://MY_TOKEN_ENV_VAR",value:h.secretRef??"",onChange:V})]})]})]}):et("div",{className:"flex items-center gap-3 rounded-xl border border-emerald-500/20 bg-emerald-500/5 p-4 text-sm",children:[Se(Hb,{checked:!0,onCheckedChange:()=>{},"aria-label":"Managed"}),et("div",{children:[Se("p",{className:"font-semibold",children:"Managed encryption enabled"}),Se("p",{className:"text-muted-foreground",children:"Secrets are encrypted server-side for this tenant."})]})]}),et("div",{className:"space-y-1 text-sm",children:[Se(Bi,{htmlFor:"config",className:"font-semibold",children:"Configuration (JSON)"}),Se(qb,{id:"config",name:"config",className:"min-h-[140px] w-full font-mono text-sm",value:h.config,onChange:V})]}),et("div",{className:"flex flex-wrap items-center gap-3",children:[et(Qd,{variant:"ghost",onPress:()=>a?.(h),disabled:b,children:[Se(Kb,{className:"h-4 w-4"}),"Test connection"]}),Se(Qd,{variant:"default",onPress:()=>r?.(h),disabled:l,children:"Save settings"})]})]})}import{BookCopy as Qb,Plus as Yb,RefreshCcw as Jb}from"lucide-react";import{jsx as so,jsxs as qo}from"react/jsx-runtime";function iD({sources:e,onRefresh:t,onDelete:a,onAdd:r}){return qo("div",{className:"space-y-4 rounded-2xl border border-border bg-card p-4",children:[qo("header",{className:"flex flex-wrap items-center justify-between gap-3",children:[qo("div",{children:[so("p",{className:"font-semibold text-sm uppercase tracking-wide",children:"Knowledge sources"}),so("p",{className:"text-muted-foreground text-sm",children:"Manage documentation, specs, and repos powering Studio RAG flows."})]}),qo("button",{type:"button",className:"btn-primary inline-flex items-center gap-2",onClick:r,children:[so(Yb,{className:"h-4 w-4"}),"Add source"]})]}),so("div",{className:"space-y-3",children:e.length?e.map((l)=>qo("div",{className:"flex flex-wrap items-center justify-between gap-3 rounded-xl border border-border bg-background p-4",children:[qo("div",{className:"flex items-center gap-3",children:[so(Qb,{className:"h-8 w-8 text-muted-foreground"}),qo("div",{children:[so("p",{className:"font-semibold text-base",children:l.name}),so("p",{className:"text-muted-foreground text-sm",children:l.type}),so("p",{className:"text-muted-foreground text-xs",children:l.indexed?`Indexed ${l.lastIndexed?new Date(l.lastIndexed).toLocaleString():""}`:"Pending indexing"})]})]}),qo("div",{className:"flex items-center gap-2",children:[qo("button",{type:"button",className:"btn-ghost inline-flex items-center gap-1 text-sm",onClick:()=>t?.(l.id),children:[so(Jb,{className:"h-3.5 w-3.5"}),"Reindex"]}),so("button",{type:"button",className:"btn-ghost text-destructive text-sm",onClick:()=>a?.(l.id),children:"Remove"})]})]},l.id)):so("div",{className:"rounded-xl border border-border border-dashed p-6 text-center text-muted-foreground text-sm",children:"No knowledge sources added yet."})})]})}import{jsx as o,jsxs as d}from"react/jsx-runtime";var mD={title:"Privacy Policy | ContractSpec",description:"Learn how ContractSpec collects, uses, and protects your personal data in compliance with GDPR."};function Zb(){return o("main",{className:"flex grow flex-col items-center justify-center pt-24",children:o("section",{className:"section-padding",children:d("div",{className:"prose prose-invert mx-auto max-w-3xl",children:[o("h1",{className:"mb-4 font-bold text-4xl",children:"Privacy Policy"}),o("p",{className:"mb-8 text-muted-foreground",children:"Last updated: December 18, 2025"}),d("section",{className:"space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"1. Who We Are"}),d("p",{className:"text-muted-foreground",children:[o("strong",{className:"text-foreground",children:"ContractSpec"})," is a brand of"," ",o("strong",{className:"text-foreground",children:"CHAMAN VENTURES"}),", a simplified joint-stock company (SASU) registered in France."]}),d("div",{className:"rounded-lg border border-white/10 bg-white/5 p-4 text-muted-foreground",children:[o("p",{className:"mb-2",children:o("strong",{className:"text-foreground",children:"Data Controller:"})}),d("ul",{className:"list-none space-y-1 pl-0",children:[o("li",{children:"CHAMAN VENTURES, SASU"}),o("li",{children:"RCS Paris • SIREN 989 498 902"}),o("li",{children:"229 rue Saint-Honoré, 75001 Paris, France"}),d("li",{children:["Contact:"," ",o("a",{href:"mailto:privacy@contractspec.io",className:"text-primary hover:underline",children:"privacy@contractspec.io"})]})]})]}),o("p",{className:"text-muted-foreground",children:"We are responsible for deciding how we hold and use personal data about you. We are required under data protection legislation to notify you of the information contained in this privacy policy."})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"2. What This Policy Covers"}),o("p",{className:"text-muted-foreground",children:"This privacy policy explains:"}),d("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[o("li",{children:"What personal data we collect through the ContractSpec website and services"}),o("li",{children:"Why we collect and process your data"}),o("li",{children:"How we store and protect your data"}),o("li",{children:"Who we may share your data with"}),o("li",{children:"Your rights under the General Data Protection Regulation (GDPR)"})]}),o("p",{className:"text-muted-foreground",children:"This policy applies to visitors of our website, users who sign up for our waitlist or contact us, and customers who use our services."})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"3. Data We Collect"}),o("p",{className:"text-muted-foreground",children:"We collect different types of data depending on how you interact with ContractSpec:"}),o("div",{className:"overflow-x-auto",children:d("table",{className:"w-full border-collapse text-muted-foreground text-sm",children:[o("thead",{children:d("tr",{className:"border-white/20 border-b",children:[o("th",{className:"py-3 pr-4 text-left font-semibold text-foreground",children:"Category"}),o("th",{className:"py-3 pr-4 text-left font-semibold text-foreground",children:"Data Collected"}),o("th",{className:"py-3 text-left font-semibold text-foreground",children:"When Collected"})]})}),d("tbody",{children:[d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Website Analytics"}),o("td",{className:"py-3 pr-4",children:"Page views, click events, device type, browser, approximate location (country level), session duration, referral source"}),o("td",{className:"py-3",children:"When browsing our website (with consent in EU/EEA)"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Contact / Waitlist"}),o("td",{className:"py-3 pr-4",children:"Name, email address, message content"}),o("td",{className:"py-3",children:"When you submit a form or join our waitlist"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Account Data"}),d("td",{className:"py-3 pr-4",children:[o("em",{children:"Not yet applicable"})," — We do not currently offer user accounts. This section will be updated when accounts are introduced."]}),o("td",{className:"py-3",children:"—"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Billing Data"}),d("td",{className:"py-3 pr-4",children:[o("em",{children:"Not yet applicable"})," — We do not currently process payments. This section will be updated when billing is introduced."]}),o("td",{className:"py-3",children:"—"})]})]})]})})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"4. Why We Process Data (Purposes & Legal Bases)"}),o("p",{className:"text-muted-foreground",children:"Under GDPR, we must have a lawful basis for processing your personal data. We rely on the following:"}),o("div",{className:"overflow-x-auto",children:d("table",{className:"w-full border-collapse text-muted-foreground text-sm",children:[o("thead",{children:d("tr",{className:"border-white/20 border-b",children:[o("th",{className:"py-3 pr-4 text-left font-semibold text-foreground",children:"Purpose"}),o("th",{className:"py-3 pr-4 text-left font-semibold text-foreground",children:"Legal Basis"}),o("th",{className:"py-3 text-left font-semibold text-foreground",children:"Details"})]})}),d("tbody",{children:[d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Website operation & security"}),o("td",{className:"py-3 pr-4",children:"Legitimate interest"}),o("td",{className:"py-3",children:"Ensuring our website functions correctly, preventing abuse, and maintaining security"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Analytics & improvement"}),o("td",{className:"py-3 pr-4",children:"Consent"}),o("td",{className:"py-3",children:"Understanding how users interact with our site to improve our services (gated behind consent in EU/EEA)"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Responding to enquiries"}),o("td",{className:"py-3 pr-4",children:"Legitimate interest / Contract"}),o("td",{className:"py-3",children:"Responding to your questions, processing waitlist requests, or pre-contractual discussions"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Service delivery"}),o("td",{className:"py-3 pr-4",children:"Contract"}),o("td",{className:"py-3",children:"If/when you become a customer, processing your data is necessary to fulfil our contractual obligations"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Legal compliance"}),o("td",{className:"py-3 pr-4",children:"Legal obligation"}),o("td",{className:"py-3",children:"Complying with applicable laws, regulations, or legal processes"})]})]})]})})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"5. Cookies & Tracking"}),d("p",{className:"text-muted-foreground",children:["We use ",o("strong",{className:"text-foreground",children:"PostHog"})," for product analytics to understand how visitors use our website. PostHog may use cookies or similar technologies to collect this information."]}),o("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"Consent in the EU/EEA"}),o("p",{className:"text-muted-foreground",children:"If you are located in the European Union or European Economic Area, we gate analytics tracking behind your explicit consent. Analytics cookies will not be set until you opt-in through our cookie consent mechanism."}),o("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"Withdrawing Consent / Opting Out"}),o("p",{className:"text-muted-foreground",children:"You can withdraw consent or opt out at any time:"}),d("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[d("li",{children:[o("strong",{children:"Cookie settings:"})," Use the cookie preferences link in our website footer to manage your consent"]}),d("li",{children:[o("strong",{children:"Browser settings:"})," Configure your browser to reject cookies or alert you when cookies are being set"]}),d("li",{children:[o("strong",{children:"PostHog opt-out:"}),' PostHog respects "Do Not Track" browser signals where applicable']})]}),o("p",{className:"text-muted-foreground",children:"Note: Rejecting analytics cookies will not affect your ability to use our website."})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"6. Sub-processors & Recipients"}),o("p",{className:"text-muted-foreground",children:"We share data with the following third-party service providers who process data on our behalf:"}),o("div",{className:"overflow-x-auto",children:d("table",{className:"w-full border-collapse text-muted-foreground text-sm",children:[o("thead",{children:d("tr",{className:"border-white/20 border-b",children:[o("th",{className:"py-3 pr-4 text-left font-semibold text-foreground",children:"Provider"}),o("th",{className:"py-3 pr-4 text-left font-semibold text-foreground",children:"Purpose"}),o("th",{className:"py-3 text-left font-semibold text-foreground",children:"Location"})]})}),d("tbody",{children:[d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"PostHog"}),o("td",{className:"py-3 pr-4",children:"Product analytics"}),o("td",{className:"py-3",children:"EU (PostHog Cloud EU) or US"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Vercel"}),o("td",{className:"py-3 pr-4",children:"Website hosting & CDN"}),o("td",{className:"py-3",children:"Global (including EU regions)"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Scaleway"}),o("td",{className:"py-3 pr-4",children:"Cloud infrastructure"}),o("td",{className:"py-3",children:"France / EU"})]}),d("tr",{className:"border-white/10 border-b",children:[d("td",{className:"py-3 pr-4 font-medium",children:["Email provider ",o("em",{children:"(TBD)"})]}),o("td",{className:"py-3 pr-4",children:"Transactional & marketing emails"}),o("td",{className:"py-3",children:o("em",{children:"To be confirmed"})})]}),d("tr",{className:"border-white/10 border-b",children:[d("td",{className:"py-3 pr-4 font-medium",children:["Error tracking ",o("em",{children:"(TBD)"})]}),o("td",{className:"py-3 pr-4",children:"Application error monitoring"}),o("td",{className:"py-3",children:o("em",{children:"To be confirmed"})})]}),d("tr",{className:"border-white/10 border-b",children:[d("td",{className:"py-3 pr-4 font-medium",children:["Payment processor ",o("em",{children:"(TBD)"})]}),o("td",{className:"py-3 pr-4",children:"Billing & subscription management"}),o("td",{className:"py-3",children:o("em",{children:"To be confirmed"})})]})]})]})}),o("p",{className:"mt-4 text-muted-foreground",children:"We carefully select our sub-processors and require them to maintain appropriate security measures and only process data according to our instructions."})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"7. International Data Transfers"}),o("p",{className:"text-muted-foreground",children:"As a France-based company, we aim to keep your data within the European Union wherever possible."}),o("p",{className:"text-muted-foreground",children:"However, some of our service providers may process data outside the EU/EEA. When this occurs, we ensure appropriate safeguards are in place, such as:"}),d("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[d("li",{children:[o("strong",{children:"Standard Contractual Clauses (SCCs)"})," approved by the European Commission"]}),d("li",{children:[o("strong",{children:"Adequacy decisions"})," where the recipient country has been deemed to provide adequate protection"]}),d("li",{children:[o("strong",{children:"Binding Corporate Rules"})," where applicable"]})]}),d("p",{className:"text-muted-foreground",children:["You may request more information about these safeguards by contacting us at"," ",o("a",{href:"mailto:privacy@contractspec.io",className:"text-primary hover:underline",children:"privacy@contractspec.io"}),"."]})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"8. Data Retention"}),o("p",{className:"text-muted-foreground",children:"We retain your personal data only for as long as necessary to fulfil the purposes for which it was collected:"}),o("div",{className:"overflow-x-auto",children:d("table",{className:"w-full border-collapse text-muted-foreground text-sm",children:[o("thead",{children:d("tr",{className:"border-white/20 border-b",children:[o("th",{className:"py-3 pr-4 text-left font-semibold text-foreground",children:"Data Type"}),o("th",{className:"py-3 text-left font-semibold text-foreground",children:"Retention Period"})]})}),d("tbody",{children:[d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Analytics data"}),o("td",{className:"py-3",children:"24 months from collection"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Waitlist / contact form data"}),o("td",{className:"py-3",children:"Until you request deletion or 24 months after last interaction"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Account data (when applicable)"}),o("td",{className:"py-3",children:"Duration of account plus 12 months after closure"})]}),d("tr",{className:"border-white/10 border-b",children:[o("td",{className:"py-3 pr-4 font-medium",children:"Billing records (when applicable)"}),o("td",{className:"py-3",children:"10 years (French legal requirement)"})]})]})]})}),o("p",{className:"mt-4 text-muted-foreground",children:"We may retain certain data longer if required by law or to establish, exercise, or defend legal claims."})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"9. Your Rights Under GDPR"}),o("p",{className:"text-muted-foreground",children:"As a data subject in the EU, you have the following rights:"}),d("ul",{className:"list-disc space-y-3 pl-6 text-muted-foreground",children:[d("li",{children:[o("strong",{className:"text-foreground",children:"Right to access"})," — Request a copy of the personal data we hold about you"]}),d("li",{children:[o("strong",{className:"text-foreground",children:"Right to rectification"})," ","— Request correction of inaccurate or incomplete data"]}),d("li",{children:[o("strong",{className:"text-foreground",children:'Right to erasure ("right to be forgotten")'})," ","— Request deletion of your personal data in certain circumstances"]}),d("li",{children:[o("strong",{className:"text-foreground",children:"Right to restriction"})," ","— Request that we limit how we use your data"]}),d("li",{children:[o("strong",{className:"text-foreground",children:"Right to data portability"})," ","— Receive your data in a structured, machine-readable format"]}),d("li",{children:[o("strong",{className:"text-foreground",children:"Right to object"})," — Object to processing based on legitimate interests or direct marketing"]}),d("li",{children:[o("strong",{className:"text-foreground",children:"Right to withdraw consent"})," ","— Where processing is based on consent, withdraw it at any time"]})]}),d("p",{className:"mt-4 text-muted-foreground",children:["To exercise any of these rights, please contact us at"," ",o("a",{href:"mailto:privacy@contractspec.io",className:"text-primary hover:underline",children:"privacy@contractspec.io"}),". We will respond within one month as required by GDPR."]})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"10. Security"}),o("p",{className:"text-muted-foreground",children:"We implement appropriate technical and organisational measures to protect your personal data against unauthorised access, alteration, disclosure, or destruction. These measures include:"}),d("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[o("li",{children:"Encryption of data in transit (TLS/HTTPS)"}),o("li",{children:"Encryption of data at rest where appropriate"}),o("li",{children:"Access controls and authentication"}),o("li",{children:"Regular security reviews and updates"}),o("li",{children:"Careful vetting of sub-processors"})]}),o("p",{className:"text-muted-foreground",children:"While we strive to protect your data, no method of transmission over the Internet or electronic storage is 100% secure. We cannot guarantee absolute security but are committed to continuous improvement."})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"11. Contact & Complaints"}),o("p",{className:"text-muted-foreground",children:"If you have any questions, concerns, or requests regarding this privacy policy or our data practices, please contact us:"}),d("div",{className:"rounded-lg border border-white/10 bg-white/5 p-4 text-muted-foreground",children:[d("p",{children:[o("strong",{className:"text-foreground",children:"Email:"})," ",o("a",{href:"mailto:privacy@contractspec.io",className:"text-primary hover:underline",children:"privacy@contractspec.io"})]}),d("p",{className:"mt-2",children:[o("strong",{className:"text-foreground",children:"Address:"})," CHAMAN VENTURES, 229 rue Saint-Honoré, 75001 Paris, France"]})]}),o("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"Supervisory Authority"}),o("p",{className:"text-muted-foreground",children:"If you are not satisfied with our response or believe we are processing your data unlawfully, you have the right to lodge a complaint with a supervisory authority. In France, the relevant authority is:"}),d("div",{className:"rounded-lg border border-white/10 bg-white/5 p-4 text-muted-foreground",children:[o("p",{children:o("strong",{className:"text-foreground",children:"Commission Nationale de l'Informatique et des Libertés (CNIL)"})}),o("p",{children:"3 Place de Fontenoy, TSA 80715, 75334 Paris Cedex 07"}),d("p",{children:["Website:"," ",o("a",{href:"https://www.cnil.fr",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:"www.cnil.fr"})]})]})]}),d("section",{className:"mt-10 space-y-4",children:[o("h2",{className:"font-bold text-2xl text-foreground",children:"12. Changes to This Policy"}),o("p",{className:"text-muted-foreground",children:'We may update this privacy policy from time to time to reflect changes in our practices, technology, legal requirements, or for other operational reasons. We will notify you of any material changes by updating the "Last updated" date at the top of this page.'}),o("p",{className:"text-muted-foreground",children:"We encourage you to review this policy periodically to stay informed about how we protect your data."})]}),o("div",{className:"mt-12 border-white/10 border-t pt-8",children:d("p",{className:"text-muted-foreground text-sm",children:["For questions about this privacy policy, please contact us at"," ",o("a",{href:"mailto:privacy@contractspec.io",className:"text-primary hover:underline",children:"privacy@contractspec.io"})]})})]})})})}import{jsx as i,jsxs as p}from"react/jsx-runtime";var fD={title:"Terms of Service | ContractSpec",description:"Terms of Service for ContractSpec. Read our terms governing use of the ContractSpec website and services."};function $b(){return i("main",{className:"flex grow flex-col items-center justify-center pt-24",children:i("section",{className:"section-padding",children:p("div",{className:"prose prose-invert mx-auto max-w-3xl",children:[i("h1",{className:"mb-4 font-bold text-4xl",children:"Terms of Service"}),i("p",{className:"mb-8 text-muted-foreground",children:"Last updated: December 18, 2025"}),p("section",{className:"space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"1. Definitions"}),i("p",{className:"text-muted-foreground",children:'In these Terms of Service ("Terms"), the following definitions apply:'}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[p("li",{children:[i("strong",{className:"text-foreground",children:'"ContractSpec"'}),","," ",i("strong",{className:"text-foreground",children:'"we"'}),","," ",i("strong",{className:"text-foreground",children:'"us"'}),", or"," ",i("strong",{className:"text-foreground",children:'"our"'})," refers to CHAMAN VENTURES, SASU, operating under the ContractSpec brand."]}),p("li",{children:[i("strong",{className:"text-foreground",children:'"Service"'})," or"," ",i("strong",{className:"text-foreground",children:'"Services"'})," refers to the ContractSpec website, ContractSpec Studio, APIs, documentation, and any related products or features we provide."]}),p("li",{children:[i("strong",{className:"text-foreground",children:'"User"'}),","," ",i("strong",{className:"text-foreground",children:'"you"'}),", or"," ",i("strong",{className:"text-foreground",children:'"your"'})," refers to any individual or entity accessing or using the Services."]}),p("li",{children:[i("strong",{className:"text-foreground",children:'"User Content"'})," ","refers to any data, specifications, configurations, or other materials you create, upload, or submit through the Services."]}),p("li",{children:[i("strong",{className:"text-foreground",children:'"ContractSpec Core"'})," ","refers to the open-source components of ContractSpec available under their respective open-source licenses."]}),p("li",{children:[i("strong",{className:"text-foreground",children:'"Design Partner"'})," ","refers to early users who have entered into a separate design partnership arrangement with us."]})]})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"2. Who We Are"}),p("p",{className:"text-muted-foreground",children:["ContractSpec is a brand of"," ",i("strong",{className:"text-foreground",children:"CHAMAN VENTURES"}),", a simplified joint-stock company (SASU) registered in France."]}),i("div",{className:"rounded-lg border border-white/10 bg-white/5 p-4 text-muted-foreground",children:p("ul",{className:"list-none space-y-1 pl-0",children:[i("li",{children:"CHAMAN VENTURES, SASU"}),i("li",{children:"RCS Paris • SIREN 989 498 902"}),i("li",{children:"229 rue Saint-Honoré, 75001 Paris, France"}),p("li",{children:["Contact:"," ",i("a",{href:"mailto:legal@contractspec.io",className:"text-primary hover:underline",children:"legal@contractspec.io"})]})]})})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"3. Acceptance of Terms"}),p("p",{className:"text-muted-foreground",children:["By accessing or using ContractSpec, you agree to be bound by these Terms and our"," ",i("a",{href:"/legal/privacy",className:"text-primary hover:underline",children:"Privacy Policy"}),". If you do not agree to these Terms, you must not use the Services."]}),i("p",{className:"text-muted-foreground",children:'We may update these Terms from time to time. We will notify you of material changes by updating the "Last updated" date. Continued use of the Services after changes constitutes acceptance of the updated Terms.'})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"4. Eligibility"}),i("p",{className:"text-muted-foreground",children:"To use the Services, you must:"}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[i("li",{children:"Be at least 18 years old or the age of majority in your jurisdiction"}),i("li",{children:"Have the legal capacity to enter into binding contracts"}),i("li",{children:"Not be prohibited from using the Services under applicable laws"}),i("li",{children:"If acting on behalf of an organisation, have the authority to bind that organisation to these Terms"})]})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"5. Accounts"}),p("div",{className:"rounded-lg border border-yellow-500/20 bg-yellow-500/5 p-4 text-muted-foreground",children:[i("p",{className:"mb-2 font-medium text-yellow-500",children:"Note"}),i("p",{children:"User accounts are not yet available. When accounts are introduced, the following terms will apply:"})]}),p("ul",{className:"mt-4 list-disc space-y-2 pl-6 text-muted-foreground",children:[i("li",{children:"You are responsible for maintaining the confidentiality of your account credentials"}),i("li",{children:"You are responsible for all activities that occur under your account"}),i("li",{children:"You must notify us immediately of any unauthorised use of your account"}),i("li",{children:"We reserve the right to suspend or terminate accounts that violate these Terms"})]})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"6. License & Intellectual Property"}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"6.1 Our Intellectual Property"}),i("p",{className:"text-muted-foreground",children:"The ContractSpec name, logo, website design, proprietary software, documentation, and all associated intellectual property rights are owned by CHAMAN VENTURES. Subject to these Terms, we grant you a limited, non-exclusive, non-transferable, revocable license to access and use the Services for their intended purpose."}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"6.2 Open-Source Components"}),i("p",{className:"text-muted-foreground",children:'Certain components of ContractSpec ("ContractSpec Core") are made available as open-source software under their respective licenses (e.g., MIT, Apache 2.0). Your use of open-source components is governed by those licenses, which may grant you additional rights not covered by these Terms. In case of conflict between these Terms and an open-source license, the open-source license prevails for the applicable component.'}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"6.3 Your Content"}),p("p",{className:"text-muted-foreground",children:[i("strong",{className:"text-foreground",children:"You retain ownership"})," ","of all User Content you create, upload, or submit through the Services. This includes your specifications, configurations, and any other materials you generate."]}),i("p",{className:"text-muted-foreground",children:"By using the Services, you grant us a limited, non-exclusive, worldwide, royalty-free license to host, store, process, and display your User Content solely to the extent necessary to provide and improve the Services. This license terminates when you delete your User Content or close your account, except where retention is required by law or for legitimate business purposes (e.g., backups, legal compliance)."}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"6.4 Feedback"}),i("p",{className:"text-muted-foreground",children:"If you provide feedback, suggestions, or ideas about the Services, you grant us a perpetual, irrevocable, royalty-free license to use, modify, and incorporate such feedback without obligation to you."})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"7. Acceptable Use"}),i("p",{className:"text-muted-foreground",children:"When using the Services, you agree not to:"}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[p("li",{children:[i("strong",{className:"text-foreground",children:"Abuse the Services:"})," ","Use the Services in a manner that disrupts, damages, or impairs our infrastructure or other users' experience"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Probe security:"})," ","Attempt to gain unauthorised access to our systems, networks, or data; perform security testing without prior written permission"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Distribute harmful content:"})," ","Upload, share, or distribute malware, viruses, or other malicious code"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Engage in illegal activity:"})," ","Use the Services for any purpose that is unlawful, fraudulent, or harmful"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Interfere with operations:"})," ","Attempt to interfere with, disrupt, or circumvent any security or access controls"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Violate rights:"})," ","Infringe upon the intellectual property, privacy, or other rights of third parties"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Misrepresent identity:"})," ","Impersonate any person or entity, or falsely claim affiliation with ContractSpec"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Circumvent limits:"})," ","Attempt to bypass any usage limits, rate limits, or access restrictions"]})]}),i("p",{className:"mt-4 text-muted-foreground",children:"We reserve the right to investigate violations and take appropriate action, including suspension or termination of access."})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"8. Beta & Preview Services"}),p("div",{className:"rounded-lg border border-orange-500/20 bg-orange-500/5 p-4 text-muted-foreground",children:[i("p",{className:"mb-2 font-medium text-orange-400",children:"⚠️ Important"}),i("p",{children:'ContractSpec is currently in active development. Some features may be labelled as "Beta", "Preview", "Alpha", or similar designations.'})]}),i("p",{className:"mt-4 text-muted-foreground",children:"By using beta or preview features, you acknowledge:"}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[p("li",{children:[i("strong",{className:"text-foreground",children:"Things may break:"})," ","Beta features may contain bugs, errors, or unexpected behaviour"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"No availability guarantee:"})," ","We do not guarantee uptime, availability, or continuity of beta features"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Features may change or disappear:"})," ","We may modify, suspend, or discontinue beta features at any time without notice"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Not for production:"})," ","Beta features should not be relied upon for mission-critical or production workloads unless you accept these risks"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Data may be lost:"})," ","We cannot guarantee the preservation of data created using beta features"]})]})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"9. Design Partner Program"}),i("p",{className:"text-muted-foreground",children:"We offer a Design Partner program for early users who wish to collaborate closely with us to shape the product. If you participate as a Design Partner:"}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"9.1 Scope"}),i("p",{className:"text-muted-foreground",children:"Design Partners receive early access to features, provide feedback, and help validate product direction. The specific scope of your participation will be outlined in a separate agreement or communication."}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"9.2 Feedback"}),i("p",{className:"text-muted-foreground",children:"We value your input. Feedback you provide may be used to improve the Services. See Section 6.4 for licensing terms regarding feedback."}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"9.3 Confidentiality"}),i("p",{className:"text-muted-foreground",children:"Design Partners may receive access to confidential or pre-release information. Unless otherwise specified in a separate agreement, you agree to keep such information confidential and not share it publicly without our prior written consent."}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"9.4 Mutual Expectations"}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[p("li",{children:[i("strong",{className:"text-foreground",children:"From us:"})," Regular communications, responsiveness to feedback, and transparency about product direction"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"From you:"})," Timely and honest feedback, reasonable engagement, and adherence to these Terms"]})]})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"10. Fees & Billing"}),p("div",{className:"rounded-lg border border-yellow-500/20 bg-yellow-500/5 p-4 text-muted-foreground",children:[i("p",{className:"mb-2 font-medium text-yellow-500",children:"Note"}),i("p",{children:"Paid plans are not yet available. When paid plans are introduced, the following terms will apply:"})]}),p("ul",{className:"mt-4 list-disc space-y-2 pl-6 text-muted-foreground",children:[i("li",{children:"Fees will be clearly communicated before you commit to a paid plan"}),i("li",{children:"Payment terms, billing cycles, and refund policies will be specified at that time"}),i("li",{children:"We reserve the right to change pricing with reasonable notice"}),i("li",{children:"Failure to pay may result in suspension or termination of paid features"})]})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"11. Third-Party Services"}),i("p",{className:"text-muted-foreground",children:"The Services may integrate with or contain links to third-party services, websites, or content. We do not control and are not responsible for third-party services."}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[i("li",{children:"Your use of third-party services is governed by their respective terms and policies"}),i("li",{children:"We make no warranties or representations about third-party services"}),i("li",{children:"Links to third-party sites do not imply endorsement"}),i("li",{children:"You are responsible for reviewing the terms of any third-party services you use"})]})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"12. Disclaimer of Warranties"}),i("div",{className:"rounded-lg border border-white/10 bg-white/5 p-4 text-muted-foreground",children:i("p",{className:"font-medium uppercase",children:'THE SERVICES ARE PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED.'})}),i("p",{className:"mt-4 text-muted-foreground",children:"To the fullest extent permitted by law, we disclaim:"}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[i("li",{children:"Warranties of merchantability, fitness for a particular purpose, and non-infringement"}),i("li",{children:"Any warranty that the Services will be uninterrupted, secure, or error-free"}),i("li",{children:"Any warranty regarding the accuracy, reliability, or completeness of content"}),i("li",{children:"Any warranty that defects will be corrected or that the Services are free of viruses or harmful components"})]}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"No Professional Advice"}),i("p",{className:"text-muted-foreground",children:"The Services are tools for software development. Nothing in the Services constitutes legal, financial, technical, or other professional advice. You are solely responsible for evaluating the suitability of the Services for your needs and for any decisions you make based on the output."})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"13. Limitation of Liability"}),i("p",{className:"text-muted-foreground",children:"To the maximum extent permitted by applicable law:"}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[p("li",{children:[i("strong",{className:"text-foreground",children:"No indirect damages:"})," ","We shall not be liable for any indirect, incidental, special, consequential, or punitive damages, including loss of profits, data, goodwill, or other intangible losses"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Limited direct liability:"})," ","Our total aggregate liability for any claims arising from or related to the Services shall not exceed the greater of: (a) the amount you paid us in the 12 months preceding the claim, or (b) €100"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Exceptions:"})," These limitations do not apply to liability that cannot be excluded under applicable law, including liability for fraud or wilful misconduct"]})]}),i("p",{className:"mt-4 text-muted-foreground",children:"You acknowledge that these limitations reflect a reasonable allocation of risk and are a fundamental basis of the agreement between us."})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"14. Termination"}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"14.1 By You"}),i("p",{className:"text-muted-foreground",children:"You may stop using the Services at any time. When accounts are available, you may close your account through the account settings or by contacting us."}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"14.2 By Us"}),i("p",{className:"text-muted-foreground",children:"We may suspend or terminate your access to the Services at any time, with or without cause, with or without notice. Reasons for termination may include:"}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[i("li",{children:"Violation of these Terms"}),i("li",{children:"Conduct that we believe is harmful to other users or our business"}),i("li",{children:"Extended inactivity"}),i("li",{children:"Discontinuation of the Services"})]}),i("h3",{className:"mt-6 font-semibold text-foreground text-xl",children:"14.3 Effect of Termination"}),i("p",{className:"text-muted-foreground",children:"Upon termination, your right to use the Services ceases immediately. Provisions that by their nature should survive termination will survive, including intellectual property rights, disclaimers, limitations of liability, and dispute resolution."})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"15. Governing Law & Jurisdiction"}),p("p",{className:"text-muted-foreground",children:["These Terms are governed by and construed in accordance with the laws of ",i("strong",{className:"text-foreground",children:"France"}),", without regard to conflict of law principles."]}),p("p",{className:"text-muted-foreground",children:["Any disputes arising from or related to these Terms or the Services shall be subject to the exclusive jurisdiction of the courts of"," ",i("strong",{className:"text-foreground",children:"Paris, France"}),"."]}),i("p",{className:"text-muted-foreground",children:"If you are a consumer in the European Union, nothing in these Terms affects your rights under mandatory consumer protection laws of your country of residence."})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"16. Contact"}),i("p",{className:"text-muted-foreground",children:"If you have any questions about these Terms, please contact us:"}),p("div",{className:"rounded-lg border border-white/10 bg-white/5 p-4 text-muted-foreground",children:[p("p",{children:[i("strong",{className:"text-foreground",children:"Email:"})," ",i("a",{href:"mailto:legal@contractspec.io",className:"text-primary hover:underline",children:"legal@contractspec.io"})]}),p("p",{className:"mt-2",children:[i("strong",{className:"text-foreground",children:"Address:"})," CHAMAN VENTURES, 229 rue Saint-Honoré, 75001 Paris, France"]})]})]}),p("section",{className:"mt-10 space-y-4",children:[i("h2",{className:"font-bold text-2xl text-foreground",children:"17. Miscellaneous"}),p("ul",{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:[p("li",{children:[i("strong",{className:"text-foreground",children:"Entire Agreement:"})," ","These Terms, together with our Privacy Policy and any additional agreements, constitute the entire agreement between you and ContractSpec regarding the Services"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Severability:"})," If any provision of these Terms is found unenforceable, the remaining provisions will continue in effect"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Waiver:"})," Our failure to enforce any right or provision does not constitute a waiver of that right or provision"]}),p("li",{children:[i("strong",{className:"text-foreground",children:"Assignment:"})," You may not assign or transfer your rights under these Terms without our consent. We may assign our rights freely"]})]})]}),i("div",{className:"mt-12 border-white/10 border-t pt-8",children:p("p",{className:"text-muted-foreground text-sm",children:["For questions about these terms, please contact us at"," ",i("a",{href:"mailto:legal@contractspec.io",className:"text-primary hover:underline",children:"legal@contractspec.io"})]})})]})})})}import{Lock as Xb}from"lucide-react";import{jsx as ar,jsxs as xb}from"react/jsx-runtime";function kD({title:e,description:t,actionLabel:a,onAction:r}){return xb("div",{className:"text-center",children:[ar("div",{className:"mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-muted/40",children:ar(Xb,{className:"h-5 w-5 text-muted-foreground"})}),ar("h3",{className:"mt-4 font-semibold text-lg",children:e}),ar("p",{className:"mt-2 text-muted-foreground text-sm",children:t}),a?ar("button",{type:"button",className:"btn-primary mt-4 inline-flex items-center justify-center",onClick:r,children:a}):null]})}import{Select as jb,SelectContent as ev,SelectItem as tv,SelectTrigger as av,SelectValue as ov}from"@contractspec/lib.ui-kit-web/ui/select";import*as xd from"react";import{jsx as xa,jsxs as Mi}from"react/jsx-runtime";function Er({title:e,subtitle:t,workspaceSelect:a,projectSelect:r,environmentSelect:l,stickyHeaderOffsetPx:b,headerRight:h}){return xa("div",{className:"sticky top-0 z-10 border-border border-b bg-card",style:{top:b??0},children:Mi("div",{className:"mx-auto flex w-full max-w-7xl flex-col gap-3 px-4 py-3 md:flex-row md:items-center md:justify-between",children:[Mi("div",{className:"min-w-0",children:[Mi("div",{className:"flex items-center gap-2",children:[xa("p",{className:"truncate font-semibold text-base",children:e}),t?xa("p",{className:"hidden text-muted-foreground text-sm md:block",children:t}):null]}),Mi("div",{className:"mt-2 flex flex-wrap gap-2",children:[a?xa(Wn,{select:a}):null,r?xa(Wn,{select:r}):null,l?xa(Wn,{select:l}):null]})]}),xa("div",{className:"flex items-center justify-between gap-2 md:justify-end",children:h})]})})}function Wn({select:e}){let t=xd.useId();return Mi("div",{className:"flex min-w-[220px] flex-col gap-1",children:[xa("span",{id:t,className:"text-muted-foreground text-xs",children:e.label}),Mi(jb,{value:e.value,onValueChange:e.onChange,children:[xa(av,{"aria-labelledby":t,className:"w-full",children:xa(ov,{placeholder:e.placeholder??e.label})}),xa(ev,{children:e.options.map((a)=>xa(tv,{value:a.value,children:a.label},a.value))})]})]})}import{Sidebar as iv,SidebarContent as rv,SidebarFooter as nv,SidebarHeader as cv,SidebarMenu as lv,SidebarMenuButton as jd,SidebarMenuItem as es,SidebarRail as dv}from"@contractspec/lib.ui-kit-web/ui/sidebar";import{Settings as sv}from"lucide-react";import{jsx as Io,jsxs as Or}from"react/jsx-runtime";function Br({modules:e,activeModuleId:t,onModuleChange:a,sidebarFooter:r}){return Or(iv,{children:[Io(dv,{}),Io(cv,{}),Io(rv,{children:Or(lv,{children:[e.map((l)=>Io(es,{children:Or(jd,{isActive:l.id===t,onClick:()=>a(l.id),children:[l.icon,Io("span",{children:l.label}),l.badge!=null?Io("span",{className:"ml-auto text-muted-foreground text-xs",children:String(l.badge)}):null]})},l.id)),Io(es,{children:Or(jd,{isActive:t==="settings",onClick:()=>a("settings"),children:[Io(sv,{className:"size-4"}),Io("span",{children:"Settings"})]})})]})}),Io(nv,{children:r})]})}import{SidebarInset as pv,SidebarProvider as mv}from"@contractspec/lib.ui-kit-web/ui/sidebar";import{cn as uv}from"@contractspec/lib.ui-kit-web/ui/utils";import{jsx as Mr,jsxs as ts}from"react/jsx-runtime";function _D({title:e,subtitle:t,workspaceSelect:a,projectSelect:r,environmentSelect:l,stickyHeaderOffsetPx:b,headerRight:h,modules:v,activeModuleId:V,onModuleChange:g,sidebarFooter:tt,assistant:va,children:ye,className:Ke}){return ts(mv,{children:[Mr(Br,{modules:v,activeModuleId:V,onModuleChange:g,sidebarFooter:tt}),Mr(pv,{children:ts("div",{className:uv("min-h-svh bg-background",Ke),children:[Mr(Er,{title:e,subtitle:t,workspaceSelect:a,projectSelect:r,environmentSelect:l,stickyHeaderOffsetPx:b,headerRight:h}),Mr("main",{className:"m-4",children:ye})]})}),va]})}import{BundleProvider as gv,BundleRenderer as fv}from"@contractspec/lib.surface-runtime/react";import{SidebarProvider as hv}from"@contractspec/lib.ui-kit-web/ui/sidebar";import{jsx as bi}from"react/jsx-runtime";function KD({plan:e,title:t,subtitle:a,workspaceSelect:r,projectSelect:l,environmentSelect:b,stickyHeaderOffsetPx:h,headerRight:v,modules:V,activeModuleId:g,onModuleChange:tt,sidebarFooter:va,assistant:ye,children:Ke,className:Gi}){let Qe={header:bi(Er,{title:t,subtitle:a,workspaceSelect:r,projectSelect:l,environmentSelect:b,stickyHeaderOffsetPx:h,headerRight:v}),sidebar:bi(Br,{modules:V,activeModuleId:g,onModuleChange:tt,sidebarFooter:va}),primary:bi("main",{className:Gi?`m-4 ${Gi}`:"m-4",children:Ke})};if(ye!=null)Qe.assistant=ye;return bi(hv,{children:bi(gv,{plan:e,children:bi("div",{className:"min-h-svh bg-background",children:bi(fv,{slotContent:Qe})})})})}import{gql as yv}from"@apollo/client";import{useQuery as bv}from"@apollo/client/react";import{useTemplateRuntime as vv}from"@contractspec/lib.example-shared-ui";import{MessageCircle as Nv,Users as wv}from"lucide-react";import{useMemo as kv}from"react";import{jsx as vi,jsxs as Ui}from"react/jsx-runtime";var Sv=yv`
|
|
4800
4800
|
query Conversations($projectId: ID!) {
|
|
4801
4801
|
conversations(projectId: $projectId) {
|
|
4802
4802
|
id
|
|
@@ -4810,7 +4810,7 @@ export const PaymentFlow = defineWorkflow({
|
|
|
4810
4810
|
}
|
|
4811
4811
|
}
|
|
4812
4812
|
}
|
|
4813
|
-
`;function
|
|
4813
|
+
`;function as({selectedId:e,onSelect:t}){let{projectId:a}=vv(),{data:r,loading:l}=bv(Sv,{variables:{projectId:a},fetchPolicy:"cache-and-network"}),b=kv(()=>r?.conversations??[],[r]);return Ui("aside",{className:"h-full overflow-y-auto rounded-2xl border border-border bg-card",children:[Ui("header",{className:"px -4 flex items-center justify-between border-border border-b px-4 py-3",children:[Ui("div",{children:[vi("p",{className:"font-semibold text-sm",children:"Conversations"}),vi("p",{className:"text-muted-foreground text-xs",children:l?"Loading…":`${b.length} active`})]}),vi(wv,{className:"h-4 w-4 text-muted-foreground"})]}),Ui("div",{className:"divide-y divide-border/70",children:[b.map((h)=>{let v=e===h.id;return Ui("button",{type:"button",className:`flex w-full flex-col items-start gap-1 px-4 py-3 text-left transition ${v?"bg-violet-500/10 text-foreground":"hover:bg-muted/40"}`,onClick:()=>t?.(h.id),children:[Ui("div",{className:"flex items-center gap-2",children:[vi(Nv,{className:"h-4 w-4 text-muted-foreground"}),vi("span",{className:"font-medium text-sm",children:h.name||"Untitled conversation"})]}),vi("p",{className:"text-muted-foreground text-xs",children:h.participants.map((V)=>V.displayName||V.userId).join(" · ")})]},h.id)}),!l&&b.length===0?vi("p",{className:"p-4 text-center text-muted-foreground text-xs",children:"No conversations yet."}):null]})]})}import{gql as rs}from"@apollo/client";import{useMutation as Cv,useQuery as Iv}from"@apollo/client/react";import{useTemplateRuntime as Pv}from"@contractspec/lib.example-shared-ui";import{useEffect as os,useRef as Tv}from"react";import{jsx as Ni,jsxs as is}from"react/jsx-runtime";var _n=rs`
|
|
4814
4814
|
query Messages($conversationId: ID!) {
|
|
4815
4815
|
messages(conversationId: $conversationId, limit: 50) {
|
|
4816
4816
|
id
|
|
@@ -4821,17 +4821,17 @@ export const PaymentFlow = defineWorkflow({
|
|
|
4821
4821
|
status
|
|
4822
4822
|
}
|
|
4823
4823
|
}
|
|
4824
|
-
`,
|
|
4824
|
+
`,Av=rs`
|
|
4825
4825
|
mutation SetMessagesRead($conversationId: ID!, $userId: String!) {
|
|
4826
4826
|
setMessagesRead(conversationId: $conversationId, userId: $userId)
|
|
4827
4827
|
}
|
|
4828
|
-
`;function
|
|
4828
|
+
`;function zn({conversationId:e,viewerId:t="local-user"}){let a=Tv(null),r=Boolean(e),{data:l,loading:b}=Iv(_n,{variables:{conversationId:e},skip:!r,fetchPolicy:"cache-and-network"}),[h]=Cv(Av),{projectId:v}=Pv(),V=l?.messages??[];if(os(()=>{if(!r||!e)return;h({variables:{conversationId:e,userId:t}}).catch(()=>{})},[e,r,h,t]),os(()=>{let g=a.current;if(!g)return;g.scrollTop=g.scrollHeight},[V]),!e)return Ni("div",{className:"flex flex-1 items-center justify-center rounded-2xl border border-border border-dashed",children:Ni("p",{className:"text-muted-foreground text-sm",children:"Select a conversation"})});return Ni("div",{className:"flex flex-1 flex-col rounded-2xl border border-border bg-card",children:Ni("div",{ref:a,className:"flex-1 space-y-3 overflow-y-auto p-4",children:b?Ni("p",{className:"text-center text-muted-foreground text-sm",children:"Loading…"}):V.slice().reverse().map((g)=>is("div",{className:`flex flex-col ${g.senderId===t?"items-end":"items-start"}`,children:[Ni("div",{className:`max-w-xs rounded-2xl px-3 py-2 text-sm ${g.senderId===t?"bg-violet-500 text-white":"bg-muted text-foreground"}`,children:Ni("p",{children:g.content})}),is("span",{className:"mt-1 text-muted-foreground text-xs",children:[g.senderName||g.senderId," ·"," ",new Date(g.createdAt).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})]})]},g.id))})})}import{gql as Rv}from"@apollo/client";import{useMutation as Lv}from"@apollo/client/react";import{useTemplateRuntime as Dv}from"@contractspec/lib.example-shared-ui";import{Send as Ev}from"lucide-react";import{useState as Ov}from"react";import{jsx as ns,jsxs as cs}from"react/jsx-runtime";var Bv=Rv`
|
|
4829
4829
|
mutation SendMessage($input: SendMessageInput!) {
|
|
4830
4830
|
sendMessage(input: $input) {
|
|
4831
4831
|
id
|
|
4832
4832
|
}
|
|
4833
4833
|
}
|
|
4834
|
-
`;function
|
|
4834
|
+
`;function Gn({conversationId:e,viewerId:t="local-user",viewerName:a="You"}){let{projectId:r}=Dv(),[l,b]=Ov(""),[h,{loading:v}]=Lv(Bv);return cs("form",{onSubmit:async(g)=>{if(g.preventDefault(),!e||!l.trim())return;await h({variables:{input:{projectId:r,conversationId:e,senderId:t,senderName:a,content:l.trim()}},refetchQueries:[{query:_n,variables:{conversationId:e}}]}),b("")},className:"mt-3 flex items-center gap-2 rounded-2xl border border-border bg-card px-4 py-3",children:[ns("input",{type:"text",className:"flex-1 bg-transparent text-foreground text-sm outline-none",placeholder:e?"Type a message…":"Select a conversation to start",disabled:!e||v,value:l,onChange:(g)=>b(g.target.value)}),cs("button",{type:"submit",className:"btn-primary inline-flex items-center gap-1 text-sm",disabled:!e||v||!l.trim(),children:[ns(Ev,{className:"h-4 w-4"}),"Send"]})]})}import{registerTemplateComponents as Mv}from"@contractspec/lib.example-shared-ui";import{useState as Uv}from"react";import{jsx as qn,jsxs as ls}from"react/jsx-runtime";function Wv(){let[e,t]=Uv();return ls("div",{className:"grid gap-4 md:grid-cols-[280px,1fr]",children:[qn(as,{selectedId:e,onSelect:t}),ls("div",{className:"flex flex-col gap-3",children:[qn(zn,{conversationId:e}),qn(Gn,{conversationId:e})]})]})}Mv("messaging-app",{list:Wv,detail:zn,form:Gn});import{jsx as ds}from"react/jsx-runtime";function ss({locale:e,onChange:t}){return ds("div",{className:"inline-flex rounded-full border border-border bg-card p-1 font-semibold text-muted-foreground text-xs",children:["EN","FR"].map((a)=>ds("button",{type:"button",className:`rounded-full px-3 py-1 transition ${e===a?"bg-violet-500 text-white":"hover:text-foreground"}`,onClick:()=>t(a),children:a==="EN"?"English":"Français"},a))})}import{Heart as _v}from"lucide-react";import{jsx as Wi,jsxs as wi}from"react/jsx-runtime";function ps({recipe:e,onSelect:t,onToggleFavorite:a}){return wi("button",{type:"button",onClick:()=>t?.(e),className:"flex flex-col gap-3 rounded-2xl border border-border bg-card text-left transition hover:border-violet-400",children:[e.heroImageUrl?Wi("img",{src:e.heroImageUrl,alt:e.name,className:"h-40 w-full rounded-t-2xl object-cover"}):Wi("div",{className:"h-40 rounded-t-2xl bg-muted"}),wi("div",{className:"space-y-2 p-4",children:[wi("div",{className:"flex items-center justify-between",children:[Wi("p",{className:"font-semibold text-base",children:e.name}),Wi("button",{type:"button",className:`inline-flex items-center justify-center rounded-full border border-transparent p-2 ${e.isFavorite?"text-red-400":"text-muted-foreground hover:text-red-400"}`,onClick:(r)=>{r.stopPropagation(),a?.(e)},children:Wi(_v,{className:`h-4 w-4 ${e.isFavorite?"fill-red-400":""}`})})]}),Wi("p",{className:"line-clamp-2 text-muted-foreground text-sm",children:e.description}),wi("div",{className:"flex flex-wrap gap-3 text-muted-foreground text-xs",children:[e.prepTimeMinutes?wi("span",{children:["Prep ",e.prepTimeMinutes,"m"]}):null,e.cookTimeMinutes?wi("span",{children:["Cook ",e.cookTimeMinutes,"m"]}):null,e.servings?wi("span",{children:[e.servings," servings"]}):null]})]})]})}import{BookOpen as zv}from"lucide-react";import{jsx as Po,jsxs as _i}from"react/jsx-runtime";function Hn({recipe:e}){if(!e)return Po("div",{className:"flex flex-1 items-center justify-center rounded-2xl border border-border border-dashed",children:Po("p",{className:"text-muted-foreground text-sm",children:"Select a recipe to view details."})});return _i("article",{className:"space-y-4 rounded-2xl border border-border bg-card p-6",children:[_i("header",{className:"flex flex-wrap items-center gap-3",children:[Po(zv,{className:"h-5 w-5 text-muted-foreground"}),_i("div",{children:[Po("h2",{className:"font-semibold text-xl",children:e.name}),Po("p",{className:"text-muted-foreground text-sm",children:e.description})]})]}),_i("section",{children:[Po("h3",{className:"font-semibold text-muted-foreground text-sm uppercase tracking-wide",children:"Ingredients"}),Po("ul",{className:"mt-2 list-disc space-y-1 pl-6 text-foreground text-sm",children:e.ingredients.map((t)=>_i("li",{children:[t.name," – ",t.quantity]},t.id))})]}),_i("section",{children:[Po("h3",{className:"font-semibold text-muted-foreground text-sm uppercase tracking-wide",children:"Instructions"}),Po("ol",{className:"mt-2 list-decimal space-y-2 pl-6 text-foreground text-sm",children:e.instructions.map((t)=>Po("li",{children:t.content},t.id))})]})]})}import{gql as us}from"@apollo/client";import{useMutation as Gv,useQuery as qv}from"@apollo/client/react";import{registerTemplateComponents as Hv,useTemplateRuntime as Vv}from"@contractspec/lib.example-shared-ui";import{useState as Vn}from"react";import{jsx as zi,jsxs as ms}from"react/jsx-runtime";var Fv=us`
|
|
4835
4835
|
query Recipes($projectId: ID!, $locale: RecipeLocale!) {
|
|
4836
4836
|
recipes(projectId: $projectId, locale: $locale) {
|
|
4837
4837
|
id
|
|
@@ -4860,21 +4860,21 @@ export const PaymentFlow = defineWorkflow({
|
|
|
4860
4860
|
}
|
|
4861
4861
|
}
|
|
4862
4862
|
}
|
|
4863
|
-
`,
|
|
4863
|
+
`,Kv=us`
|
|
4864
4864
|
mutation FavoriteRecipe($id: ID!, $isFavorite: Boolean!) {
|
|
4865
4865
|
favoriteRecipe(id: $id, isFavorite: $isFavorite) {
|
|
4866
4866
|
id
|
|
4867
4867
|
isFavorite
|
|
4868
4868
|
}
|
|
4869
4869
|
}
|
|
4870
|
-
`;function
|
|
4870
|
+
`;function Qv(){let{projectId:e}=Vv(),[t,a]=Vn("EN"),[r,l]=Vn(),[b,h]=Vn(""),{data:v,loading:V}=qv(Fv,{variables:{projectId:e,locale:t},fetchPolicy:"cache-and-network"}),[g]=Gv(Kv),va=(v?.recipes??[]).filter((Ke)=>Ke.name.toLowerCase().includes(b.toLowerCase())),ye=async(Ke)=>{await g({variables:{id:Ke.id,isFavorite:!Ke.isFavorite},optimisticResponse:{favoriteRecipe:{__typename:"Recipe",id:Ke.id,isFavorite:!Ke.isFavorite}}})};return ms("div",{className:"space-y-4",children:[ms("div",{className:"flex flex-wrap items-center gap-3",children:[zi(ss,{locale:t,onChange:a}),zi("input",{type:"search",placeholder:t==="EN"?"Search recipes":"Rechercher des recettes",className:"flex-1 rounded-full border border-border bg-card px-4 py-2 text-sm",value:b,onChange:(Ke)=>h(Ke.target.value)})]}),V?zi("p",{className:"text-muted-foreground text-sm",children:"Loading recipes…"}):zi("div",{className:"grid gap-4 md:grid-cols-3",children:va.map((Ke)=>zi(ps,{recipe:Ke,onSelect:l,onToggleFavorite:ye},Ke.id))}),zi(Hn,{recipe:r})]})}Hv("recipe-app-i18n",{list:Qv,detail:Hn});import{jsx as po,jsxs as ri}from"react/jsx-runtime";function gs({value:e,onChange:t,categories:a}){let r=(l,b)=>{t({...e,[l]:b})};return ri("div",{className:"grid gap-3 rounded-2xl border border-border bg-card p-4 md:grid-cols-4",children:[ri("label",{className:"flex flex-col text-muted-foreground text-xs uppercase tracking-wide",children:["Status",ri("select",{className:"mt-1 rounded-md border border-border bg-background px-3 py-2 text-foreground text-sm",value:e.status,onChange:(l)=>r("status",l.target.value),children:[po("option",{value:"all",children:"All tasks"}),po("option",{value:"active",children:"Active"}),po("option",{value:"completed",children:"Completed"})]})]}),ri("label",{className:"flex flex-col text-muted-foreground text-xs uppercase tracking-wide",children:["Priority",ri("select",{className:"mt-1 rounded-md border border-border bg-background px-3 py-2 text-foreground text-sm",value:e.priority,onChange:(l)=>r("priority",l.target.value),children:[po("option",{value:"all",children:"All"}),po("option",{value:"LOW",children:"Low"}),po("option",{value:"MEDIUM",children:"Medium"}),po("option",{value:"HIGH",children:"High"}),po("option",{value:"URGENT",children:"Urgent"})]})]}),ri("label",{className:"flex flex-col text-muted-foreground text-xs uppercase tracking-wide",children:["Category",ri("select",{className:"mt-1 rounded-md border border-border bg-background px-3 py-2 text-foreground text-sm",value:e.categoryId,onChange:(l)=>r("categoryId",l.target.value),children:[po("option",{value:"all",children:"All categories"}),a.map((l)=>po("option",{value:l.id,children:l.name},l.id))]})]}),ri("label",{className:"flex flex-col text-muted-foreground text-xs uppercase tracking-wide",children:["Search",po("input",{type:"search",className:"mt-1 rounded-md border border-border bg-background px-3 py-2 text-foreground text-sm",placeholder:"Search by title",value:e.search,onChange:(l)=>r("search",l.target.value)})]})]})}import{gql as Yv}from"@apollo/client";import{useMutation as Jv}from"@apollo/client/react";import{useTemplateRuntime as Zv}from"@contractspec/lib.example-shared-ui";import{useState as or}from"react";import{jsx as ja,jsxs as Ho}from"react/jsx-runtime";var $v=Yv`
|
|
4871
4871
|
mutation CreateTask($input: CreateTaskInput!) {
|
|
4872
4872
|
createTask(input: $input) {
|
|
4873
4873
|
id
|
|
4874
4874
|
title
|
|
4875
4875
|
}
|
|
4876
4876
|
}
|
|
4877
|
-
`;function
|
|
4877
|
+
`;function Fn({categories:e}){let{projectId:t}=Zv(),[a,r]=or(""),[l,b]=or(""),[h,v]=or("MEDIUM"),[V,g]=or("none"),[tt,va]=or(""),[ye,{loading:Ke}]=Jv($v);return Ho("form",{onSubmit:async(Qe)=>{if(Qe.preventDefault(),!a.trim())return;await ye({variables:{input:{projectId:t,title:a.trim(),description:l.trim()||void 0,priority:h,categoryId:V==="none"?void 0:V,tags:Xv(tt)}},refetchQueries:["Tasks"],awaitRefetchQueries:!0}),r(""),b(""),v("MEDIUM"),g("none"),va("")},className:"space-y-3 rounded-2xl border border-border bg-background/60 p-4",children:[ja("div",{children:Ho("label",{className:"font-semibold text-muted-foreground text-xs uppercase",children:["Title",ja("input",{type:"text",className:"mt-1 w-full rounded-md border border-border bg-card px-3 py-2 text-sm",placeholder:"What needs to get done?",value:a,onChange:(Qe)=>r(Qe.target.value),required:!0})]})}),ja("div",{children:Ho("label",{className:"font-semibold text-muted-foreground text-xs uppercase",children:["Description",ja("textarea",{className:"mt-1 w-full rounded-md border border-border bg-card px-3 py-2 text-sm",rows:3,placeholder:"Add context or policy notes",value:l,onChange:(Qe)=>b(Qe.target.value)})]})}),Ho("div",{className:"grid gap-3 md:grid-cols-3",children:[Ho("label",{className:"font-semibold text-muted-foreground text-xs uppercase",children:["Priority",Ho("select",{className:"mt-1 w-full rounded-md border border-border bg-card px-3 py-2 text-sm",value:h,onChange:(Qe)=>v(Qe.target.value),children:[ja("option",{value:"LOW",children:"Low"}),ja("option",{value:"MEDIUM",children:"Medium"}),ja("option",{value:"HIGH",children:"High"}),ja("option",{value:"URGENT",children:"Urgent"})]})]}),Ho("label",{className:"font-semibold text-muted-foreground text-xs uppercase",children:["Category",Ho("select",{className:"mt-1 w-full rounded-md border border-border bg-card px-3 py-2 text-sm",value:V,onChange:(Qe)=>g(Qe.target.value),children:[ja("option",{value:"none",children:"None"}),e.map((Qe)=>ja("option",{value:Qe.id,children:Qe.name},Qe.id))]})]}),Ho("label",{className:"font-semibold text-muted-foreground text-xs uppercase",children:["Tags",ja("input",{className:"mt-1 w-full rounded-md border border-border bg-card px-3 py-2 text-sm",placeholder:"Comma separated (optional)",value:tt,onChange:(Qe)=>va(Qe.target.value)})]})]}),ja("button",{type:"submit",className:"btn-primary w-full py-2 font-semibold text-sm",disabled:Ke,children:Ke?"Saving...":"Add task"})]})}function Xv(e){return e.split(",").map((t)=>t.trim()).filter(Boolean)}import{Check as xv,Circle as jv,Trash2 as eN}from"lucide-react";import{jsx as To,jsxs as ir}from"react/jsx-runtime";function fs({task:e,onToggle:t,onDelete:a}){let r=e.priority==="URGENT"?"text-red-200 bg-red-500/10 border-red-500/40":e.priority==="HIGH"?"text-amber-200 bg-amber-500/10 border-amber-500/40":e.priority==="LOW"?"text-emerald-200 bg-emerald-500/10 border-emerald-500/40":"text-violet-200 bg-violet-500/10 border-violet-500/40";return ir("div",{className:"flex items-start gap-4 rounded-2xl border border-border/70 bg-card/60 p-4 transition hover:border-border",children:[To("button",{type:"button",className:"rounded-full border border-border p-2 text-muted-foreground hover:bg-muted/40","aria-pressed":e.completed,onClick:()=>t?.(e),children:e.completed?To(xv,{className:"h-4 w-4 text-emerald-400"}):To(jv,{className:"h-4 w-4"})}),ir("div",{className:"flex-1 space-y-2",children:[ir("div",{className:"flex flex-wrap items-center gap-2",children:[To("p",{className:`font-medium ${e.completed?"text-muted-foreground line-through":"text-foreground"}`,children:e.title}),To("span",{className:`rounded-full border px-2 py-0.5 text-xs ${r}`,children:e.priority.charAt(0)+e.priority.slice(1).toLowerCase()}),e.category?To("span",{className:"rounded-full bg-muted/40 px-2 py-0.5 text-muted-foreground text-xs",children:e.category.name}):null,e.dueDate?ir("span",{className:"text-muted-foreground text-xs",children:["Due ",new Date(e.dueDate).toLocaleDateString()]}):null]}),e.description?To("p",{className:"text-muted-foreground text-sm",children:e.description}):null,e.tags.length?To("div",{className:"flex flex-wrap gap-1",children:e.tags.map((l)=>ir("span",{className:"rounded-full bg-muted/40 px-2 py-0.5 text-muted-foreground text-xs",children:["#",l]},l))}):null]}),To("button",{type:"button",className:"text-muted-foreground hover:text-destructive","aria-label":`Delete ${e.title}`,onClick:()=>a?.(e),children:To(eN,{className:"h-4 w-4"})})]})}import{gql as Kn}from"@apollo/client";import{useMutation as hs,useQuery as tN}from"@apollo/client/react";import{registerTemplateComponents as aN,useTemplateRuntime as oN}from"@contractspec/lib.example-shared-ui";import{useMemo as iN,useState as rN}from"react";import{jsx as ki,jsxs as lN}from"react/jsx-runtime";var ys=Kn`
|
|
4878
4878
|
query Tasks($projectId: ID!) {
|
|
4879
4879
|
taskCategories(projectId: $projectId) {
|
|
4880
4880
|
id
|
|
@@ -4896,15 +4896,15 @@ export const PaymentFlow = defineWorkflow({
|
|
|
4896
4896
|
}
|
|
4897
4897
|
}
|
|
4898
4898
|
}
|
|
4899
|
-
`,
|
|
4899
|
+
`,nN=Kn`
|
|
4900
4900
|
mutation ToggleTask($id: ID!, $completed: Boolean!) {
|
|
4901
4901
|
toggleTask(id: $id, completed: $completed) {
|
|
4902
4902
|
id
|
|
4903
4903
|
completed
|
|
4904
4904
|
}
|
|
4905
4905
|
}
|
|
4906
|
-
`,
|
|
4906
|
+
`,cN=Kn`
|
|
4907
4907
|
mutation DeleteTask($id: ID!) {
|
|
4908
4908
|
deleteTask(id: $id)
|
|
4909
4909
|
}
|
|
4910
|
-
`;function fs(){let{projectId:e}=xv(),[t,a]=eN({status:"all",priority:"all",categoryId:"all",search:""}),{data:r,loading:l}=$v(gs,{variables:{projectId:e},fetchPolicy:"cache-and-network"}),[b]=us(tN),[h]=us(aN),v=r?.taskCategories??[],V=r?.tasks??[],g=jv(()=>{return V.filter((ye)=>{if(t.status==="active"&&ye.completed)return!1;if(t.status==="completed"&&!ye.completed)return!1;if(t.priority!=="all"&&ye.priority!==t.priority)return!1;if(t.categoryId!=="all"&&ye.category?.id!==t.categoryId)return!1;if(t.search&&!ye.title.toLowerCase().includes(t.search.toLowerCase()))return!1;return!0})},[V,t]),tt=async(ye)=>{await b({variables:{id:ye.id,completed:!ye.completed},optimisticResponse:{toggleTask:{__typename:"Task",id:ye.id,completed:!ye.completed}},update(Ke){Ke.modify({fields:{tasks(Gi=[]){return Gi.map((Qe)=>Qe.__ref?.endsWith(ye.id)?{...Qe,completed:!ye.completed}:Qe)}}})}})},va=async(ye)=>{await h({variables:{id:ye.id},refetchQueries:[{query:gs,variables:{projectId:e}}]})};return oN("div",{className:"space-y-6",children:[ki(ps,{value:t,onChange:a,categories:v}),ki(Hn,{categories:v}),l?ki("p",{className:"text-muted-foreground text-sm",children:"Loading tasks…"}):g.length?ki("div",{className:"space-y-3",children:g.map((ye)=>ki(ms,{task:ye,onToggle:tt,onDelete:va},ye.id))}):ki("div",{className:"rounded-2xl border border-border border-dashed p-8 text-center",children:ki("p",{className:"text-muted-foreground",children:"No tasks match your filters. Create one above."})})]})}Xv("todos-app",{list:fs,detail:fs,form:Hn});var Fn={appNameKey:"ContractSpec",assets:[{type:"logo",url:"/logo.svg",dimensions:{width:180,height:40}},{type:"logo-dark",url:"/logo-dark.svg",dimensions:{width:180,height:40}},{type:"favicon",url:"/favicon.ico",dimensions:{width:32,height:32}},{type:"og-image",url:"/og-image.png",dimensions:{width:1200,height:630}}],colorTokens:{primary:"#0ea5e9",secondary:"#6366f1"}},iN={appName:"ContractSpec",assets:{logo:"/logo.svg",logoDark:"/logo-dark.svg",favicon:"/favicon.ico",ogImage:"/og-image.png"},colors:{primary:"#0ea5e9",secondary:"#6366f1"},domain:"contractspec.io"};var Kn=[{path:"/",label:"Home"},{path:"/product",label:"Product"},{path:"/pricing",label:"Pricing"},{path:"/changelog",label:"Changelog"},{path:"/contact",label:"Contact"},{path:"/docs",label:"Documentation"},{path:"/docs/getting-started",label:"Getting Started"},{path:"/docs/architecture",label:"Architecture"},{path:"/docs/specs",label:"Specs"},{path:"/docs/integrations",label:"Integrations"},{path:"/docs/libraries",label:"Libraries"},{path:"/docs/advanced",label:"Advanced"},{path:"/features",label:"Feature Discovery",featureFlag:"feature-discovery-ui"},{path:"/sandbox",label:"Sandbox",featureFlag:"sandbox-enabled"}];var Ur=(e,t)=>({key:e,version:t}),Wr=(e)=>({key:e}),rN={meta:{key:"contractspec.app",version:"1.0.0",appId:"contractspec",title:"ContractSpec",description:"The deterministic, spec-first compiler for AI-coded systems",domain:"platform",owners:["@platform.core"],tags:["contracts","specs","ai-safety","code-generation"],stability:"beta"},capabilities:{enabled:[Ur("contracts.operations","1.0.0"),Ur("contracts.presentations","1.0.0"),Ur("contracts.mcp","1.0.0"),Ur("contracts.docs","1.0.0")]},features:{include:[Wr("contractspec.docs"),Wr("contractspec.mcp"),Wr("contractspec.presentations"),Wr("app-config")]},branding:Fn,featureFlags:[{key:"feature-discovery-ui",enabled:!0,description:"Show feature discovery UI"},{key:"dark-mode",enabled:!0,description:"Enable dark mode theming"},{key:"ai-assistant",enabled:!1,description:"AI-powered assistant integration"},{key:"sandbox-enabled",enabled:!0,description:"Enable sandbox playground"}],routes:Kn,notes:"ContractSpec platform blueprint - defines the app's capabilities, features, and configuration."};var Qn={meta:{key:"contractspec.docs",version:"1.0.0",title:"Documentation",description:"Comprehensive documentation system for ContractSpec",domain:"platform",owners:["@platform.docs"],tags:["documentation","guides","api-reference"],stability:"stable"},operations:[{key:"docs_search",version:"1.0.0"},{key:"docs.navigate",version:"1.0.0"}],events:[{key:"docs.page_viewed",version:"1.0.0"},{key:"docs.search_performed",version:"1.0.0"}],presentations:[{key:"docs.landing",version:"1.0.0"},{key:"docs.getting-started",version:"1.0.0"},{key:"docs.architecture",version:"1.0.0"}],capabilities:{provides:[{key:"contracts.docs",version:"1.0.0"}],requires:[]}};import{ContractReferenceQuery as nN,DocSummaryModel as cN,DocsIndexInput as lN,DocsIndexOutput as dN,DocsIndexQuery as sN,DocsIndexQuery as pN}from"@contractspec/lib.contracts-spec/docs";var Yn={meta:{key:"contractspec.mcp",version:"1.0.0",title:"MCP Integration",description:"Model Context Protocol server for AI agent integration",domain:"platform",owners:["@platform.mcp"],tags:["mcp","ai-agents","tooling"],stability:"beta"},operations:[{key:"mcp.tool.register",version:"1.0.0"},{key:"mcp.resource.register",version:"1.0.0"},{key:"mcp.prompt.register",version:"1.0.0"}],events:[{key:"mcp.tool_invoked",version:"1.0.0"},{key:"mcp.resource_accessed",version:"1.0.0"}],presentations:[],capabilities:{provides:[{key:"contracts.mcp",version:"1.0.0"}],requires:[{key:"contracts.operations",version:"1.0.0"}]}};var Jn={meta:{key:"contractspec.presentations",version:"1.0.0",title:"Presentation Runtime",description:"Cross-platform rendering of contract-driven UI",domain:"platform",owners:["@platform.presentations"],tags:["presentations","ui","rendering","cross-platform"],stability:"beta"},operations:[{key:"presentation.render",version:"1.0.0"},{key:"presentation.transform",version:"1.0.0"}],events:[{key:"presentation.rendered",version:"1.0.0"},{key:"presentation.transformed",version:"1.0.0"}],presentations:[{key:"form.standard",version:"1.0.0"},{key:"list.standard",version:"1.0.0"},{key:"detail.standard",version:"1.0.0"}],capabilities:{provides:[{key:"contracts.presentations",version:"1.0.0"}],requires:[]}};import{AppConfigFeature as mN}from"@contractspec/lib.contracts-spec/app-config";import{FeatureRegistry as uN}from"@contractspec/lib.contracts-spec/features";function hs(){let e=new uN;return e.register(Qn),e.register(Yn),e.register(Jn),e.register(mN),e}var _r=null;function gN(){if(!_r)_r=hs();return _r}function fN(){_r=null}import{FeatureRegistry as YO}from"@contractspec/lib.contracts-spec/features";export{Qs as resolveSerializedPresentationSpec,Fs as resolveSerializedOperationSpec,Js as resolveSerializedFormSpec,Ks as resolveSerializedEventSpec,Ys as resolveSerializedDataViewSpec,oc as resolvePresentationSpec,Xn as resolveOperationSpec,dc as resolveFormSpec,ec as resolveEventSpec,nc as resolveDataViewSpec,mc as resetContractSpecPresentationRegistry,sc as resetContractSpecOperationRegistry,gc as resetContractSpecFormRegistry,fN as resetContractSpecFeatureRegistry,pc as resetContractSpecEventRegistry,uc as resetContractSpecDataViewRegistry,Zs as resetAllContractSpecRegistries,Wc as listGeneratedDocs,fc as getSecondaryDocsPages,xs as getPrimaryDocsTraversal,Xs as getPrimaryDocsSections,h2 as getGeneratedDocById,TN as getDocsPageByHref,AN as getDocsNextPrevious,f2 as getDocsIndexManifest,hc as getDocsHomeSections,ac as getContractSpecPresentationRegistry,$n as getContractSpecOperationRegistry,lc as getContractSpecFormRegistry,gN as getContractSpecFeatureRegistry,jn as getContractSpecEventRegistry,rc as getContractSpecDataViewRegistry,sN as docsSearchSpec,tc as createContractSpecPresentationRegistry,Zn as createContractSpecOperationRegistry,cc as createContractSpecFormRegistry,hs as createContractSpecFeatureRegistry,xn as createContractSpecEventRegistry,ic as createContractSpecDataViewRegistry,Kn as contractspecRoutes,iN as contractspecResolvedBranding,Fn as contractspecBrandingDefaults,rN as contractspecBlueprint,Br as WorkspaceSidebar,zD as WorkspaceShellRenderer,ED as WorkspaceProjectShellLayout,Er as WorkspaceHeader,cS as VSCodeExtensionPage,Fm as TroubleshootingPage,Kb as TermsTemplate,fs as TaskList,ms as TaskItem,Hn as TaskForm,Ib as StudioVisualBuilderPage,Sb as StudioOverviewPage,Nb as StudioIntegrationsPage,yb as StudioGettingStartedPage,gb as StudioDeploymentsPage,pb as StudioBYOKPage,qm as StartHerePage,db as SpecsWorkflowsPage,cb as SpecsPolicyPage,rb as SpecsOverviewPage,ab as SpecsOverlaysPage,eb as SpecsModuleBundlesPage,Xy as SpecsDataViewsPage,Jy as SpecsConnectPage,Hy as SpecsCapabilitiesPage,zy as SpecsBuilderControlPlanePage,Gg as SpecDrivenDevelopmentPage,Wg as SchemaValidationTypescriptPage,My as SafetyTenantIsolationPage,By as SafetySigningPage,Dy as SafetySecurityTrustPage,Ly as SafetyPDPPage,Ay as SafetyOverviewPage,Iy as SafetyMigrationsPage,Sy as SafetyAuditingPage,qv as RecipeList,Gn as RecipeDetail,ls as RecipeCard,Fb as PrivacyTemplate,Jn as PresentationsFeature,Kh as OpsDistributedTracingPage,Fh as OpsAutoEvolutionPage,Bg as OpenapiAlternativePage,Ev as MessagingWorkspace,Wn as MessageThread,_n as MessageComposer,Vh as ManifestoPage,Un as MESSAGES_QUERY,Yn as MCPFeature,IN as LibraryBundle,Hh as LibrariesWorkflowsPage,_h as LibrariesWorkflowComposerPage,Mh as LibrariesUIKitWebPage,Lh as LibrariesUIKitPage,Ih as LibrariesTestingPage,kh as LibrariesSupportBotPage,hh as LibrariesSchemaPage,vh as LibrariesSLOPage,uh as LibrariesRuntimePage,dh as LibrariesResiliencePage,nh as LibrariesProgressiveDeliveryPage,oh as LibrariesPersonalizationPage,eh as LibrariesOverviewPage,$f as LibrariesOverlayEnginePage,Yf as LibrariesObservabilityPage,Ff as LibrariesMultiTenancyPage,qf as LibrariesGrowthPage,_f as LibrariesGraphQLPage,Bf as LibrariesEvolutionPage,Df as LibrariesDesignSystemPage,If as LibrariesDataViewsPage,kf as LibrariesDataBackendPage,vf as LibrariesCrossPlatformUIPage,yf as LibrariesCostTrackingPage,gf as LibrariesContractsPage,df as LibrariesContentGenPage,rf as LibrariesAnalyticsPage,af as LibrariesAiAgentPage,jg as LibrariesAccessibilityPage,cs as LanguageSwitcher,$g as KnowledgeSpacesPage,Jg as KnowledgeSourcesPage,xL as KnowledgeSourceList,Qg as KnowledgeOverviewPage,Vg as KnowledgeExamplesPage,Hg as KnowledgeCategoriesPage,kg as IntegrationsWhatsappTwilioPage,Ng as IntegrationsWhatsappMetaPage,bg as IntegrationsTwilioPage,yg as IntegrationsStripePage,fg as IntegrationsSpecModelPage,ug as IntegrationsSlackPage,pg as IntegrationsS3Page,dg as IntegrationsResendPage,cg as IntegrationsQdrantPage,rg as IntegrationsPowensPage,og as IntegrationsPostmarkPage,tg as IntegrationsOverviewPage,ju as IntegrationsOpenAIPage,Xu as IntegrationsMistralPage,Zu as IntegrationsHealthRoutingPage,Ju as IntegrationsGoogleCalendarPage,Qu as IntegrationsGmailPage,Fu as IntegrationsGithubPage,Hu as IntegrationsElevenLabsPage,Gu as IntegrationsCircuitBreakersPage,JL as IntegrationSettings,GL as IntegrationMarketplace,qd as IntegrationCard,_m as InstallationPage,Mm as HelloWorldPage,Wu as GuidesIndexPage,Lu as GuideSpecValidationTypingPage,Au as GuideReleaseCapsulesPage,Iu as GuideNextjsOneEndpointPage,Su as GuideImportExistingCodebasesPage,yu as GuideHostBuilderWorkbenchPage,uu as GuideGenerateDocsClientsSchemasPage,pu as GuideFirstModuleBundlePage,du as GuideDocsPipelinePage,cu as GuideContractTypesPage,eu as GuideConnectInRepoPage,Xm as GuideCIDiffGatingPage,Dg as GenerateClientFromSchemaPage,ps as FilterBar,YO as FeatureRegistry,hD as FeatureGateNotice,sm as ExampleShowcasePage,qp as EcosystemTemplatesPage,Wp as EcosystemRegistryPage,Mp as EcosystemPluginsPage,Op as EcosystemIntegrationsPage,Ny as DocsReferencePage,ay as DocsReferenceIndexPage,pN as DocsIndexQuery,rp as DocsIndexPage,Qn as DocsFeature,$p as DocsExamplesPage,cN as DocSummaryModel,dN as DocSearchOutput,lN as DocSearchInput,M2 as DeveloperToolsPage,Ag as DeterministicCodegenPage,Pm as DataViewTutorialPage,zr as DOCS_PRIMARY_SECTIONS,sr as DOCS_PAGES,jd as ConversationList,nN as ContractReferenceQuery,Ig as ContractFirstApiPage,Sm as CompatibilityPage,Lp as ComparisonWorkflowEnginesPage,Rp as ComparisonWindmillPage,Ap as ComparisonOverviewPage,Tp as ComparisonInternalToolBuildersPage,Pp as ComparisonEnterprisePlatformsPage,Cp as ComparisonAutomationPlatformsPage,wm as CLIPage,Sp as ArchitectureOverviewPage,wp as ArchitectureMultiTenancyPage,bp as ArchitectureKnowledgeBindingPage,hp as ArchitectureIntegrationBindingPage,gp as ArchitectureControlPlanePage,mp as ArchitectureAppConfigPage,iw as AdvancedWorkflowMonitoringPage,tw as AdvancedTelemetryPage,$N as AdvancedSpecExperimentsPage,YN as AdvancedRenderersPage,HN as AdvancedOverlayEditorPage,_N as AdvancedMCPPage};
|
|
4910
|
+
`;function bs(){let{projectId:e}=oN(),[t,a]=rN({status:"all",priority:"all",categoryId:"all",search:""}),{data:r,loading:l}=tN(ys,{variables:{projectId:e},fetchPolicy:"cache-and-network"}),[b]=hs(nN),[h]=hs(cN),v=r?.taskCategories??[],V=r?.tasks??[],g=iN(()=>{return V.filter((ye)=>{if(t.status==="active"&&ye.completed)return!1;if(t.status==="completed"&&!ye.completed)return!1;if(t.priority!=="all"&&ye.priority!==t.priority)return!1;if(t.categoryId!=="all"&&ye.category?.id!==t.categoryId)return!1;if(t.search&&!ye.title.toLowerCase().includes(t.search.toLowerCase()))return!1;return!0})},[V,t]),tt=async(ye)=>{await b({variables:{id:ye.id,completed:!ye.completed},optimisticResponse:{toggleTask:{__typename:"Task",id:ye.id,completed:!ye.completed}},update(Ke){Ke.modify({fields:{tasks(Gi=[]){return Gi.map((Qe)=>Qe.__ref?.endsWith(ye.id)?{...Qe,completed:!ye.completed}:Qe)}}})}})},va=async(ye)=>{await h({variables:{id:ye.id},refetchQueries:[{query:ys,variables:{projectId:e}}]})};return lN("div",{className:"space-y-6",children:[ki(gs,{value:t,onChange:a,categories:v}),ki(Fn,{categories:v}),l?ki("p",{className:"text-muted-foreground text-sm",children:"Loading tasks…"}):g.length?ki("div",{className:"space-y-3",children:g.map((ye)=>ki(fs,{task:ye,onToggle:tt,onDelete:va},ye.id))}):ki("div",{className:"rounded-2xl border border-border border-dashed p-8 text-center",children:ki("p",{className:"text-muted-foreground",children:"No tasks match your filters. Create one above."})})]})}aN("todos-app",{list:bs,detail:bs,form:Fn});var Qn={appNameKey:"ContractSpec",assets:[{type:"logo",url:"/logo.svg",dimensions:{width:180,height:40}},{type:"logo-dark",url:"/logo-dark.svg",dimensions:{width:180,height:40}},{type:"favicon",url:"/favicon.ico",dimensions:{width:32,height:32}},{type:"og-image",url:"/og-image.png",dimensions:{width:1200,height:630}}],colorTokens:{primary:"#0ea5e9",secondary:"#6366f1"}},dN={appName:"ContractSpec",assets:{logo:"/logo.svg",logoDark:"/logo-dark.svg",favicon:"/favicon.ico",ogImage:"/og-image.png"},colors:{primary:"#0ea5e9",secondary:"#6366f1"},domain:"contractspec.io"};var Yn=[{path:"/",label:"Home"},{path:"/product",label:"Product"},{path:"/pricing",label:"Pricing"},{path:"/changelog",label:"Changelog"},{path:"/contact",label:"Contact"},{path:"/docs",label:"Documentation"},{path:"/docs/getting-started",label:"Getting Started"},{path:"/docs/architecture",label:"Architecture"},{path:"/docs/specs",label:"Specs"},{path:"/docs/integrations",label:"Integrations"},{path:"/docs/libraries",label:"Libraries"},{path:"/docs/advanced",label:"Advanced"},{path:"/features",label:"Feature Discovery",featureFlag:"feature-discovery-ui"},{path:"/sandbox",label:"Sandbox",featureFlag:"sandbox-enabled"}];var Ur=(e,t)=>({key:e,version:t}),Wr=(e)=>({key:e}),sN={meta:{key:"contractspec.app",version:"1.0.0",appId:"contractspec",title:"ContractSpec",description:"The deterministic, spec-first compiler for AI-coded systems",domain:"platform",owners:["@platform.core"],tags:["contracts","specs","ai-safety","code-generation"],stability:"beta"},capabilities:{enabled:[Ur("contracts.operations","1.0.0"),Ur("contracts.presentations","1.0.0"),Ur("contracts.mcp","1.0.0"),Ur("contracts.docs","1.0.0")]},features:{include:[Wr("contractspec.docs"),Wr("contractspec.mcp"),Wr("contractspec.presentations"),Wr("app-config")]},branding:Qn,featureFlags:[{key:"feature-discovery-ui",enabled:!0,description:"Show feature discovery UI"},{key:"dark-mode",enabled:!0,description:"Enable dark mode theming"},{key:"ai-assistant",enabled:!1,description:"AI-powered assistant integration"},{key:"sandbox-enabled",enabled:!0,description:"Enable sandbox playground"}],routes:Yn,notes:"ContractSpec platform blueprint - defines the app's capabilities, features, and configuration."};var Jn={meta:{key:"contractspec.docs",version:"1.0.0",title:"Documentation",description:"Comprehensive documentation system for ContractSpec",domain:"platform",owners:["@platform.docs"],tags:["documentation","guides","api-reference"],stability:"stable"},operations:[{key:"docs_search",version:"1.0.0"},{key:"docs.navigate",version:"1.0.0"}],events:[{key:"docs.page_viewed",version:"1.0.0"},{key:"docs.search_performed",version:"1.0.0"}],presentations:[{key:"docs.landing",version:"1.0.0"},{key:"docs.getting-started",version:"1.0.0"},{key:"docs.architecture",version:"1.0.0"}],capabilities:{provides:[{key:"contracts.docs",version:"1.0.0"}],requires:[]}};import{ContractReferenceQuery as pN,DocSummaryModel as mN,DocsIndexInput as uN,DocsIndexOutput as gN,DocsIndexQuery as fN,DocsIndexQuery as hN}from"@contractspec/lib.contracts-spec/docs";var Zn={meta:{key:"contractspec.mcp",version:"1.0.0",title:"MCP Integration",description:"Model Context Protocol server for AI agent integration",domain:"platform",owners:["@platform.mcp"],tags:["mcp","ai-agents","tooling"],stability:"beta"},operations:[{key:"mcp.tool.register",version:"1.0.0"},{key:"mcp.resource.register",version:"1.0.0"},{key:"mcp.prompt.register",version:"1.0.0"}],events:[{key:"mcp.tool_invoked",version:"1.0.0"},{key:"mcp.resource_accessed",version:"1.0.0"}],presentations:[],capabilities:{provides:[{key:"contracts.mcp",version:"1.0.0"}],requires:[{key:"contracts.operations",version:"1.0.0"}]}};var $n={meta:{key:"contractspec.presentations",version:"1.0.0",title:"Presentation Runtime",description:"Cross-platform rendering of contract-driven UI",domain:"platform",owners:["@platform.presentations"],tags:["presentations","ui","rendering","cross-platform"],stability:"beta"},operations:[{key:"presentation.render",version:"1.0.0"},{key:"presentation.transform",version:"1.0.0"}],events:[{key:"presentation.rendered",version:"1.0.0"},{key:"presentation.transformed",version:"1.0.0"}],presentations:[{key:"form.standard",version:"1.0.0"},{key:"list.standard",version:"1.0.0"},{key:"detail.standard",version:"1.0.0"}],capabilities:{provides:[{key:"contracts.presentations",version:"1.0.0"}],requires:[]}};import{AppConfigFeature as yN}from"@contractspec/lib.contracts-spec/app-config";import{FeatureRegistry as bN}from"@contractspec/lib.contracts-spec/features";function vs(){let e=new bN;return e.register(Jn),e.register(Zn),e.register($n),e.register(yN),e}var _r=null;function vN(){if(!_r)_r=vs();return _r}function NN(){_r=null}import{FeatureRegistry as jO}from"@contractspec/lib.contracts-spec/features";export{Zs as resolveSerializedPresentationSpec,Ys as resolveSerializedOperationSpec,Xs as resolveSerializedFormSpec,Js as resolveSerializedEventSpec,$s as resolveSerializedDataViewSpec,rc as resolvePresentationSpec,jn as resolveOperationSpec,pc as resolveFormSpec,ac as resolveEventSpec,lc as resolveDataViewSpec,gc as resetContractSpecPresentationRegistry,mc as resetContractSpecOperationRegistry,hc as resetContractSpecFormRegistry,NN as resetContractSpecFeatureRegistry,uc as resetContractSpecEventRegistry,fc as resetContractSpecDataViewRegistry,xs as resetAllContractSpecRegistries,Gc as listGeneratedDocs,yc as getSecondaryDocsPages,tp as getPrimaryDocsTraversal,ep as getPrimaryDocsSections,k2 as getGeneratedDocById,EN as getDocsPageByHref,ON as getDocsNextPrevious,w2 as getDocsIndexManifest,bc as getDocsHomeSections,ic as getContractSpecPresentationRegistry,xn as getContractSpecOperationRegistry,sc as getContractSpecFormRegistry,vN as getContractSpecFeatureRegistry,tc as getContractSpecEventRegistry,cc as getContractSpecDataViewRegistry,fN as docsSearchSpec,oc as createContractSpecPresentationRegistry,Xn as createContractSpecOperationRegistry,dc as createContractSpecFormRegistry,vs as createContractSpecFeatureRegistry,ec as createContractSpecEventRegistry,nc as createContractSpecDataViewRegistry,Yn as contractspecRoutes,dN as contractspecResolvedBranding,Qn as contractspecBrandingDefaults,sN as contractspecBlueprint,Br as WorkspaceSidebar,KD as WorkspaceShellRenderer,_D as WorkspaceProjectShellLayout,Er as WorkspaceHeader,uS as VSCodeExtensionPage,Zm as TroubleshootingPage,$b as TermsTemplate,bs as TaskList,fs as TaskItem,Fn as TaskForm,Lb as StudioVisualBuilderPage,Ab as StudioOverviewPage,Ib as StudioIntegrationsPage,kb as StudioGettingStartedPage,vb as StudioDeploymentsPage,hb as StudioBYOKPage,Qm as StartHerePage,gb as SpecsWorkflowsPage,mb as SpecsPolicyPage,sb as SpecsOverviewPage,cb as SpecsOverlaysPage,rb as SpecsModuleBundlesPage,ab as SpecsDataViewsPage,jy as SpecsConnectPage,Yy as SpecsCapabilitiesPage,Fy as SpecsBuilderControlPlanePage,Kg as SpecDrivenDevelopmentPage,Hg as SchemaValidationTypescriptPage,Gy as SafetyTenantIsolationPage,zy as SafetySigningPage,Uy as SafetySecurityTrustPage,My as SafetyPDPPage,Oy as SafetyOverviewPage,Ly as SafetyMigrationsPage,Ay as SafetyAuditingPage,Qv as RecipeList,Hn as RecipeDetail,ps as RecipeCard,Zb as PrivacyTemplate,$n as PresentationsFeature,$h as OpsDistributedTracingPage,Zh as OpsAutoEvolutionPage,zg as OpenapiAlternativePage,Wv as MessagingWorkspace,zn as MessageThread,Gn as MessageComposer,Jh as ManifestoPage,_n as MESSAGES_QUERY,Zn as MCPFeature,LN as LibraryBundle,Yh as LibrariesWorkflowsPage,Vh as LibrariesWorkflowComposerPage,Gh as LibrariesUIKitWebPage,Mh as LibrariesUIKitPage,Lh as LibrariesTestingPage,Th as LibrariesSupportBotPage,wh as LibrariesSchemaPage,Ch as LibrariesSLOPage,bh as LibrariesRuntimePage,gh as LibrariesResiliencePage,ph as LibrariesProgressiveDeliveryPage,lh as LibrariesPersonalizationPage,rh as LibrariesOverviewPage,th as LibrariesOverlayEnginePage,xf as LibrariesObservabilityPage,Zf as LibrariesMultiTenancyPage,Qf as LibrariesGrowthPage,Vf as LibrariesGraphQLPage,zf as LibrariesEvolutionPage,Uf as LibrariesDesignSystemPage,Lf as LibrariesDataViewsPage,Tf as LibrariesDataBackendPage,Cf as LibrariesCrossPlatformUIPage,kf as LibrariesCostTrackingPage,vf as LibrariesContractsPage,gf as LibrariesContentGenPage,sf as LibrariesAnalyticsPage,lf as LibrariesAiAgentPage,rf as LibrariesAccessibilityPage,ss as LanguageSwitcher,tf as KnowledgeSpacesPage,jg as KnowledgeSourcesPage,iD as KnowledgeSourceList,Xg as KnowledgeOverviewPage,Jg as KnowledgeExamplesPage,Yg as KnowledgeCategoriesPage,Tg as IntegrationsWhatsappTwilioPage,Ig as IntegrationsWhatsappMetaPage,Sg as IntegrationsTwilioPage,kg as IntegrationsStripePage,Ng as IntegrationsSpecModelPage,bg as IntegrationsSlackPage,hg as IntegrationsS3Page,gg as IntegrationsResendPage,mg as IntegrationsQdrantPage,sg as IntegrationsPowensPage,lg as IntegrationsPostmarkPage,ng as IntegrationsOverviewPage,ig as IntegrationsOpenAIPage,ag as IntegrationsMistralPage,eg as IntegrationsHealthRoutingPage,ju as IntegrationsGoogleCalendarPage,Xu as IntegrationsGmailPage,Zu as IntegrationsGithubPage,Yu as IntegrationsElevenLabsPage,Ku as IntegrationsCircuitBreakersPage,eD as IntegrationSettings,QL as IntegrationMarketplace,Fd as IntegrationCard,Vm as InstallationPage,Gm as HelloWorldPage,Hu as GuidesIndexPage,Mu as GuideSpecValidationTypingPage,Ou as GuideReleaseCapsulesPage,Lu as GuideNextjsOneEndpointPage,Au as GuideImportExistingCodebasesPage,ku as GuideHostBuilderWorkbenchPage,bu as GuideGenerateDocsClientsSchemasPage,hu as GuideFirstModuleBundlePage,gu as GuideDocsPipelinePage,mu as GuideContractTypesPage,ru as GuideConnectInRepoPage,au as GuideCIDiffGatingPage,Ug as GenerateClientFromSchemaPage,gs as FilterBar,jO as FeatureRegistry,kD as FeatureGateNotice,fm as ExampleShowcasePage,Qp as EcosystemTemplatesPage,Hp as EcosystemRegistryPage,Gp as EcosystemPluginsPage,_p as EcosystemIntegrationsPage,Iy as DocsReferencePage,cy as DocsReferenceIndexPage,hN as DocsIndexQuery,lp as DocsIndexPage,Jn as DocsFeature,tm as DocsExamplesPage,mN as DocSummaryModel,gN as DocSearchOutput,uN as DocSearchInput,q2 as DeveloperToolsPage,Og as DeterministicCodegenPage,Dm as DataViewTutorialPage,zr as DOCS_PRIMARY_SECTIONS,sr as DOCS_PAGES,as as ConversationList,pN as ContractReferenceQuery,Lg as ContractFirstApiPage,Am as CompatibilityPage,Mp as ComparisonWorkflowEnginesPage,Bp as ComparisonWindmillPage,Op as ComparisonOverviewPage,Ep as ComparisonInternalToolBuildersPage,Dp as ComparisonEnterprisePlatformsPage,Rp as ComparisonAutomationPlatformsPage,Pm as CLIPage,Ap as ArchitectureOverviewPage,Pp as ArchitectureMultiTenancyPage,Sp as ArchitectureKnowledgeBindingPage,wp as ArchitectureIntegrationBindingPage,vp as ArchitectureControlPlanePage,yp as ArchitectureAppConfigPage,sw as AdvancedWorkflowMonitoringPage,cw as AdvancedTelemetryPage,aw as AdvancedSpecExperimentsPage,xN as AdvancedRenderersPage,YN as AdvancedOverlayEditorPage,VN as AdvancedMCPPage};
|