@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.
- package/README.md +62 -325
- package/dist/app-config/contracts.d.ts +51 -49
- package/dist/app-config/contracts.d.ts.map +1 -1
- package/dist/app-config/contracts.js +1 -1
- package/dist/app-config/contracts.js.map +1 -1
- package/dist/app-config/events.d.ts +28 -26
- package/dist/app-config/events.d.ts.map +1 -1
- package/dist/app-config/events.js +1 -1
- package/dist/app-config/events.js.map +1 -1
- package/dist/app-config/lifecycle-contracts.d.ts +81 -79
- package/dist/app-config/lifecycle-contracts.d.ts.map +1 -1
- package/dist/app-config/lifecycle-contracts.js +1 -1
- package/dist/app-config/lifecycle-contracts.js.map +1 -1
- package/dist/app-config/runtime.d.ts.map +1 -1
- package/dist/app-config/runtime.js.map +1 -1
- package/dist/app-config/spec.d.ts +2 -2
- package/dist/app-config/spec.d.ts.map +1 -1
- package/dist/app-config/spec.js.map +1 -1
- package/dist/app-config/validation.d.ts.map +1 -1
- package/dist/app-config/validation.js.map +1 -1
- package/dist/capabilities/openbanking.d.ts.map +1 -1
- package/dist/capabilities/openbanking.js.map +1 -1
- package/dist/capabilities.d.ts +2 -1
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +1 -1
- package/dist/capabilities.js.map +1 -1
- package/dist/client/react/form-render.d.ts +1 -0
- package/dist/client/react/form-render.d.ts.map +1 -1
- package/dist/contracts-adapter-input.d.ts +1 -0
- package/dist/contracts-adapter-input.d.ts.map +1 -1
- package/dist/data-views/query-generator.d.ts +40 -0
- package/dist/data-views/query-generator.d.ts.map +1 -0
- package/dist/data-views/query-generator.js +2 -0
- package/dist/data-views/query-generator.js.map +1 -0
- package/dist/data-views/runtime.d.ts +27 -0
- package/dist/data-views/runtime.d.ts.map +1 -0
- package/dist/data-views/runtime.js +2 -0
- package/dist/data-views/runtime.js.map +1 -0
- package/dist/data-views.js.map +1 -1
- package/dist/events.d.ts +1 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +1 -1
- package/dist/events.js.map +1 -1
- package/dist/experiments/evaluator.d.ts.map +1 -1
- package/dist/experiments/evaluator.js.map +1 -1
- package/dist/experiments/spec-resolver.d.ts +17 -0
- package/dist/experiments/spec-resolver.d.ts.map +1 -0
- package/dist/experiments/spec-resolver.js +0 -0
- package/dist/experiments/spec.js.map +1 -1
- package/dist/forms.d.ts +1 -0
- package/dist/forms.d.ts.map +1 -1
- package/dist/graphql-federation/dist/index.js +2 -0
- package/dist/graphql-federation/dist/index.js.map +1 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +1 -1
- package/dist/install.d.ts +1 -0
- package/dist/install.d.ts.map +1 -1
- package/dist/integrations/connection.d.ts.map +1 -1
- package/dist/integrations/contracts.d.ts +103 -101
- package/dist/integrations/contracts.d.ts.map +1 -1
- package/dist/integrations/contracts.js +1 -1
- package/dist/integrations/contracts.js.map +1 -1
- package/dist/integrations/health.d.ts.map +1 -1
- package/dist/integrations/health.js.map +1 -1
- package/dist/integrations/openbanking/contracts/accounts.d.ts +67 -65
- package/dist/integrations/openbanking/contracts/accounts.d.ts.map +1 -1
- package/dist/integrations/openbanking/contracts/accounts.js +1 -1
- package/dist/integrations/openbanking/contracts/accounts.js.map +1 -1
- package/dist/integrations/openbanking/contracts/balances.d.ts +35 -33
- package/dist/integrations/openbanking/contracts/balances.d.ts.map +1 -1
- package/dist/integrations/openbanking/contracts/balances.js +1 -1
- package/dist/integrations/openbanking/contracts/balances.js.map +1 -1
- package/dist/integrations/openbanking/contracts/index.js.map +1 -1
- package/dist/integrations/openbanking/contracts/transactions.d.ts +49 -47
- package/dist/integrations/openbanking/contracts/transactions.d.ts.map +1 -1
- package/dist/integrations/openbanking/contracts/transactions.js +1 -1
- package/dist/integrations/openbanking/contracts/transactions.js.map +1 -1
- package/dist/integrations/openbanking/guards.js.map +1 -1
- package/dist/integrations/openbanking/models.d.ts +57 -54
- package/dist/integrations/openbanking/models.d.ts.map +1 -1
- package/dist/integrations/openbanking/models.js +1 -1
- package/dist/integrations/openbanking/models.js.map +1 -1
- package/dist/integrations/openbanking/telemetry.js.map +1 -1
- package/dist/integrations/providers/elevenlabs.d.ts.map +1 -1
- package/dist/integrations/providers/elevenlabs.js.map +1 -1
- package/dist/integrations/providers/gcs-storage.js.map +1 -1
- package/dist/integrations/providers/gmail.d.ts.map +1 -1
- package/dist/integrations/providers/gmail.js.map +1 -1
- package/dist/integrations/providers/google-calendar.js.map +1 -1
- package/dist/integrations/providers/impls/elevenlabs-voice.js.map +1 -1
- package/dist/integrations/providers/impls/gcs-storage.js.map +1 -1
- package/dist/integrations/providers/impls/gmail-inbound.js.map +1 -1
- package/dist/integrations/providers/impls/gmail-outbound.d.ts.map +1 -1
- package/dist/integrations/providers/impls/gmail-outbound.js.map +1 -1
- package/dist/integrations/providers/impls/google-calendar.d.ts.map +1 -1
- package/dist/integrations/providers/impls/google-calendar.js.map +1 -1
- package/dist/integrations/providers/impls/mistral-embedding.js.map +1 -1
- package/dist/integrations/providers/impls/mistral-llm.js.map +1 -1
- package/dist/integrations/providers/impls/postmark-email.js.map +1 -1
- package/dist/integrations/providers/impls/powens-client.d.ts.map +1 -1
- package/dist/integrations/providers/impls/powens-client.js.map +1 -1
- package/dist/integrations/providers/impls/powens-openbanking.d.ts.map +1 -1
- package/dist/integrations/providers/impls/powens-openbanking.js.map +1 -1
- package/dist/integrations/providers/impls/provider-factory.d.ts.map +1 -1
- package/dist/integrations/providers/impls/provider-factory.js.map +1 -1
- package/dist/integrations/providers/impls/qdrant-vector.d.ts.map +1 -1
- package/dist/integrations/providers/impls/qdrant-vector.js.map +1 -1
- package/dist/integrations/providers/impls/stripe-payments.d.ts.map +1 -1
- package/dist/integrations/providers/impls/stripe-payments.js.map +1 -1
- package/dist/integrations/providers/impls/twilio-sms.js.map +1 -1
- package/dist/integrations/providers/llm.d.ts.map +1 -1
- package/dist/integrations/providers/mistral.d.ts.map +1 -1
- package/dist/integrations/providers/mistral.js.map +1 -1
- package/dist/integrations/providers/payments.d.ts.map +1 -1
- package/dist/integrations/providers/postmark.d.ts.map +1 -1
- package/dist/integrations/providers/postmark.js.map +1 -1
- package/dist/integrations/providers/powens.js.map +1 -1
- package/dist/integrations/providers/qdrant.d.ts.map +1 -1
- package/dist/integrations/providers/qdrant.js.map +1 -1
- package/dist/integrations/providers/stripe.js.map +1 -1
- package/dist/integrations/providers/twilio-sms.js.map +1 -1
- package/dist/integrations/runtime.d.ts.map +1 -1
- package/dist/integrations/runtime.js.map +1 -1
- package/dist/integrations/secrets/env-secret-provider.js.map +1 -1
- package/dist/integrations/secrets/gcp-secret-manager.d.ts.map +1 -1
- package/dist/integrations/secrets/gcp-secret-manager.js.map +1 -1
- package/dist/integrations/secrets/manager.d.ts +2 -2
- package/dist/integrations/secrets/manager.d.ts.map +1 -1
- package/dist/integrations/secrets/manager.js.map +1 -1
- package/dist/integrations/secrets/provider.js.map +1 -1
- package/dist/integrations/spec.d.ts.map +1 -1
- package/dist/integrations/spec.js.map +1 -1
- package/dist/jobs/gcp-cloud-tasks.js.map +1 -1
- package/dist/jobs/gcp-pubsub.d.ts.map +1 -1
- package/dist/jobs/gcp-pubsub.js.map +1 -1
- package/dist/jobs/handlers/gmail-sync-handler.js.map +1 -1
- package/dist/jobs/handlers/storage-document-handler.js.map +1 -1
- package/dist/jobs/memory-queue.d.ts.map +1 -1
- package/dist/jobs/memory-queue.js.map +1 -1
- package/dist/jobs/queue.d.ts.map +1 -1
- package/dist/jsonschema.d.ts +1 -1
- package/dist/jsonschema.d.ts.map +1 -1
- package/dist/knowledge/contracts.d.ts +67 -65
- package/dist/knowledge/contracts.d.ts.map +1 -1
- package/dist/knowledge/contracts.js +1 -1
- package/dist/knowledge/contracts.js.map +1 -1
- package/dist/knowledge/ingestion/document-processor.js.map +1 -1
- package/dist/knowledge/ingestion/embedding-service.d.ts.map +1 -1
- package/dist/knowledge/ingestion/embedding-service.js.map +1 -1
- package/dist/knowledge/ingestion/gmail-adapter.d.ts.map +1 -1
- package/dist/knowledge/ingestion/gmail-adapter.js.map +1 -1
- package/dist/knowledge/ingestion/storage-adapter.js.map +1 -1
- package/dist/knowledge/ingestion/vector-indexer.js.map +1 -1
- package/dist/knowledge/query/service.d.ts +2 -2
- package/dist/knowledge/query/service.d.ts.map +1 -1
- package/dist/knowledge/query/service.js.map +1 -1
- package/dist/knowledge/runtime.d.ts.map +1 -1
- package/dist/knowledge/runtime.js.map +1 -1
- package/dist/knowledge/spaces/email-threads.js.map +1 -1
- package/dist/knowledge/spaces/financial-docs.js.map +1 -1
- package/dist/knowledge/spaces/financial-overview.js.map +1 -1
- package/dist/knowledge/spaces/product-canon.js.map +1 -1
- package/dist/knowledge/spaces/support-faq.js.map +1 -1
- package/dist/knowledge/spaces/uploaded-docs.js.map +1 -1
- package/dist/knowledge/spec.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js.map +1 -1
- package/dist/onboarding-base.d.ts +30 -28
- package/dist/onboarding-base.d.ts.map +1 -1
- package/dist/onboarding-base.js +1 -1
- package/dist/onboarding-base.js.map +1 -1
- package/dist/policy/engine.js.map +1 -1
- package/dist/policy/opa-adapter.d.ts.map +1 -1
- package/dist/policy/opa-adapter.js.map +1 -1
- package/dist/policy/spec.d.ts.map +1 -1
- package/dist/policy/spec.js.map +1 -1
- package/dist/presentations.d.ts +1 -0
- package/dist/presentations.d.ts.map +1 -1
- package/dist/presentations.v2.d.ts +1 -0
- package/dist/presentations.v2.d.ts.map +1 -1
- package/dist/regenerator/executor.d.ts.map +1 -1
- package/dist/regenerator/executor.js.map +1 -1
- package/dist/regenerator/service.d.ts.map +1 -1
- package/dist/regenerator/service.js.map +1 -1
- package/dist/regenerator/sinks.d.ts.map +1 -1
- package/dist/regenerator/sinks.js.map +1 -1
- package/dist/regenerator/types.d.ts.map +1 -1
- package/dist/regenerator/utils.js.map +1 -1
- package/dist/registry.d.ts +37 -9
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +1 -1
- package/dist/registry.js.map +1 -1
- package/dist/schema/dist/FieldType.js +2 -0
- package/dist/schema/dist/FieldType.js.map +1 -0
- package/dist/schema/dist/ScalarTypeEnum.js +2 -0
- package/dist/schema/dist/ScalarTypeEnum.js.map +1 -0
- package/dist/schema/{src → dist}/SchemaModel.js +1 -1
- package/dist/schema/dist/SchemaModel.js.map +1 -0
- package/dist/schema/dist/index.js +1 -0
- package/dist/server/graphql-pothos.d.ts +15 -2
- package/dist/server/graphql-pothos.d.ts.map +1 -1
- package/dist/server/graphql-pothos.js.map +1 -1
- package/dist/server/graphql-schema-export.js +1 -1
- package/dist/server/graphql-schema-export.js.map +1 -1
- package/dist/server/provider-mcp.d.ts +22 -4
- package/dist/server/provider-mcp.d.ts.map +1 -1
- package/dist/server/provider-mcp.js.map +1 -1
- package/dist/server/rest-next-app.d.ts +23 -3
- package/dist/server/rest-next-app.d.ts.map +1 -1
- package/dist/server/rest-next-app.js.map +1 -1
- package/dist/spec.d.ts +23 -0
- package/dist/spec.d.ts.map +1 -1
- package/dist/spec.js.map +1 -1
- package/dist/telemetry/anomaly.js.map +1 -1
- package/dist/telemetry/spec.d.ts.map +1 -1
- package/dist/telemetry/spec.js.map +1 -1
- package/dist/telemetry/tracker.d.ts.map +1 -1
- package/dist/telemetry/tracker.js.map +1 -1
- package/dist/tests/runner.js.map +1 -1
- package/dist/tests/spec.js.map +1 -1
- package/dist/themes.d.ts.map +1 -1
- package/dist/themes.js.map +1 -1
- package/dist/types/all.d.ts +2 -2
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/workflow/adapters/db-adapter.d.ts +30 -10
- package/dist/workflow/adapters/db-adapter.d.ts.map +1 -1
- package/dist/workflow/adapters/db-adapter.js +1 -1
- package/dist/workflow/adapters/db-adapter.js.map +1 -1
- package/dist/workflow/adapters/file-adapter.js.map +1 -1
- package/dist/workflow/adapters/index.d.ts +2 -2
- package/dist/workflow/adapters/index.js +1 -1
- package/dist/workflow/adapters/memory-store.d.ts.map +1 -1
- package/dist/workflow/adapters/memory-store.js.map +1 -1
- package/dist/workflow/expression.js.map +1 -1
- package/dist/workflow/index.d.ts +2 -2
- package/dist/workflow/index.js +1 -1
- package/dist/workflow/runner.d.ts +1 -0
- package/dist/workflow/runner.d.ts.map +1 -1
- package/dist/workflow/runner.js +1 -1
- package/dist/workflow/runner.js.map +1 -1
- package/dist/workflow/sla-monitor.d.ts +21 -0
- package/dist/workflow/sla-monitor.d.ts.map +1 -0
- package/dist/workflow/sla-monitor.js +2 -0
- package/dist/workflow/sla-monitor.js.map +1 -0
- package/dist/workflow/spec.d.ts.map +1 -1
- package/dist/workflow/spec.js.map +1 -1
- package/dist/workflow/state.d.ts +1 -0
- package/dist/workflow/state.d.ts.map +1 -1
- package/dist/workflow/validation.d.ts.map +1 -1
- package/dist/workflow/validation.js.map +1 -1
- package/package.json +181 -177
- package/dist/graphql-federation/src/index.js +0 -2
- package/dist/graphql-federation/src/index.js.map +0 -1
- package/dist/schema/src/FieldType.js +0 -2
- package/dist/schema/src/FieldType.js.map +0 -1
- package/dist/schema/src/ScalarTypeEnum.js +0 -2
- package/dist/schema/src/ScalarTypeEnum.js.map +0 -1
- package/dist/schema/src/SchemaModel.js.map +0 -1
- package/dist/schema/src/index.js +0 -1
- /package/dist/schema/{src → dist}/EnumType.js +0 -0
package/README.md
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
# @lssm/lib.contracts
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Unified specifications for Operations, Events, Presentations, and Features.
|
|
4
4
|
|
|
5
|
-
|
|
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
|
-
|
|
17
|
+
## Key Concepts
|
|
14
18
|
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
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
|
-
|
|
25
|
+
## Exports
|
|
21
26
|
|
|
22
|
-
- **
|
|
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
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
|
|
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
|
-
|
|
34
|
+
## Usage
|
|
97
35
|
|
|
98
|
-
|
|
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
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
220
|
-
// Web component presentations (user stories)
|
|
221
|
-
const WeeklyPulseQuickVote: PresentationSpec = {
|
|
50
|
+
export const CreateUser = defineCommand({
|
|
222
51
|
meta: {
|
|
223
|
-
name: '
|
|
52
|
+
name: 'user.create',
|
|
224
53
|
version: 1,
|
|
225
|
-
|
|
226
|
-
|
|
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
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
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
|
-
|
|
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
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
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
|
-
|
|
350
|
-
|
|
351
|
-
|
|
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
|
-
|
|
95
|
+
const handler = makeNextAppHandler(reg, (req) => ({ actor: 'anonymous' }));
|
|
358
96
|
|
|
359
|
-
|
|
360
|
-
|
|
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
|
+
```
|