@lssm/lib.contracts 1.42.10 → 1.43.2

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 (78) hide show
  1. package/README.md +1 -0
  2. package/dist/app-config/app-config.feature.d.ts +2 -1
  3. package/dist/app-config/contracts.d.ts +51 -51
  4. package/dist/app-config/docs/app-config.docblock.js +1 -1
  5. package/dist/app-config/events.d.ts +27 -27
  6. package/dist/app-config/lifecycle-contracts.d.ts +55 -55
  7. package/dist/app-config/runtime.d.ts +7 -4
  8. package/dist/app-config/spec.d.ts +3 -2
  9. package/dist/app-config/validation.d.ts +1 -1
  10. package/dist/client/react/feature-render.d.ts +3 -1
  11. package/dist/contract-registry/schemas.d.ts +2 -2
  12. package/dist/data-views/data-views.d.ts +5 -138
  13. package/dist/data-views/data-views.js +3 -57
  14. package/dist/data-views/index.d.ts +4 -4
  15. package/dist/data-views/index.js +3 -4
  16. package/dist/data-views/query-generator.d.ts +1 -1
  17. package/dist/data-views/registry.d.ts +51 -0
  18. package/dist/data-views/registry.js +82 -0
  19. package/dist/data-views/runtime.d.ts +2 -1
  20. package/dist/data-views/spec.d.ts +32 -0
  21. package/dist/data-views/spec.js +10 -0
  22. package/dist/data-views/types.d.ts +157 -0
  23. package/dist/data-views/types.js +0 -0
  24. package/dist/docs/index.js +3 -1
  25. package/dist/docs/tech/contracts/openapi-import.docblock.d.ts +6 -0
  26. package/dist/docs/tech/contracts/openapi-import.docblock.js +65 -0
  27. package/dist/docs/tech/presentation-runtime.docblock.js +1 -1
  28. package/dist/docs/tech/schema/README.docblock.js +1 -1
  29. package/dist/experiments/spec-resolver.d.ts +1 -1
  30. package/dist/features/index.d.ts +5 -0
  31. package/dist/features/index.js +5 -0
  32. package/dist/features/install.d.ts +22 -0
  33. package/dist/features/install.js +36 -0
  34. package/dist/features/registry.d.ts +26 -0
  35. package/dist/features/registry.js +49 -0
  36. package/dist/features/types.d.ts +88 -0
  37. package/dist/features/types.js +0 -0
  38. package/dist/features/validation.d.ts +8 -0
  39. package/dist/features/validation.js +14 -0
  40. package/dist/index.d.ts +16 -12
  41. package/dist/index.js +7 -6
  42. package/dist/install.d.ts +1 -1
  43. package/dist/integrations/integrations.feature.d.ts +2 -1
  44. package/dist/integrations/openbanking/contracts/accounts.d.ts +67 -67
  45. package/dist/integrations/openbanking/contracts/balances.d.ts +35 -35
  46. package/dist/integrations/openbanking/contracts/transactions.d.ts +49 -49
  47. package/dist/integrations/openbanking/models.d.ts +55 -55
  48. package/dist/integrations/openbanking/openbanking.feature.d.ts +2 -1
  49. package/dist/integrations/operations.d.ts +103 -103
  50. package/dist/jsonschema.d.ts +3 -4
  51. package/dist/knowledge/knowledge.feature.d.ts +2 -1
  52. package/dist/knowledge/operations.d.ts +67 -67
  53. package/dist/llm/exporters.d.ts +3 -2
  54. package/dist/llm/prompts.d.ts +1 -1
  55. package/dist/llm/types.d.ts +3 -2
  56. package/dist/markdown.d.ts +2 -2
  57. package/dist/model-registry.d.ts +1 -1
  58. package/dist/model-registry.js +14 -3
  59. package/dist/onboarding-base.d.ts +29 -29
  60. package/dist/operations/operation.d.ts +7 -1
  61. package/dist/schema-to-markdown.js +3 -0
  62. package/dist/server/contracts-adapter-input.js +36 -30
  63. package/dist/server/graphql-pothos.js +33 -26
  64. package/dist/tests/runner.js +1 -1
  65. package/dist/tests/spec.d.ts +2 -10
  66. package/dist/{docs/tech/workflows → workflow}/overview.docblock.d.ts +1 -1
  67. package/dist/{docs/tech/workflows → workflow}/overview.docblock.js +2 -2
  68. package/dist/workflow/runner.d.ts +2 -1
  69. package/dist/workflow/spec.d.ts +3 -2
  70. package/dist/workspace-config/contractsrc-schema.d.ts +81 -5
  71. package/dist/workspace-config/contractsrc-schema.js +38 -4
  72. package/dist/workspace-config/index.d.ts +2 -2
  73. package/dist/workspace-config/index.js +2 -2
  74. package/dist/workspace-config/workspace-config.docblock.d.ts +6 -0
  75. package/dist/workspace-config/workspace-config.docblock.js +45 -0
  76. package/package.json +18 -8
  77. package/dist/features.d.ts +0 -104
  78. package/dist/features.js +0 -91
package/README.md CHANGED
@@ -30,6 +30,7 @@ bun add @lssm/lib.contracts @lssm/lib.schema
30
30
  ## Exports
31
31
 
32
32
  - **Core**: `OperationSpecRegistry`, `defineCommand`, `defineQuery`, `defineEvent`.
33
+ - **Config**: `SchemaFormat` ('contractspec' | 'zod' | 'json-schema' | 'graphql').
33
34
  - **Adapters**:
34
35
  - `server/rest-next-app`: Next.js App Router adapter.
35
36
  - `server/provider-mcp`: Model Context Protocol (MCP) adapter for AI agents.
@@ -1,4 +1,5 @@
1
- import { FeatureModuleSpec } from "../features.js";
1
+ import { FeatureModuleSpec } from "../features/types.js";
2
+ import "../features/index.js";
2
3
 
3
4
  //#region src/app-config/app-config.feature.d.ts
4
5
 
@@ -1,39 +1,39 @@
1
- import "../operations/index.js";
2
1
  import { OperationSpec } from "../operations/operation.js";
3
2
  import { OperationSpecRegistry } from "../operations/registry.js";
4
- import * as _lssm_lib_schema35 from "@lssm/lib.schema";
3
+ import "../operations/index.js";
4
+ import * as _lssm_lib_schema128 from "@lssm/lib.schema";
5
5
  import { SchemaModel } from "@lssm/lib.schema";
6
6
 
7
7
  //#region src/app-config/contracts.d.ts
8
8
  declare const UpdateTenantBrandingCommand: OperationSpec<SchemaModel<{
9
9
  tenantId: {
10
- type: _lssm_lib_schema35.FieldType<string, string>;
10
+ type: _lssm_lib_schema128.FieldType<string, string>;
11
11
  isOptional: false;
12
12
  };
13
13
  appId: {
14
- type: _lssm_lib_schema35.FieldType<string, string>;
14
+ type: _lssm_lib_schema128.FieldType<string, string>;
15
15
  isOptional: false;
16
16
  };
17
17
  environment: {
18
- type: _lssm_lib_schema35.FieldType<string, string>;
18
+ type: _lssm_lib_schema128.FieldType<string, string>;
19
19
  isOptional: true;
20
20
  };
21
21
  appName: {
22
- type: _lssm_lib_schema35.FieldType<Record<string, unknown>, Record<string, unknown>>;
22
+ type: _lssm_lib_schema128.FieldType<Record<string, unknown>, Record<string, unknown>>;
23
23
  isOptional: true;
24
24
  };
25
25
  assets: {
26
26
  type: SchemaModel<{
27
27
  type: {
28
- type: _lssm_lib_schema35.FieldType<string, string>;
28
+ type: _lssm_lib_schema128.FieldType<string, string>;
29
29
  isOptional: false;
30
30
  };
31
31
  url: {
32
- type: _lssm_lib_schema35.FieldType<string, string>;
32
+ type: _lssm_lib_schema128.FieldType<string, string>;
33
33
  isOptional: false;
34
34
  };
35
35
  mimeType: {
36
- type: _lssm_lib_schema35.FieldType<string, string>;
36
+ type: _lssm_lib_schema128.FieldType<string, string>;
37
37
  isOptional: true;
38
38
  };
39
39
  }>;
@@ -41,92 +41,92 @@ declare const UpdateTenantBrandingCommand: OperationSpec<SchemaModel<{
41
41
  isArray: true;
42
42
  };
43
43
  colors: {
44
- type: _lssm_lib_schema35.FieldType<Record<string, unknown>, Record<string, unknown>>;
44
+ type: _lssm_lib_schema128.FieldType<Record<string, unknown>, Record<string, unknown>>;
45
45
  isOptional: true;
46
46
  };
47
47
  customDomain: {
48
- type: _lssm_lib_schema35.FieldType<string, string>;
48
+ type: _lssm_lib_schema128.FieldType<string, string>;
49
49
  isOptional: true;
50
50
  };
51
51
  subdomain: {
52
- type: _lssm_lib_schema35.FieldType<string, string>;
52
+ type: _lssm_lib_schema128.FieldType<string, string>;
53
53
  isOptional: true;
54
54
  };
55
55
  }>, SchemaModel<{
56
56
  success: {
57
- type: _lssm_lib_schema35.FieldType<boolean, boolean>;
57
+ type: _lssm_lib_schema128.FieldType<boolean, boolean>;
58
58
  isOptional: false;
59
59
  };
60
60
  updatedAt: {
61
- type: _lssm_lib_schema35.FieldType<Date, string>;
61
+ type: _lssm_lib_schema128.FieldType<Date, string>;
62
62
  isOptional: false;
63
63
  };
64
64
  }>, undefined>;
65
65
  declare const VerifyCustomDomainCommand: OperationSpec<SchemaModel<{
66
66
  tenantId: {
67
- type: _lssm_lib_schema35.FieldType<string, string>;
67
+ type: _lssm_lib_schema128.FieldType<string, string>;
68
68
  isOptional: false;
69
69
  };
70
70
  appId: {
71
- type: _lssm_lib_schema35.FieldType<string, string>;
71
+ type: _lssm_lib_schema128.FieldType<string, string>;
72
72
  isOptional: false;
73
73
  };
74
74
  domain: {
75
- type: _lssm_lib_schema35.FieldType<string, string>;
75
+ type: _lssm_lib_schema128.FieldType<string, string>;
76
76
  isOptional: false;
77
77
  };
78
78
  }>, SchemaModel<{
79
79
  status: {
80
- type: _lssm_lib_schema35.FieldType<string, string>;
80
+ type: _lssm_lib_schema128.FieldType<string, string>;
81
81
  isOptional: false;
82
82
  };
83
83
  message: {
84
- type: _lssm_lib_schema35.FieldType<string, string>;
84
+ type: _lssm_lib_schema128.FieldType<string, string>;
85
85
  isOptional: true;
86
86
  };
87
87
  }>, undefined>;
88
88
  declare const UpdateBlueprintTranslationCatalogCommand: OperationSpec<SchemaModel<{
89
89
  blueprintName: {
90
- type: _lssm_lib_schema35.FieldType<string, string>;
90
+ type: _lssm_lib_schema128.FieldType<string, string>;
91
91
  isOptional: false;
92
92
  };
93
93
  blueprintVersion: {
94
- type: _lssm_lib_schema35.FieldType<number, number>;
94
+ type: _lssm_lib_schema128.FieldType<number, number>;
95
95
  isOptional: false;
96
96
  };
97
97
  catalogName: {
98
- type: _lssm_lib_schema35.FieldType<string, string>;
98
+ type: _lssm_lib_schema128.FieldType<string, string>;
99
99
  isOptional: false;
100
100
  };
101
101
  catalogVersion: {
102
- type: _lssm_lib_schema35.FieldType<number, number>;
102
+ type: _lssm_lib_schema128.FieldType<number, number>;
103
103
  isOptional: false;
104
104
  };
105
105
  defaultLocale: {
106
- type: _lssm_lib_schema35.FieldType<string, string>;
106
+ type: _lssm_lib_schema128.FieldType<string, string>;
107
107
  isOptional: false;
108
108
  };
109
109
  supportedLocales: {
110
- type: _lssm_lib_schema35.FieldType<string, string>;
110
+ type: _lssm_lib_schema128.FieldType<string, string>;
111
111
  isOptional: false;
112
112
  isArray: true;
113
113
  };
114
114
  entries: {
115
115
  type: SchemaModel<{
116
116
  key: {
117
- type: _lssm_lib_schema35.FieldType<string, string>;
117
+ type: _lssm_lib_schema128.FieldType<string, string>;
118
118
  isOptional: false;
119
119
  };
120
120
  locale: {
121
- type: _lssm_lib_schema35.FieldType<string, string>;
121
+ type: _lssm_lib_schema128.FieldType<string, string>;
122
122
  isOptional: false;
123
123
  };
124
124
  value: {
125
- type: _lssm_lib_schema35.FieldType<string, string>;
125
+ type: _lssm_lib_schema128.FieldType<string, string>;
126
126
  isOptional: false;
127
127
  };
128
128
  context: {
129
- type: _lssm_lib_schema35.FieldType<string, string>;
129
+ type: _lssm_lib_schema128.FieldType<string, string>;
130
130
  isOptional: true;
131
131
  };
132
132
  }>;
@@ -135,39 +135,39 @@ declare const UpdateBlueprintTranslationCatalogCommand: OperationSpec<SchemaMode
135
135
  };
136
136
  }>, SchemaModel<{
137
137
  success: {
138
- type: _lssm_lib_schema35.FieldType<boolean, boolean>;
138
+ type: _lssm_lib_schema128.FieldType<boolean, boolean>;
139
139
  isOptional: false;
140
140
  };
141
141
  updatedAt: {
142
- type: _lssm_lib_schema35.FieldType<Date, string>;
142
+ type: _lssm_lib_schema128.FieldType<Date, string>;
143
143
  isOptional: false;
144
144
  };
145
145
  }>, undefined>;
146
146
  declare const UpdateTenantTranslationOverridesCommand: OperationSpec<SchemaModel<{
147
147
  tenantId: {
148
- type: _lssm_lib_schema35.FieldType<string, string>;
148
+ type: _lssm_lib_schema128.FieldType<string, string>;
149
149
  isOptional: false;
150
150
  };
151
151
  appId: {
152
- type: _lssm_lib_schema35.FieldType<string, string>;
152
+ type: _lssm_lib_schema128.FieldType<string, string>;
153
153
  isOptional: false;
154
154
  };
155
155
  entries: {
156
156
  type: SchemaModel<{
157
157
  key: {
158
- type: _lssm_lib_schema35.FieldType<string, string>;
158
+ type: _lssm_lib_schema128.FieldType<string, string>;
159
159
  isOptional: false;
160
160
  };
161
161
  locale: {
162
- type: _lssm_lib_schema35.FieldType<string, string>;
162
+ type: _lssm_lib_schema128.FieldType<string, string>;
163
163
  isOptional: false;
164
164
  };
165
165
  value: {
166
- type: _lssm_lib_schema35.FieldType<string, string>;
166
+ type: _lssm_lib_schema128.FieldType<string, string>;
167
167
  isOptional: false;
168
168
  };
169
169
  context: {
170
- type: _lssm_lib_schema35.FieldType<string, string>;
170
+ type: _lssm_lib_schema128.FieldType<string, string>;
171
171
  isOptional: true;
172
172
  };
173
173
  }>;
@@ -175,67 +175,67 @@ declare const UpdateTenantTranslationOverridesCommand: OperationSpec<SchemaModel
175
175
  isArray: true;
176
176
  };
177
177
  defaultLocale: {
178
- type: _lssm_lib_schema35.FieldType<string, string>;
178
+ type: _lssm_lib_schema128.FieldType<string, string>;
179
179
  isOptional: true;
180
180
  };
181
181
  enabledLocales: {
182
- type: _lssm_lib_schema35.FieldType<string, string>;
182
+ type: _lssm_lib_schema128.FieldType<string, string>;
183
183
  isOptional: true;
184
184
  isArray: true;
185
185
  };
186
186
  }>, SchemaModel<{
187
187
  success: {
188
- type: _lssm_lib_schema35.FieldType<boolean, boolean>;
188
+ type: _lssm_lib_schema128.FieldType<boolean, boolean>;
189
189
  isOptional: false;
190
190
  };
191
191
  updatedAt: {
192
- type: _lssm_lib_schema35.FieldType<Date, string>;
192
+ type: _lssm_lib_schema128.FieldType<Date, string>;
193
193
  isOptional: false;
194
194
  };
195
195
  }>, undefined>;
196
196
  declare const GetResolvedBrandingQuery: OperationSpec<SchemaModel<{
197
197
  tenantId: {
198
- type: _lssm_lib_schema35.FieldType<string, string>;
198
+ type: _lssm_lib_schema128.FieldType<string, string>;
199
199
  isOptional: false;
200
200
  };
201
201
  appId: {
202
- type: _lssm_lib_schema35.FieldType<string, string>;
202
+ type: _lssm_lib_schema128.FieldType<string, string>;
203
203
  isOptional: false;
204
204
  };
205
205
  environment: {
206
- type: _lssm_lib_schema35.FieldType<string, string>;
206
+ type: _lssm_lib_schema128.FieldType<string, string>;
207
207
  isOptional: true;
208
208
  };
209
209
  }>, SchemaModel<{
210
210
  branding: {
211
- type: _lssm_lib_schema35.FieldType<Record<string, unknown>, Record<string, unknown>>;
211
+ type: _lssm_lib_schema128.FieldType<Record<string, unknown>, Record<string, unknown>>;
212
212
  isOptional: false;
213
213
  };
214
214
  }>, undefined>;
215
215
  declare const ResolveMessageQuery: OperationSpec<SchemaModel<{
216
216
  tenantId: {
217
- type: _lssm_lib_schema35.FieldType<string, string>;
217
+ type: _lssm_lib_schema128.FieldType<string, string>;
218
218
  isOptional: false;
219
219
  };
220
220
  appId: {
221
- type: _lssm_lib_schema35.FieldType<string, string>;
221
+ type: _lssm_lib_schema128.FieldType<string, string>;
222
222
  isOptional: false;
223
223
  };
224
224
  locale: {
225
- type: _lssm_lib_schema35.FieldType<string, string>;
225
+ type: _lssm_lib_schema128.FieldType<string, string>;
226
226
  isOptional: false;
227
227
  };
228
228
  key: {
229
- type: _lssm_lib_schema35.FieldType<string, string>;
229
+ type: _lssm_lib_schema128.FieldType<string, string>;
230
230
  isOptional: false;
231
231
  };
232
232
  }>, SchemaModel<{
233
233
  value: {
234
- type: _lssm_lib_schema35.FieldType<string, string>;
234
+ type: _lssm_lib_schema128.FieldType<string, string>;
235
235
  isOptional: true;
236
236
  };
237
237
  source: {
238
- type: _lssm_lib_schema35.FieldType<string, string>;
238
+ type: _lssm_lib_schema128.FieldType<string, string>;
239
239
  isOptional: true;
240
240
  };
241
241
  }>, undefined>;
@@ -13,7 +13,7 @@ const tech_contracts_app_config_DocBlocks = [{
13
13
  "contracts",
14
14
  "app-config"
15
15
  ],
16
- body: "## App Configuration Layers\n\nApp orchestration is split into three explicit layers:\n\n1. **AppBlueprintSpec** – global, versioned description of what an app can look like. Stored in Git, no tenant/environment data.\n2. **TenantAppConfig** – tenant/environment overrides that the future Studio edits. Stored per tenant (DB/contract), mutable at runtime.\n3. **ResolvedAppConfig** – pure, merged view consumed by the runtime. Derived in-memory from a blueprint + tenant config.\n\n- Types & registry: `packages/libs/contracts/src/app-config/spec.ts`\n- Resolution helpers: `packages/libs/contracts/src/app-config/runtime.ts`\n- CLI wizard (blueprint scaffolding): `contractspec create app-config`\n\n### 1. AppBlueprintSpec\n\n```ts\nexport interface AppBlueprintSpec {\n meta: AppBlueprintMeta; // { name, version, appId, ownership }\n capabilities?: { enabled?: CapabilityRef[]; disabled?: CapabilityRef[] };\n features?: { include?: FeatureRef[]; exclude?: FeatureRef[] };\n integrationSlots?: AppIntegrationSlot[];\n branding?: BrandingDefaults;\n dataViews?: Record<string, SpecPointer>;\n workflows?: Record<string, SpecPointer>;\n policies?: PolicyRef[];\n theme?: AppThemeBinding;\n telemetry?: TelemetryBinding;\n experiments?: { active?: ExperimentRef[]; paused?: ExperimentRef[] };\n featureFlags?: FeatureFlagState[];\n routes?: AppRouteConfig[];\n notes?: string;\n}\n```\n\nRegister blueprints with `AppBlueprintRegistry`. Blueprints only capture the default/global experience.\n\n- **Integration slots** declare the categories and capability requirements an app expects (e.g. `\"primary-payments\"` must be a payments provider that supports managed or BYOK credentials). Slots never include secrets; tenants bind concrete connections later.\n- **Branding defaults** provide message-key based names, placeholder assets, and theme token references that downstream tenants can override.\n\n### 2. TenantAppConfig\n\n```ts\nexport interface TenantAppConfig {\n meta: TenantAppConfigMeta; // { id, tenantId, appId, blueprintName/version, environment?, version, timestamps }\n capabilities?: { enable?: CapabilityRef[]; disable?: CapabilityRef[] };\n features?: { include?: FeatureRef[]; exclude?: FeatureRef[] };\n dataViewOverrides?: TenantSpecOverride[];\n workflowOverrides?: TenantSpecOverride[];\n additionalPolicies?: PolicyRef[];\n themeOverride?: { primary?: ThemeRef | null; fallbacks?: ThemeRef[] };\n telemetryOverride?: { spec?: SpecPointer | null; disabledEvents?: string[] };\n experiments?: { active?: ExperimentRef[]; paused?: ExperimentRef[] };\n featureFlags?: FeatureFlagState[];\n routeOverrides?: TenantRouteOverride[];\n integrations?: AppIntegrationBinding[];\n knowledge?: AppKnowledgeBinding[];\n branding?: TenantBrandingConfig;\n notes?: string;\n}\n```\n\nThis object represents what a tenant edits via the Studio (stored in DB/contracts later).\n\n- **AppIntegrationBinding** now maps `slotId` → `connectionId` (plus optional workflow scopes). It no longer carries capability lists; those are defined once in the slot.\n- **TenantBrandingConfig** allows per-tenant names, assets, and domain overrides while keeping secrets and large files out of blueprints.\n\n### 3. ResolvedAppConfig\n\n```ts\nexport interface ResolvedAppConfig {\n appId: string;\n tenantId: string;\n environment?: string;\n blueprintName: string;\n blueprintVersion: number;\n configVersion: number;\n capabilities: { enabled: CapabilityRef[]; disabled: CapabilityRef[] };\n features: { include: FeatureRef[]; exclude: FeatureRef[] };\n dataViews: Record<string, SpecPointer>;\n workflows: Record<string, SpecPointer>;\n policies: PolicyRef[];\n theme?: AppThemeBinding;\n telemetry?: TelemetryBinding;\n experiments: { catalog: ExperimentRef[]; active: ExperimentRef[]; paused: ExperimentRef[] };\n featureFlags: FeatureFlagState[];\n routes: AppRouteConfig[];\n integrations: ResolvedIntegration[];\n knowledge: ResolvedKnowledge[];\n branding: ResolvedBranding;\n notes?: string;\n}\n```\n\nUse `resolveAppConfig(blueprint, tenant)` to produce this merged view. No IO, no registry lookups—pure data merge.\n\n- `resolveAppConfig` validates slot/category/mode constraints when `integrationConnections` and `integrationSpecs` are provided.\n- `branding` merges blueprint defaults with tenant overrides, producing a runtime-friendly shape (resolved asset URLs, color values, and effective domain).\n\n### Materializing specs\n\n`composeAppConfig(blueprint, tenant, registries, { strict })`:\n\n1. Calls `resolveAppConfig` to build the merged pointers.\n2. Looks up referenced specs in the provided registries.\n3. Returns:\n - `resolved` – the merged pointer view\n - `capabilities`, `features`, `dataViews`, `workflows`, `policies`, `theme`, `telemetry`, `experiments`\n - `missing` – unresolved references (strict mode throws).\n\n```ts\nconst blueprint = blueprintRegistry.get('core.app', 1)!;\nconst tenant = loadTenantConfigFromDB();\n\nconst composition = composeAppConfig(blueprint, tenant, {\n capabilities,\n features,\n dataViews,\n workflows,\n policies,\n themes,\n telemetry,\n experiments,\n});\n\nif (composition.missing.length) {\n console.warn('Unresolved references', composition.missing);\n}\n```\n\n### CLI workflow\n\n```\ncontractspec create app-config\n```\n\nGenerates an `AppBlueprintSpec`. A separate flow will later scaffold tenant configs.\n\n### Best practices\n\n1. Keep blueprint and tenant versions monotonic; bump when referenced spec versions change.\n2. Favor stable slot keys (e.g. `dataViews.dashboard`) to align with Studio UX.\n3. Reference telemetry and experiments declared in their respective specs to maintain observability.\n4. Run `resolveAppConfig` in pure unit tests and `composeAppConfig(..., { strict: true })` in CI to catch drift early.\n5. Pair resolved configs with `TestSpec` scenarios to guard tenant experiences end-to-end.\n\n### Static validation\n\nUse the validation helpers in `@lssm/lib.contracts/app-config/validation` to keep blueprints and tenant configs safe before publish time.\n\n```ts\nimport {\n validateConfig,\n validateBlueprint,\n validateTenantConfig,\n validateResolvedConfig,\n} from '@lssm/lib.contracts/app-config/validation';\n\nconst context = {\n integrationSpecs,\n tenantConnections,\n knowledgeSpaces,\n knowledgeSources,\n translationCatalogs: {\n blueprint: blueprintCatalog,\n platform: platformCatalog,\n },\n existingConfigs,\n};\n\nconst blueprintReport = validateBlueprint(blueprint, context);\nconst tenantReport = validateTenantConfig(blueprint, tenant, context);\nconst publishReport = validateConfig(blueprint, tenant, context);\n```\n\n- `ValidationResult` exposes `valid`, plus structured `errors`, `warnings`, and `info`.\n- Core rules cover capability references, integration slot bindings (category/ownership/capabilities), knowledge bindings, branding constraints (domains + assets), and translation coverage.\n- Call `validateBlueprint` in CI when committing new specs, and `validateConfig` before promoting/publishing a tenant config.\n- `validateResolvedConfig` can be used as a runtime pre-flight check when composing full configs for workflows.\n- CLI usage example (blueprint + tenant):\n\n```\npnpm contractspec validate \\\n packages/examples/integration-stripe/blueprint.ts \\\n --blueprint packages/examples/integration-stripe/blueprint.ts \\\n --tenant-config packages/examples/integration-stripe/tenant.ts\n```\n- Repository script:\n\n```\nbun run validate:blueprints\n```\n\nRuns the static validator for the sample blueprints/tenants and is wired into CI.\n\n\n### Lifecycle types & events\n\nTo model multi-step configuration changes, use the lifecycle helpers exported from `@lssm/lib.contracts/app-config`:\n\n```ts\nimport type {\n ConfigStatus,\n TenantAppConfigVersion,\n ConfigTransition,\n} from '@lssm/lib.contracts/app-config';\nimport {\n ConfigDraftCreatedEvent,\n ConfigPromotedToPreviewEvent,\n ConfigPublishedEvent,\n ConfigRolledBackEvent,\n} from '@lssm/lib.contracts/app-config';\n```\n\n- `ConfigStatus` enumerates the canonical states: `draft`, `preview`, `published`, `archived`, `superseded`.\n- `TenantAppConfigMeta` now includes lifecycle metadata (`status`, `createdBy`, `publishedBy`, `publishedAt`, `rolledBackFrom`, `rolledBackTo`, `changeSummary`).\n- `TenantAppConfigVersion` couples the lifecycle-aware metadata with the `TenantAppConfig` payload for history views.\n- `ConfigTransition` captures state changes with actor, timestamp, and optional reason.\n- Lifecycle events (`app_config.draft_created`, `app_config.promoted_to_preview`, `app_config.published`, `app_config.rolled_back`) standardize observability across services.\n- Lifecycle contract specs (`appConfig.lifecycle.*`) expose typed commands/queries for create → preview → publish → rollback flows.\n\n"
16
+ body: "## App Configuration Layers\n\nApp orchestration is split into three explicit layers:\n\n1. **AppBlueprintSpec** – global, versioned description of what an app can look like. Stored in Git, no tenant/environment data.\n2. **TenantAppConfig** – tenant/environment overrides that the future Studio edits. Stored per tenant (DB/contract), mutable at runtime.\n3. **ResolvedAppConfig** – pure, merged view consumed by the runtime. Derived in-memory from a blueprint + tenant config.\n\n- Types & registry: `packages/libs/contracts/src/app-config/spec.ts`\n- Resolution helpers: `packages/libs/contracts/src/app-config/runtime.ts`\n- CLI wizard (blueprint scaffolding): `contractspec create app-config`\n\n### 1. AppBlueprintSpec\n\n```ts\nexport interface AppBlueprintSpec {\n meta: AppBlueprintMeta; // { name, version, appId, ownership }\n capabilities?: { enabled?: CapabilityRef[]; disabled?: CapabilityRef[] };\n features?: { include?: FeatureRef[]; exclude?: FeatureRef[] };\n integrationSlots?: AppIntegrationSlot[];\n branding?: BrandingDefaults;\n dataViews?: Record<string, SpecPointer>;\n workflows?: Record<string, SpecPointer>;\n policies?: PolicyRef[];\n theme?: AppThemeBinding;\n telemetry?: TelemetryBinding;\n experiments?: { active?: ExperimentRef[]; paused?: ExperimentRef[] };\n featureFlags?: FeatureFlagState[];\n routes?: AppRouteConfig[];\n notes?: string;\n}\n```\n\nRegister blueprints with `AppBlueprintRegistry`. Blueprints only capture the default/global experience.\n\n- **Integration slots** declare the categories and capability requirements an app expects (e.g. `\"primary-payments\"` must be a payments provider that supports managed or BYOK credentials). Slots never include secrets; tenants bind concrete connections later.\n- **Branding defaults** provide message-key based names, placeholder assets, and theme token references that downstream tenants can override.\n\n### 2. TenantAppConfig\n\n```ts\nexport interface TenantAppConfig {\n meta: TenantAppConfigMeta; // { id, tenantId, appId, blueprintName/version, environment?, version, timestamps }\n capabilities?: { enable?: CapabilityRef[]; disable?: CapabilityRef[] };\n features?: { include?: FeatureRef[]; exclude?: FeatureRef[] };\n dataViewOverrides?: TenantSpecOverride[];\n workflowOverrides?: TenantSpecOverride[];\n additionalPolicies?: PolicyRef[];\n themeOverride?: { primary?: ThemeRef | null; fallbacks?: ThemeRef[] };\n telemetryOverride?: { spec?: SpecPointer | null; disabledEvents?: string[] };\n experiments?: { active?: ExperimentRef[]; paused?: ExperimentRef[] };\n featureFlags?: FeatureFlagState[];\n routeOverrides?: TenantRouteOverride[];\n integrations?: AppIntegrationBinding[];\n knowledge?: AppKnowledgeBinding[];\n branding?: TenantBrandingConfig;\n notes?: string;\n}\n```\n\nThis object represents what a tenant edits via the Studio (stored in DB/contracts later).\n\n- **AppIntegrationBinding** now maps `slotId` → `connectionId` (plus optional workflow scopes). It no longer carries capability lists; those are defined once in the slot.\n- **TenantBrandingConfig** allows per-tenant names, assets, and domain overrides while keeping secrets and large files out of blueprints.\n\n### 3. ResolvedAppConfig\n\n```ts\nexport interface ResolvedAppConfig {\n appId: string;\n tenantId: string;\n environment?: string;\n blueprintName: string;\n blueprintVersion: number;\n configVersion: number;\n capabilities: { enabled: CapabilityRef[]; disabled: CapabilityRef[] };\n features: { include: FeatureRef[]; exclude: FeatureRef[] };\n dataViews: Record<string, SpecPointer>;\n workflows: Record<string, SpecPointer>;\n policies: PolicyRef[];\n theme?: AppThemeBinding;\n telemetry?: TelemetryBinding;\n experiments: { catalog: ExperimentRef[]; active: ExperimentRef[]; paused: ExperimentRef[] };\n featureFlags: FeatureFlagState[];\n routes: AppRouteConfig[];\n integrations: ResolvedIntegration[];\n knowledge: ResolvedKnowledge[];\n branding: ResolvedBranding;\n notes?: string;\n}\n```\n\nUse `resolveAppConfig(blueprint, tenant)` to produce this merged view. No IO, no registry lookups—pure data merge.\n\n- `resolveAppConfig` validates slot/category/mode constraints when `integrationConnections` and `integrationSpecs` are provided.\n- `branding` merges blueprint defaults with tenant overrides, producing a runtime-friendly shape (resolved asset URLs, color values, and effective domain).\n\n### Materializing specs\n\n`composeAppConfig(blueprint, tenant, registries, { strict })`:\n\n1. Calls `resolveAppConfig` to build the merged pointers.\n2. Looks up referenced specs in the provided registries.\n3. Returns:\n - `resolved` – the merged pointer view\n - `capabilities`, `features`, `dataViews`, `workflows`, `policies`, `theme`, `telemetry`, `experiments`\n - `missing` – unresolved references (strict mode throws).\n\n```ts\nconst blueprint = blueprintRegistry.get('core.app', 1)!;\nconst tenant = loadTenantConfigFromDB();\n\nconst composition = composeAppConfig(blueprint, tenant, {\n capabilities,\n features,\n dataViews,\n workflows,\n policies,\n themes,\n telemetry,\n experiments,\n});\n\nif (composition.missing.length) {\n console.warn('Unresolved references', composition.missing);\n}\n```\n\n### CLI workflow\n\n```\ncontractspec create app-config\n```\n\nGenerates an `AppBlueprintSpec`. A separate flow will later scaffold tenant configs.\n\n### Best practices\n\n1. Keep blueprint and tenant versions monotonic; bump when referenced spec versions change.\n2. Favor stable slot keys (e.g. `dataViews.dashboard`) to align with Studio UX.\n3. Reference telemetry and experiments declared in their respective specs to maintain observability.\n4. Run `resolveAppConfig` in pure unit tests and `composeAppConfig(..., { strict: true })` in CI to catch drift early.\n5. Pair resolved configs with `TestSpec` scenarios to guard tenant experiences end-to-end.\n\n### Static validation\n\nUse the validation helpers in `@lssm/lib.contracts/app-config/validation` to keep blueprints and tenant configs safe before publish time.\n\n```ts\nimport {\n validateConfig,\n validateBlueprint,\n validateTenantConfig,\n validateResolvedConfig,\n} from '@lssm/lib.contracts/app-config/validation';\n\nconst context = {\n integrationSpecs,\n tenantConnections,\n knowledgeSpaces,\n knowledgeSources,\n translationCatalogs: {\n blueprint: blueprintCatalog,\n platform: platformCatalog,\n },\n existingConfigs,\n};\n\nconst blueprintReport = validateBlueprint(blueprint, context);\nconst tenantReport = validateTenantConfig(blueprint, tenant, context);\nconst publishReport = validateConfig(blueprint, tenant, context);\n```\n\n- `ValidationResult` exposes `valid`, plus structured `errors`, `warnings`, and `info`.\n- Core rules cover capability references, integration slot bindings (category/ownership/capabilities), knowledge bindings, branding constraints (domains + assets), and translation coverage.\n- Call `validateBlueprint` in CI when committing new specs, and `validateConfig` before promoting/publishing a tenant config.\n- `validateResolvedConfig` can be used as a runtime pre-flight check when composing full configs for workflows.\n- CLI usage example (blueprint + tenant):\n\n```\nbuncontractspec validate \\\n packages/examples/integration-stripe/blueprint.ts \\\n --blueprint packages/examples/integration-stripe/blueprint.ts \\\n --tenant-config packages/examples/integration-stripe/tenant.ts\n```\n- Repository script:\n\n```\nbun run validate:blueprints\n```\n\nRuns the static validator for the sample blueprints/tenants and is wired into CI.\n\n\n### Lifecycle types & events\n\nTo model multi-step configuration changes, use the lifecycle helpers exported from `@lssm/lib.contracts/app-config`:\n\n```ts\nimport type {\n ConfigStatus,\n TenantAppConfigVersion,\n ConfigTransition,\n} from '@lssm/lib.contracts/app-config';\nimport {\n ConfigDraftCreatedEvent,\n ConfigPromotedToPreviewEvent,\n ConfigPublishedEvent,\n ConfigRolledBackEvent,\n} from '@lssm/lib.contracts/app-config';\n```\n\n- `ConfigStatus` enumerates the canonical states: `draft`, `preview`, `published`, `archived`, `superseded`.\n- `TenantAppConfigMeta` now includes lifecycle metadata (`status`, `createdBy`, `publishedBy`, `publishedAt`, `rolledBackFrom`, `rolledBackTo`, `changeSummary`).\n- `TenantAppConfigVersion` couples the lifecycle-aware metadata with the `TenantAppConfig` payload for history views.\n- `ConfigTransition` captures state changes with actor, timestamp, and optional reason.\n- Lifecycle events (`app_config.draft_created`, `app_config.promoted_to_preview`, `app_config.published`, `app_config.rolled_back`) standardize observability across services.\n- Lifecycle contract specs (`appConfig.lifecycle.*`) expose typed commands/queries for create → preview → publish → rollback flows.\n\n"
17
17
  }];
18
18
  registerDocBlocks(tech_contracts_app_config_DocBlocks);
19
19
 
@@ -1,120 +1,120 @@
1
1
  import { EventSpec } from "../events.js";
2
2
  import "../index.js";
3
- import * as _lssm_lib_schema84 from "@lssm/lib.schema";
3
+ import * as _lssm_lib_schema177 from "@lssm/lib.schema";
4
4
  import { SchemaModel } from "@lssm/lib.schema";
5
5
 
6
6
  //#region src/app-config/events.d.ts
7
7
  declare const ConfigDraftCreatedEvent: EventSpec<SchemaModel<{
8
8
  tenantId: {
9
- type: _lssm_lib_schema84.FieldType<string, string>;
9
+ type: _lssm_lib_schema177.FieldType<string, string>;
10
10
  isOptional: false;
11
11
  };
12
12
  appId: {
13
- type: _lssm_lib_schema84.FieldType<string, string>;
13
+ type: _lssm_lib_schema177.FieldType<string, string>;
14
14
  isOptional: false;
15
15
  };
16
16
  version: {
17
- type: _lssm_lib_schema84.FieldType<number, number>;
17
+ type: _lssm_lib_schema177.FieldType<number, number>;
18
18
  isOptional: false;
19
19
  };
20
20
  blueprintName: {
21
- type: _lssm_lib_schema84.FieldType<string, string>;
21
+ type: _lssm_lib_schema177.FieldType<string, string>;
22
22
  isOptional: false;
23
23
  };
24
24
  blueprintVersion: {
25
- type: _lssm_lib_schema84.FieldType<number, number>;
25
+ type: _lssm_lib_schema177.FieldType<number, number>;
26
26
  isOptional: false;
27
27
  };
28
28
  createdBy: {
29
- type: _lssm_lib_schema84.FieldType<string, string>;
29
+ type: _lssm_lib_schema177.FieldType<string, string>;
30
30
  isOptional: false;
31
31
  };
32
32
  clonedFrom: {
33
- type: _lssm_lib_schema84.FieldType<number, number>;
33
+ type: _lssm_lib_schema177.FieldType<number, number>;
34
34
  isOptional: true;
35
35
  };
36
36
  }>>;
37
37
  declare const ConfigPromotedToPreviewEvent: EventSpec<SchemaModel<{
38
38
  tenantId: {
39
- type: _lssm_lib_schema84.FieldType<string, string>;
39
+ type: _lssm_lib_schema177.FieldType<string, string>;
40
40
  isOptional: false;
41
41
  };
42
42
  appId: {
43
- type: _lssm_lib_schema84.FieldType<string, string>;
43
+ type: _lssm_lib_schema177.FieldType<string, string>;
44
44
  isOptional: false;
45
45
  };
46
46
  version: {
47
- type: _lssm_lib_schema84.FieldType<number, number>;
47
+ type: _lssm_lib_schema177.FieldType<number, number>;
48
48
  isOptional: false;
49
49
  };
50
50
  promotedBy: {
51
- type: _lssm_lib_schema84.FieldType<string, string>;
51
+ type: _lssm_lib_schema177.FieldType<string, string>;
52
52
  isOptional: false;
53
53
  };
54
54
  warnings: {
55
- type: _lssm_lib_schema84.FieldType<string, string>;
55
+ type: _lssm_lib_schema177.FieldType<string, string>;
56
56
  isOptional: true;
57
57
  isArray: true;
58
58
  };
59
59
  }>>;
60
60
  declare const ConfigPublishedEvent: EventSpec<SchemaModel<{
61
61
  tenantId: {
62
- type: _lssm_lib_schema84.FieldType<string, string>;
62
+ type: _lssm_lib_schema177.FieldType<string, string>;
63
63
  isOptional: false;
64
64
  };
65
65
  appId: {
66
- type: _lssm_lib_schema84.FieldType<string, string>;
66
+ type: _lssm_lib_schema177.FieldType<string, string>;
67
67
  isOptional: false;
68
68
  };
69
69
  version: {
70
- type: _lssm_lib_schema84.FieldType<number, number>;
70
+ type: _lssm_lib_schema177.FieldType<number, number>;
71
71
  isOptional: false;
72
72
  };
73
73
  previousVersion: {
74
- type: _lssm_lib_schema84.FieldType<number, number>;
74
+ type: _lssm_lib_schema177.FieldType<number, number>;
75
75
  isOptional: true;
76
76
  };
77
77
  publishedBy: {
78
- type: _lssm_lib_schema84.FieldType<string, string>;
78
+ type: _lssm_lib_schema177.FieldType<string, string>;
79
79
  isOptional: false;
80
80
  };
81
81
  changeSummary: {
82
- type: _lssm_lib_schema84.FieldType<string, string>;
82
+ type: _lssm_lib_schema177.FieldType<string, string>;
83
83
  isOptional: true;
84
84
  };
85
85
  changedSections: {
86
- type: _lssm_lib_schema84.FieldType<string, string>;
86
+ type: _lssm_lib_schema177.FieldType<string, string>;
87
87
  isOptional: true;
88
88
  isArray: true;
89
89
  };
90
90
  }>>;
91
91
  declare const ConfigRolledBackEvent: EventSpec<SchemaModel<{
92
92
  tenantId: {
93
- type: _lssm_lib_schema84.FieldType<string, string>;
93
+ type: _lssm_lib_schema177.FieldType<string, string>;
94
94
  isOptional: false;
95
95
  };
96
96
  appId: {
97
- type: _lssm_lib_schema84.FieldType<string, string>;
97
+ type: _lssm_lib_schema177.FieldType<string, string>;
98
98
  isOptional: false;
99
99
  };
100
100
  newVersion: {
101
- type: _lssm_lib_schema84.FieldType<number, number>;
101
+ type: _lssm_lib_schema177.FieldType<number, number>;
102
102
  isOptional: false;
103
103
  };
104
104
  rolledBackFrom: {
105
- type: _lssm_lib_schema84.FieldType<number, number>;
105
+ type: _lssm_lib_schema177.FieldType<number, number>;
106
106
  isOptional: false;
107
107
  };
108
108
  rolledBackTo: {
109
- type: _lssm_lib_schema84.FieldType<number, number>;
109
+ type: _lssm_lib_schema177.FieldType<number, number>;
110
110
  isOptional: false;
111
111
  };
112
112
  rolledBackBy: {
113
- type: _lssm_lib_schema84.FieldType<string, string>;
113
+ type: _lssm_lib_schema177.FieldType<string, string>;
114
114
  isOptional: false;
115
115
  };
116
116
  reason: {
117
- type: _lssm_lib_schema84.FieldType<string, string>;
117
+ type: _lssm_lib_schema177.FieldType<string, string>;
118
118
  isOptional: false;
119
119
  };
120
120
  }>>;