@lssm/lib.contracts 1.7.3 → 1.9.0

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.
Files changed (261) hide show
  1. package/README.md +62 -325
  2. package/dist/app-config/contracts.d.ts +51 -49
  3. package/dist/app-config/contracts.d.ts.map +1 -1
  4. package/dist/app-config/contracts.js +1 -1
  5. package/dist/app-config/contracts.js.map +1 -1
  6. package/dist/app-config/events.d.ts +28 -26
  7. package/dist/app-config/events.d.ts.map +1 -1
  8. package/dist/app-config/events.js +1 -1
  9. package/dist/app-config/events.js.map +1 -1
  10. package/dist/app-config/lifecycle-contracts.d.ts +81 -79
  11. package/dist/app-config/lifecycle-contracts.d.ts.map +1 -1
  12. package/dist/app-config/lifecycle-contracts.js +1 -1
  13. package/dist/app-config/lifecycle-contracts.js.map +1 -1
  14. package/dist/app-config/runtime.d.ts.map +1 -1
  15. package/dist/app-config/runtime.js.map +1 -1
  16. package/dist/app-config/spec.d.ts +2 -2
  17. package/dist/app-config/spec.d.ts.map +1 -1
  18. package/dist/app-config/spec.js.map +1 -1
  19. package/dist/app-config/validation.d.ts.map +1 -1
  20. package/dist/app-config/validation.js.map +1 -1
  21. package/dist/capabilities/openbanking.d.ts.map +1 -1
  22. package/dist/capabilities/openbanking.js.map +1 -1
  23. package/dist/capabilities.d.ts +2 -1
  24. package/dist/capabilities.d.ts.map +1 -1
  25. package/dist/capabilities.js +1 -1
  26. package/dist/capabilities.js.map +1 -1
  27. package/dist/client/react/form-render.d.ts +1 -0
  28. package/dist/client/react/form-render.d.ts.map +1 -1
  29. package/dist/contracts-adapter-input.d.ts +1 -0
  30. package/dist/contracts-adapter-input.d.ts.map +1 -1
  31. package/dist/data-views/query-generator.d.ts +40 -0
  32. package/dist/data-views/query-generator.d.ts.map +1 -0
  33. package/dist/data-views/query-generator.js +2 -0
  34. package/dist/data-views/query-generator.js.map +1 -0
  35. package/dist/data-views/runtime.d.ts +27 -0
  36. package/dist/data-views/runtime.d.ts.map +1 -0
  37. package/dist/data-views/runtime.js +2 -0
  38. package/dist/data-views/runtime.js.map +1 -0
  39. package/dist/data-views.js.map +1 -1
  40. package/dist/events.d.ts +1 -0
  41. package/dist/events.d.ts.map +1 -1
  42. package/dist/events.js +1 -1
  43. package/dist/events.js.map +1 -1
  44. package/dist/experiments/evaluator.d.ts.map +1 -1
  45. package/dist/experiments/evaluator.js.map +1 -1
  46. package/dist/experiments/spec-resolver.d.ts +17 -0
  47. package/dist/experiments/spec-resolver.d.ts.map +1 -0
  48. package/dist/experiments/spec-resolver.js +0 -0
  49. package/dist/experiments/spec.js.map +1 -1
  50. package/dist/forms.d.ts +1 -0
  51. package/dist/forms.d.ts.map +1 -1
  52. package/dist/graphql-federation/dist/index.js +2 -0
  53. package/dist/graphql-federation/dist/index.js.map +1 -0
  54. package/dist/index.d.ts +4 -3
  55. package/dist/index.js +1 -1
  56. package/dist/install.d.ts +1 -0
  57. package/dist/install.d.ts.map +1 -1
  58. package/dist/integrations/connection.d.ts.map +1 -1
  59. package/dist/integrations/contracts.d.ts +103 -101
  60. package/dist/integrations/contracts.d.ts.map +1 -1
  61. package/dist/integrations/contracts.js +1 -1
  62. package/dist/integrations/contracts.js.map +1 -1
  63. package/dist/integrations/health.d.ts.map +1 -1
  64. package/dist/integrations/health.js.map +1 -1
  65. package/dist/integrations/openbanking/contracts/accounts.d.ts +67 -65
  66. package/dist/integrations/openbanking/contracts/accounts.d.ts.map +1 -1
  67. package/dist/integrations/openbanking/contracts/accounts.js +1 -1
  68. package/dist/integrations/openbanking/contracts/accounts.js.map +1 -1
  69. package/dist/integrations/openbanking/contracts/balances.d.ts +35 -33
  70. package/dist/integrations/openbanking/contracts/balances.d.ts.map +1 -1
  71. package/dist/integrations/openbanking/contracts/balances.js +1 -1
  72. package/dist/integrations/openbanking/contracts/balances.js.map +1 -1
  73. package/dist/integrations/openbanking/contracts/index.js.map +1 -1
  74. package/dist/integrations/openbanking/contracts/transactions.d.ts +49 -47
  75. package/dist/integrations/openbanking/contracts/transactions.d.ts.map +1 -1
  76. package/dist/integrations/openbanking/contracts/transactions.js +1 -1
  77. package/dist/integrations/openbanking/contracts/transactions.js.map +1 -1
  78. package/dist/integrations/openbanking/guards.js.map +1 -1
  79. package/dist/integrations/openbanking/models.d.ts +57 -54
  80. package/dist/integrations/openbanking/models.d.ts.map +1 -1
  81. package/dist/integrations/openbanking/models.js +1 -1
  82. package/dist/integrations/openbanking/models.js.map +1 -1
  83. package/dist/integrations/openbanking/telemetry.js.map +1 -1
  84. package/dist/integrations/providers/elevenlabs.d.ts.map +1 -1
  85. package/dist/integrations/providers/elevenlabs.js.map +1 -1
  86. package/dist/integrations/providers/gcs-storage.js.map +1 -1
  87. package/dist/integrations/providers/gmail.d.ts.map +1 -1
  88. package/dist/integrations/providers/gmail.js.map +1 -1
  89. package/dist/integrations/providers/google-calendar.js.map +1 -1
  90. package/dist/integrations/providers/impls/elevenlabs-voice.js.map +1 -1
  91. package/dist/integrations/providers/impls/gcs-storage.js.map +1 -1
  92. package/dist/integrations/providers/impls/gmail-inbound.js.map +1 -1
  93. package/dist/integrations/providers/impls/gmail-outbound.d.ts.map +1 -1
  94. package/dist/integrations/providers/impls/gmail-outbound.js.map +1 -1
  95. package/dist/integrations/providers/impls/google-calendar.d.ts.map +1 -1
  96. package/dist/integrations/providers/impls/google-calendar.js.map +1 -1
  97. package/dist/integrations/providers/impls/mistral-embedding.js.map +1 -1
  98. package/dist/integrations/providers/impls/mistral-llm.js.map +1 -1
  99. package/dist/integrations/providers/impls/postmark-email.js.map +1 -1
  100. package/dist/integrations/providers/impls/powens-client.d.ts.map +1 -1
  101. package/dist/integrations/providers/impls/powens-client.js.map +1 -1
  102. package/dist/integrations/providers/impls/powens-openbanking.d.ts.map +1 -1
  103. package/dist/integrations/providers/impls/powens-openbanking.js.map +1 -1
  104. package/dist/integrations/providers/impls/provider-factory.d.ts.map +1 -1
  105. package/dist/integrations/providers/impls/provider-factory.js.map +1 -1
  106. package/dist/integrations/providers/impls/qdrant-vector.d.ts.map +1 -1
  107. package/dist/integrations/providers/impls/qdrant-vector.js.map +1 -1
  108. package/dist/integrations/providers/impls/stripe-payments.d.ts.map +1 -1
  109. package/dist/integrations/providers/impls/stripe-payments.js.map +1 -1
  110. package/dist/integrations/providers/impls/twilio-sms.js.map +1 -1
  111. package/dist/integrations/providers/llm.d.ts.map +1 -1
  112. package/dist/integrations/providers/mistral.d.ts.map +1 -1
  113. package/dist/integrations/providers/mistral.js.map +1 -1
  114. package/dist/integrations/providers/payments.d.ts.map +1 -1
  115. package/dist/integrations/providers/postmark.d.ts.map +1 -1
  116. package/dist/integrations/providers/postmark.js.map +1 -1
  117. package/dist/integrations/providers/powens.js.map +1 -1
  118. package/dist/integrations/providers/qdrant.d.ts.map +1 -1
  119. package/dist/integrations/providers/qdrant.js.map +1 -1
  120. package/dist/integrations/providers/stripe.js.map +1 -1
  121. package/dist/integrations/providers/twilio-sms.js.map +1 -1
  122. package/dist/integrations/runtime.d.ts.map +1 -1
  123. package/dist/integrations/runtime.js.map +1 -1
  124. package/dist/integrations/secrets/env-secret-provider.js.map +1 -1
  125. package/dist/integrations/secrets/gcp-secret-manager.d.ts.map +1 -1
  126. package/dist/integrations/secrets/gcp-secret-manager.js.map +1 -1
  127. package/dist/integrations/secrets/manager.d.ts +2 -2
  128. package/dist/integrations/secrets/manager.d.ts.map +1 -1
  129. package/dist/integrations/secrets/manager.js.map +1 -1
  130. package/dist/integrations/secrets/provider.js.map +1 -1
  131. package/dist/integrations/spec.d.ts.map +1 -1
  132. package/dist/integrations/spec.js.map +1 -1
  133. package/dist/jobs/gcp-cloud-tasks.js.map +1 -1
  134. package/dist/jobs/gcp-pubsub.d.ts.map +1 -1
  135. package/dist/jobs/gcp-pubsub.js.map +1 -1
  136. package/dist/jobs/handlers/gmail-sync-handler.js.map +1 -1
  137. package/dist/jobs/handlers/storage-document-handler.js.map +1 -1
  138. package/dist/jobs/memory-queue.d.ts.map +1 -1
  139. package/dist/jobs/memory-queue.js.map +1 -1
  140. package/dist/jobs/queue.d.ts.map +1 -1
  141. package/dist/jsonschema.d.ts +1 -1
  142. package/dist/jsonschema.d.ts.map +1 -1
  143. package/dist/knowledge/contracts.d.ts +67 -65
  144. package/dist/knowledge/contracts.d.ts.map +1 -1
  145. package/dist/knowledge/contracts.js +1 -1
  146. package/dist/knowledge/contracts.js.map +1 -1
  147. package/dist/knowledge/ingestion/document-processor.js.map +1 -1
  148. package/dist/knowledge/ingestion/embedding-service.d.ts.map +1 -1
  149. package/dist/knowledge/ingestion/embedding-service.js.map +1 -1
  150. package/dist/knowledge/ingestion/gmail-adapter.d.ts.map +1 -1
  151. package/dist/knowledge/ingestion/gmail-adapter.js.map +1 -1
  152. package/dist/knowledge/ingestion/storage-adapter.js.map +1 -1
  153. package/dist/knowledge/ingestion/vector-indexer.js.map +1 -1
  154. package/dist/knowledge/query/service.d.ts +2 -2
  155. package/dist/knowledge/query/service.d.ts.map +1 -1
  156. package/dist/knowledge/query/service.js.map +1 -1
  157. package/dist/knowledge/runtime.d.ts.map +1 -1
  158. package/dist/knowledge/runtime.js.map +1 -1
  159. package/dist/knowledge/spaces/email-threads.js.map +1 -1
  160. package/dist/knowledge/spaces/financial-docs.js.map +1 -1
  161. package/dist/knowledge/spaces/financial-overview.js.map +1 -1
  162. package/dist/knowledge/spaces/product-canon.js.map +1 -1
  163. package/dist/knowledge/spaces/support-faq.js.map +1 -1
  164. package/dist/knowledge/spaces/uploaded-docs.js.map +1 -1
  165. package/dist/knowledge/spec.js.map +1 -1
  166. package/dist/migrations.d.ts.map +1 -1
  167. package/dist/migrations.js.map +1 -1
  168. package/dist/onboarding-base.d.ts +30 -28
  169. package/dist/onboarding-base.d.ts.map +1 -1
  170. package/dist/onboarding-base.js +1 -1
  171. package/dist/onboarding-base.js.map +1 -1
  172. package/dist/policy/engine.js.map +1 -1
  173. package/dist/policy/opa-adapter.d.ts.map +1 -1
  174. package/dist/policy/opa-adapter.js.map +1 -1
  175. package/dist/policy/spec.d.ts.map +1 -1
  176. package/dist/policy/spec.js.map +1 -1
  177. package/dist/presentations.d.ts +1 -0
  178. package/dist/presentations.d.ts.map +1 -1
  179. package/dist/presentations.v2.d.ts +1 -0
  180. package/dist/presentations.v2.d.ts.map +1 -1
  181. package/dist/regenerator/executor.d.ts.map +1 -1
  182. package/dist/regenerator/executor.js.map +1 -1
  183. package/dist/regenerator/service.d.ts.map +1 -1
  184. package/dist/regenerator/service.js.map +1 -1
  185. package/dist/regenerator/sinks.d.ts.map +1 -1
  186. package/dist/regenerator/sinks.js.map +1 -1
  187. package/dist/regenerator/types.d.ts.map +1 -1
  188. package/dist/regenerator/utils.js.map +1 -1
  189. package/dist/registry.d.ts +37 -9
  190. package/dist/registry.d.ts.map +1 -1
  191. package/dist/registry.js +1 -1
  192. package/dist/registry.js.map +1 -1
  193. package/dist/schema/dist/FieldType.js +2 -0
  194. package/dist/schema/dist/FieldType.js.map +1 -0
  195. package/dist/schema/dist/ScalarTypeEnum.js +2 -0
  196. package/dist/schema/dist/ScalarTypeEnum.js.map +1 -0
  197. package/dist/schema/{src → dist}/SchemaModel.js +1 -1
  198. package/dist/schema/dist/SchemaModel.js.map +1 -0
  199. package/dist/schema/dist/index.js +1 -0
  200. package/dist/server/graphql-pothos.d.ts +15 -2
  201. package/dist/server/graphql-pothos.d.ts.map +1 -1
  202. package/dist/server/graphql-pothos.js.map +1 -1
  203. package/dist/server/graphql-schema-export.js +1 -1
  204. package/dist/server/graphql-schema-export.js.map +1 -1
  205. package/dist/server/provider-mcp.d.ts +22 -4
  206. package/dist/server/provider-mcp.d.ts.map +1 -1
  207. package/dist/server/provider-mcp.js.map +1 -1
  208. package/dist/server/rest-next-app.d.ts +23 -3
  209. package/dist/server/rest-next-app.d.ts.map +1 -1
  210. package/dist/server/rest-next-app.js.map +1 -1
  211. package/dist/spec.d.ts +23 -0
  212. package/dist/spec.d.ts.map +1 -1
  213. package/dist/spec.js.map +1 -1
  214. package/dist/telemetry/anomaly.js.map +1 -1
  215. package/dist/telemetry/spec.d.ts.map +1 -1
  216. package/dist/telemetry/spec.js.map +1 -1
  217. package/dist/telemetry/tracker.d.ts.map +1 -1
  218. package/dist/telemetry/tracker.js.map +1 -1
  219. package/dist/tests/runner.js.map +1 -1
  220. package/dist/tests/spec.js.map +1 -1
  221. package/dist/themes.d.ts.map +1 -1
  222. package/dist/themes.js.map +1 -1
  223. package/dist/types/all.d.ts +2 -2
  224. package/dist/types.d.ts +3 -0
  225. package/dist/types.d.ts.map +1 -1
  226. package/dist/workflow/adapters/db-adapter.d.ts +30 -10
  227. package/dist/workflow/adapters/db-adapter.d.ts.map +1 -1
  228. package/dist/workflow/adapters/db-adapter.js +1 -1
  229. package/dist/workflow/adapters/db-adapter.js.map +1 -1
  230. package/dist/workflow/adapters/file-adapter.js.map +1 -1
  231. package/dist/workflow/adapters/index.d.ts +2 -2
  232. package/dist/workflow/adapters/index.js +1 -1
  233. package/dist/workflow/adapters/memory-store.d.ts.map +1 -1
  234. package/dist/workflow/adapters/memory-store.js.map +1 -1
  235. package/dist/workflow/expression.js.map +1 -1
  236. package/dist/workflow/index.d.ts +2 -2
  237. package/dist/workflow/index.js +1 -1
  238. package/dist/workflow/runner.d.ts +1 -0
  239. package/dist/workflow/runner.d.ts.map +1 -1
  240. package/dist/workflow/runner.js +1 -1
  241. package/dist/workflow/runner.js.map +1 -1
  242. package/dist/workflow/sla-monitor.d.ts +21 -0
  243. package/dist/workflow/sla-monitor.d.ts.map +1 -0
  244. package/dist/workflow/sla-monitor.js +2 -0
  245. package/dist/workflow/sla-monitor.js.map +1 -0
  246. package/dist/workflow/spec.d.ts.map +1 -1
  247. package/dist/workflow/spec.js.map +1 -1
  248. package/dist/workflow/state.d.ts +1 -0
  249. package/dist/workflow/state.d.ts.map +1 -1
  250. package/dist/workflow/validation.d.ts.map +1 -1
  251. package/dist/workflow/validation.js.map +1 -1
  252. package/package.json +181 -177
  253. package/dist/graphql-federation/src/index.js +0 -2
  254. package/dist/graphql-federation/src/index.js.map +0 -1
  255. package/dist/schema/src/FieldType.js +0 -2
  256. package/dist/schema/src/FieldType.js.map +0 -1
  257. package/dist/schema/src/ScalarTypeEnum.js +0 -2
  258. package/dist/schema/src/ScalarTypeEnum.js.map +0 -1
  259. package/dist/schema/src/SchemaModel.js.map +0 -1
  260. package/dist/schema/src/index.js +0 -1
  261. /package/dist/schema/{src → dist}/EnumType.js +0 -0
package/README.md CHANGED
@@ -1,8 +1,12 @@
1
- ## @lssm/lib.contracts — Unified Specs for Ops, Events, Presentations, and Features
1
+ # @lssm/lib.contracts
2
2
 
3
- Purpose: Provide a single, typed source of truth for backend operations, events, prompts/resources, and UI/data presentations. This enables consistent adapters (REST/GraphQL/MCP/UI), high‑quality docs, and agent-friendly automation across apps.
3
+ Unified specifications for Operations, Events, Presentations, and Features.
4
4
 
5
- ### Installation
5
+ ## Purpose
6
+
7
+ To provide a single, typed source of truth for backend operations (`ContractSpec`), events (`EventSpec`), and UI/data presentations. This enables **runtime adapters** (REST, GraphQL, MCP, UI) to automatically generate endpoints, schemas, and user interfaces without code duplication.
8
+
9
+ ## Installation
6
10
 
7
11
  ```bash
8
12
  npm install @lssm/lib.contracts @lssm/lib.schema
@@ -10,352 +14,85 @@ npm install @lssm/lib.contracts @lssm/lib.schema
10
14
  bun add @lssm/lib.contracts @lssm/lib.schema
11
15
  ```
12
16
 
13
- Import from the scoped entry points for leaner bundles:
17
+ ## Key Concepts
14
18
 
15
- - `@lssm/lib.contracts/client` – browser-safe helpers (`client/react`, render drivers, SDK).
16
- - `@lssm/lib.contracts/server` Node adapters (REST, GraphQL, MCP).
17
- - `@lssm/lib.contracts/types` runtime context types (`HandlerCtx`, `PolicyDecision`, etc.).
18
- - `@lssm/lib.contracts/types/all` type-only re-exports across the package (compiles to an empty JS module).
19
+ - **Spec-First, TypeScript-First**: Define operations in pure TypeScript (no YAML).
20
+ - **Runtime Adapters**: The `SpecRegistry` is passed to adapters (e.g., `makeNextAppHandler`) to serve APIs dynamically. There is no intermediate "compile" step to generate code; the spec _is_ the code.
21
+ - **Capabilities**: `defineCommand` (writes) and `defineQuery` (reads) with Zod-backed I/O.
22
+ - **Events**: `defineEvent` for type-safe side effects.
23
+ - **Presentations**: (V2) Describe how data is rendered (Web Components, Markdown, Data) for automated UI generation.
19
24
 
20
- ### Today (already implemented)
25
+ ## Exports
21
26
 
22
- - **Operations (ContractSpec)**: versioned `command`/`query` definitions with `meta`, `io` (zod-backed via `@lssm/lib.schema`), `policy`, `sideEffects` (declared events), `transport` hints, and `acceptance` examples. See `src/spec.ts` and `src/registry.ts`.
23
- - **Events (EventSpec)**: versioned event payloads validated at publish time and guarded from undeclared emission. See `src/events.ts` and runtime guard in `SpecRegistry.execute()`.
27
+ - **Core**: `SpecRegistry`, `defineCommand`, `defineQuery`, `defineEvent`.
24
28
  - **Adapters**:
25
- - REST: `server/rest-generic`, `server/rest-next-app`, `server/rest-next-pages`, `server/rest-elysia`.
26
- - MCP: `server/provider-mcp` (tools, resources, prompts), `server/rest-next-mcp` (MCP via Next route).
27
- - GraphQL: `server/graphql-pothos` to mount contract operations into a Pothos schema.
28
- - Docs: `markdown.specsToMarkdown(reg)` and `markdown.docsToMarkdown(reg, { presentations, features })` to render human docs.
29
-
30
- ### Next (this document proposes)
31
-
32
- Add a first-class, typed presentation layer (V2 descriptors available today) and feature grouping so one module can declare:
33
-
34
- - What it DOES (operations/queries),
35
- - What it EMITS (events),
36
- - How it is SHOWN or EXPORTED (presentations),
37
- - How to INSTALL/REGISTER it as a coherent feature.
38
-
39
- This improves reuse, observability, and AI agent operability across web apps, docs, and integrations.
40
-
41
- ---
42
-
43
- ## Presentation Categories
44
-
45
- Three complementary presentation types can be declared and exported from the contracts library. They are transport-agnostic and do not bind to a specific app; host apps mount them using adapters. A normalized V2 descriptor exists in `presentations.v2.ts` with a transform engine and validators.
46
-
47
- ### 1) Web components (React first)
48
-
49
- - **Goal**: Render real user stories with clean, simple, Atomic Design components. Mobile-friendly by default.
50
- - **Adapter**: Host app provides a `componentMap` that resolves a `componentKey` to a concrete React component. This avoids cross-package JSX coupling.
51
- - **Use cases**: Feature previews, onboarding stories, guided flows.
52
-
53
- Shape (proposed):
54
-
55
- ```ts
56
- type PresentationKind = 'web_component' | 'markdown' | 'data';
57
-
58
- interface PresentationMeta {
59
- name: string; // e.g. "hcircle.weekly_pulse.quick_vote"
60
- version: number; // bump on breaking changes
61
- stability?: 'experimental' | 'beta' | 'stable' | 'deprecated';
62
- owners?: string[];
63
- tags?: string[]; // search, grouping
64
- description?: string;
65
- }
66
-
67
- interface WebComponentPresentation {
68
- kind: 'web_component';
69
- framework: 'react';
70
- /** Symbolic key resolved by host via componentMap */
71
- componentKey: string; // e.g. "userStory.weekly_pulse.quick_vote"
72
- /** zod-backed props schema from @lssm/lib.schema */
73
- props: import('@lssm/lib.schema').AnySchemaModel;
74
- /** Optional interaction analytics intents */
75
- analytics?: string[];
76
- }
77
- ```
78
-
79
- Host-side rendering contract (example):
80
-
81
- ```ts
82
- // In the host app
83
- const componentMap: Record<string, React.ComponentType<any>> = {
84
- 'userStory.weekly_pulse.quick_vote': QuickVote,
85
- 'userStory.weekly_pulse.happiness': HappinessLife,
86
- };
87
-
88
- function renderWebPresentation(p: WebComponentPresentation, data: any) {
89
- const C = componentMap[p.componentKey];
90
- if (!C) return <Fallback componentKey={p.componentKey} />;
91
- const parsed = p.props.getZod().parse(data);
92
- return <C {...parsed} />;
93
- }
94
- ```
29
+ - `server/rest-next-app`: Next.js App Router adapter.
30
+ - `server/provider-mcp`: Model Context Protocol (MCP) adapter for AI agents.
31
+ - `server/graphql-pothos`: GraphQL schema generator.
32
+ - **Docs**: `markdown` utilities to generate human-readable documentation from specs.
95
33
 
96
- Guidelines:
34
+ ## Usage
97
35
 
98
- - Use Atomic Design; keep components stateless where feasible.
99
- - Ensure a11y (labels, roles, keyboard traversal) and small-screen ergonomics.
100
- - Gate feature-flagged experiences in the host, aligning with `policy.flags` when relevant.
101
-
102
- ### 2) Markdown/MDX
103
-
104
- - **Goal**: Make the platform and its features easily digestible by LLMs and human readers.
105
- - **Adapter**: Expose as static strings (Markdown) or MDX sources. Optionally resolve via `ResourceRegistry` URIs so MCP clients can fetch them.
106
- - **Use cases**: Feature guides, acceptance narratives, inline help.
107
-
108
- Shape (proposed):
109
-
110
- ```ts
111
- interface MarkdownPresentation {
112
- kind: 'markdown';
113
- /** Either inline content or a resource URI template */
114
- content?: string; // Markdown/MDX source
115
- resourceUri?: string; // e.g. "feature://{featureKey}/story/{storyKey}.md"
116
- }
117
- ```
118
-
119
- ### 3) Structured raw data (JSON/XML)
120
-
121
- - **Goal**: Enable external integrations, partial adoption, and customized setups without lock-in.
122
- - **Adapter**: Expose via `ResourceRegistry` with stable URIs and MIME types; MCP resources map 1:1.
123
- - **Use cases**: CSV/JSON/XML export, analytics snapshots, reference dictionaries.
124
-
125
- Shape (proposed):
126
-
127
- ```ts
128
- interface DataPresentation {
129
- kind: 'data';
130
- mimeType: 'application/json' | 'application/xml' | string;
131
- /** zod-backed schema for the payload structure */
132
- model: import('@lssm/lib.schema').AnySchemaModel;
133
- }
134
- ```
135
-
136
- Union and registry (proposed):
36
+ ### 1. Define a Spec
137
37
 
138
38
  ```ts
139
- type PresentationSpec = {
140
- meta: PresentationMeta;
141
- policy?: { flags?: string[]; pii?: string[] };
142
- content: WebComponentPresentation | MarkdownPresentation | DataPresentation;
143
- };
144
-
145
- class PresentationRegistry {
146
- register(p: PresentationSpec): this {
147
- /* ... */ return this;
148
- }
149
- list(): PresentationSpec[] {
150
- /* ... */ return [];
151
- }
152
- get(name: string, version?: number): PresentationSpec | undefined {
153
- /* ... */ return undefined;
154
- }
155
- }
156
- ```
157
-
158
- ---
159
-
160
- ## Feature Grouping
161
-
162
- Group operations, events, and presentations into a feature/module spec that can be installed in one go.
163
-
164
- Shape (proposed):
165
-
166
- ```ts
167
- interface FeatureModuleMeta {
168
- key: string; // stable slug, e.g. "weekly_pulse"
169
- title: string;
170
- description?: string;
171
- domain?: string; // bounded context, e.g. "hcircle.harmony"
172
- owners?: string[];
173
- tags?: string[]; // e.g. ["connect", "save_time"]
174
- }
175
-
176
- interface FeatureModuleSpec {
177
- meta: FeatureModuleMeta;
178
- operations?: Array<{ name: string; version: number }>; // ContractSpec
179
- events?: Array<{ name: string; version: number }>; // EventSpec
180
- presentations?: Array<{ name: string; version: number }>; // PresentationSpec
181
- }
182
-
183
- class FeatureRegistry {
184
- register(f: FeatureModuleSpec): this {
185
- /* ... */ return this;
186
- }
187
- list(): FeatureModuleSpec[] {
188
- /* ... */ return [];
189
- }
190
- }
191
-
192
- // Optional installer to wire everything in one call
193
- function installFeature(
194
- feature: FeatureModuleSpec,
195
- deps: {
196
- ops: import('./src/registry').SpecRegistry;
197
- presentations: PresentationRegistry;
198
- resources: import('./src/resources').ResourceRegistry;
199
- }
200
- ) {
201
- /* register ops/events/presentations/resources */
202
- }
203
- ```
204
-
205
- Why group?
206
-
207
- - Single place to discover/enable a capability
208
- - Consistent docs generation and MCP exposure
209
- - Better alignment with product modules (see `hcircle` module registry)
210
-
211
- ---
212
-
213
- ## Mapping coliving modules → Presentations
214
-
215
- Reference: `packages/hcircle/apps/web-coliving/src/components/modules/{types.ts,registry.ts}` defines modules like `weekly_pulse`, `incident_hygiene`, `groceries`, with user stories and preview components.
216
-
217
- Examples (conceptual):
39
+ import { defineCommand, defineQuery } from '@lssm/lib.contracts';
40
+ import { z } from 'zod';
41
+ import { SchemaModel, ScalarTypeEnum } from '@lssm/lib.schema';
42
+
43
+ const UserInput = new SchemaModel({
44
+ name: 'UserInput',
45
+ fields: {
46
+ email: { type: ScalarTypeEnum.Email(), isOptional: false },
47
+ },
48
+ });
218
49
 
219
- ```ts
220
- // Web component presentations (user stories)
221
- const WeeklyPulseQuickVote: PresentationSpec = {
50
+ export const CreateUser = defineCommand({
222
51
  meta: {
223
- name: 'hcircle.weekly_pulse.quick_vote',
52
+ name: 'user.create',
224
53
  version: 1,
225
- tags: ['connect', 'harmony'],
226
- description: '3-tap check-in for house alignment',
54
+ description: 'Register a new user',
55
+ owners: ['team-auth'],
56
+ tags: ['auth'],
57
+ goal: 'Onboard users',
58
+ context: 'Public registration',
59
+ stability: 'stable',
227
60
  },
228
- content: {
229
- kind: 'web_component',
230
- framework: 'react',
231
- componentKey: 'userStory.weekly_pulse.quick_vote',
232
- props: /* SchemaModel for props */ undefined as any,
61
+ io: {
62
+ input: UserInput,
63
+ output: new SchemaModel({
64
+ name: 'UserOutput',
65
+ fields: {
66
+ id: { type: ScalarTypeEnum.String(), isOptional: false },
67
+ },
68
+ }),
233
69
  },
234
- };
235
-
236
- // Markdown/MDX guide
237
- const WeeklyPulseGuide: PresentationSpec = {
238
- meta: { name: 'hcircle.weekly_pulse.guide', version: 1 },
239
- content: {
240
- kind: 'markdown',
241
- resourceUri: 'feature://weekly_pulse/story/guide.md',
242
- },
243
- };
244
-
245
- // Data export (JSON)
246
- const GroceriesBudgetExport: PresentationSpec = {
247
- meta: { name: 'hcircle.groceries.budget_export', version: 1 },
248
- content: {
249
- kind: 'data',
250
- mimeType: 'application/json',
251
- model: /* SchemaModel for export shape */ undefined as any,
70
+ policy: {
71
+ auth: 'anonymous',
252
72
  },
253
- };
73
+ });
254
74
  ```
255
75
 
256
- In the feature group:
257
-
258
- ```ts
259
- const WeeklyPulseFeature: FeatureModuleSpec = {
260
- meta: {
261
- key: 'weekly_pulse',
262
- title: 'Weekly Pulse',
263
- tags: ['harmony', 'connect'],
264
- },
265
- operations: [{ name: 'pulse.submitQuickVote', version: 1 }],
266
- events: [{ name: 'pulse.vote_recorded', version: 1 }],
267
- presentations: [
268
- { name: 'hcircle.weekly_pulse.quick_vote', version: 1 },
269
- { name: 'hcircle.weekly_pulse.guide', version: 1 },
270
- ],
271
- };
272
- ```
273
-
274
- ---
275
-
276
- ## Adapters and Exposure
277
-
278
- - **REST**: already provided; driven by `SpecRegistry`. Presentations are not REST endpoints directly, but their data forms can be exposed as `ResourceRegistry` entries.
279
- - **GraphQL (Pothos)**: provided in `src/server/graphql-pothos.ts`. Auto-maps operations into Query/Mutation fields. Presentations are better exposed as resources (URIs) consumed by prompts/LLMs.
280
- - **MCP**: `createMcpServer` exposes commands (tools), resources, and prompts. Presentations map naturally:
281
- - `web_component` → discoverable metadata (name, tags) for UI agents.
282
- - `markdown` → resources (URIs) returned by prompts.
283
- - `data` → resources with explicit MIME types.
284
- - **Docs**: extend `specsToMarkdown` to include presentations and feature groups so dev portals stay in sync. See `docs/tech/contracts/presentations-v2.md` for the unified V2 model and engine.
285
-
286
- ---
287
-
288
- ## Versioning & Stability (recommended)
289
-
290
- - Bump `version` on any breaking change to shape or behavior of the spec.
291
- - Mark `stability` to guide adopters: `experimental` → `beta` → `stable` → `deprecated`.
292
- - Keep event payloads and data exports backward compatible where feasible. For UI, prefer additive props; otherwise, bump version and keep both entries during transition.
293
-
294
- ---
295
-
296
- ## Adapters Planning (next steps)
297
-
298
- - React adapter: resolve `componentKey` → component map in host, validate props with SchemaModel, capture analytics intents.
299
- - Markdown adapter: expose `markdown` presentations via `ResourceRegistry` + MCP resources; optionally render in app help.
300
- - Data adapter: expose `data` presentations via `ResourceRegistry` with explicit MIME types (JSON/XML) and stable URIs.
301
-
302
- ---
303
-
304
- ## Authoring Guidelines
305
-
306
- - **Atomic Design** for web components; keep complexity low and interactions obvious.
307
- - **Accessibility**: labels, roles, focus order, and reduced motion options.
308
- - **i18n**: UI strings belong in app i18n namespaces; contracts carry keys and defaults, not hard-coded text.
309
- - **Feature flags**: gate risky or staged presentations via `policy.flags` + host checks.
310
- - **Docs as source**: when specs change, update `docs/` in the same change.
311
-
312
- ---
313
-
314
- ## How to Add a New Feature
315
-
316
- 1. Define operations/events in code using `defineCommand`, `defineQuery`, and `defineEvent`.
317
- 2. Declare presentations (at least one) in a `PresentationRegistry` and link to the feature.
318
- 3. Register a `FeatureModuleSpec` that references ops/events/presentations.
319
- 4. Mount adapters in the host app(s): REST/GraphQL/MCP/UI.
320
- 5. Update docs via the markdown generator and/or bespoke docs in `docs/`.
321
-
322
- ### Quick start
76
+ ### 2. Register and Implement
323
77
 
324
78
  ```ts
325
79
  import { SpecRegistry, installOp } from '@lssm/lib.contracts';
326
- import { makeNextAppHandler } from '@lssm/lib.contracts/server/rest-next-app';
327
80
 
328
81
  const reg = new SpecRegistry();
329
- installOp(reg, BeginSignupSpec, beginSignupHandler);
330
82
 
331
- export const { GET, POST } = {
332
- GET: (req: Request) =>
333
- makeNextAppHandler(reg, () => ({ actor: 'anonymous' }))(req),
334
- POST: (req: Request) =>
335
- makeNextAppHandler(reg, () => ({ actor: 'anonymous' }))(req),
336
- };
83
+ installOp(reg, CreateUser, async (ctx, input) => {
84
+ // Implementation logic here
85
+ return { id: '123' };
86
+ });
337
87
  ```
338
88
 
339
- ---
340
-
341
- ## Exports (current)
342
-
343
- See `src/index.ts` for public exports:
344
-
345
- - Ops/events/specs/registries
346
- - REST/Next/Elysia/MCP adapters
347
- - Markdown generator, prompt registry, resources
89
+ ### 3. Serve (Next.js Adapter)
348
90
 
349
- Planned additions:
350
-
351
- - `PresentationSpec`, `PresentationRegistry`
352
- - `FeatureModuleSpec`, `FeatureRegistry`, `installFeature`
353
- - Extended docs generator to include presentations/features
354
-
355
- ---
91
+ ```ts
92
+ // app/api/[...route]/route.ts
93
+ import { makeNextAppHandler } from '@lssm/lib.contracts/server/rest-next-app';
356
94
 
357
- ## Notes
95
+ const handler = makeNextAppHandler(reg, (req) => ({ actor: 'anonymous' }));
358
96
 
359
- - Keep adapters and registries modular and swappable (hexagonal). Domain logic must remain testable in isolation.
360
- - Prefer `@lssm/lib.schema` models to avoid zod schema drift across adapters.
361
- - When multiple apps consume the same presentation, rely on the `componentKey` indirection rather than importing components across packages.
97
+ export { handler as GET, handler as POST };
98
+ ```