@contractspec/example.personalization 3.7.7 → 3.7.12

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.
@@ -2,40 +2,46 @@ $ contractspec-bun-build prebuild
2
2
  $ bun run prebuild && bun run build:bundle && bun run build:types
3
3
  $ contractspec-bun-build prebuild
4
4
  $ contractspec-bun-build transpile
5
- [contractspec-bun-build] transpile target=bun root=src entries=8 noBundle=false
6
- Bundled 8 modules in 5ms
5
+ [contractspec-bun-build] transpile target=bun root=src entries=10 noBundle=false
6
+ Bundled 10 modules in 13ms
7
7
 
8
- ./behavior-tracking.js 1.33 KB (entry point)
9
- ./index.js 7.60 KB (entry point)
10
- docs/index.js 1.48 KB (entry point)
11
- docs/personalization.docblock.js 1.48 KB (entry point)
12
- ./example.js 0.99 KB (entry point)
13
- ./overlay-customization.js 1.53 KB (entry point)
14
- ./personalization.feature.js 0.71 KB (entry point)
15
- ./workflow-extension.js 1.59 KB (entry point)
8
+ ./behavior-tracking.js 1.33 KB (entry point)
9
+ ./index.js 10.57 KB (entry point)
10
+ ./personalization.theme.js 1.35 KB (entry point)
11
+ ./workflow-extension.js 1.59 KB (entry point)
12
+ docs/index.js 1.48 KB (entry point)
13
+ docs/personalization.docblock.js 1.48 KB (entry point)
14
+ ./example.js 0.99 KB (entry point)
15
+ ./overlay-customization.js 1.53 KB (entry point)
16
+ ./personalization.experiment.js 1.60 KB (entry point)
17
+ ./personalization.feature.js 0.71 KB (entry point)
16
18
 
17
- [contractspec-bun-build] transpile target=node root=src entries=8 noBundle=false
18
- Bundled 8 modules in 5ms
19
+ [contractspec-bun-build] transpile target=node root=src entries=10 noBundle=false
20
+ Bundled 10 modules in 12ms
19
21
 
20
- ./behavior-tracking.js 1.32 KB (entry point)
21
- ./index.js 7.59 KB (entry point)
22
- docs/index.js 1.47 KB (entry point)
23
- docs/personalization.docblock.js 1.47 KB (entry point)
24
- ./example.js 0.99 KB (entry point)
25
- ./overlay-customization.js 1.52 KB (entry point)
26
- ./personalization.feature.js 0.70 KB (entry point)
27
- ./workflow-extension.js 1.58 KB (entry point)
22
+ ./behavior-tracking.js 1.32 KB (entry point)
23
+ ./index.js 10.56 KB (entry point)
24
+ ./personalization.theme.js 1.34 KB (entry point)
25
+ ./workflow-extension.js 1.58 KB (entry point)
26
+ docs/index.js 1.47 KB (entry point)
27
+ docs/personalization.docblock.js 1.47 KB (entry point)
28
+ ./example.js 0.99 KB (entry point)
29
+ ./overlay-customization.js 1.52 KB (entry point)
30
+ ./personalization.experiment.js 1.60 KB (entry point)
31
+ ./personalization.feature.js 0.70 KB (entry point)
28
32
 
29
- [contractspec-bun-build] transpile target=browser root=src entries=8 noBundle=false
30
- Bundled 8 modules in 17ms
33
+ [contractspec-bun-build] transpile target=browser root=src entries=10 noBundle=false
34
+ Bundled 10 modules in 8ms
31
35
 
32
- ./behavior-tracking.js 1.32 KB (entry point)
33
- ./index.js 7.59 KB (entry point)
34
- docs/index.js 1.47 KB (entry point)
35
- docs/personalization.docblock.js 1.47 KB (entry point)
36
- ./example.js 0.99 KB (entry point)
37
- ./overlay-customization.js 1.52 KB (entry point)
38
- ./personalization.feature.js 0.70 KB (entry point)
39
- ./workflow-extension.js 1.58 KB (entry point)
36
+ ./behavior-tracking.js 1.32 KB (entry point)
37
+ ./index.js 10.56 KB (entry point)
38
+ ./personalization.theme.js 1.34 KB (entry point)
39
+ ./workflow-extension.js 1.58 KB (entry point)
40
+ docs/index.js 1.47 KB (entry point)
41
+ docs/personalization.docblock.js 1.47 KB (entry point)
42
+ ./example.js 0.99 KB (entry point)
43
+ ./overlay-customization.js 1.52 KB (entry point)
44
+ ./personalization.experiment.js 1.60 KB (entry point)
45
+ ./personalization.feature.js 0.70 KB (entry point)
40
46
 
41
47
  $ contractspec-bun-build types
package/CHANGELOG.md CHANGED
@@ -1,5 +1,55 @@
1
1
  # @contractspec/example.personalization
2
2
 
3
+ ## 3.7.12
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [81256ea]
8
+ - Updated dependencies [2619dd8]
9
+ - Updated dependencies [81256ea]
10
+ - Updated dependencies [a4489bb]
11
+ - Updated dependencies [9cb304e]
12
+ - @contractspec/lib.contracts-spec@5.0.0
13
+ - @contractspec/lib.workflow-composer@3.7.12
14
+ - @contractspec/lib.overlay-engine@3.7.12
15
+ - @contractspec/lib.personalization@6.0.12
16
+
17
+ ## 3.7.11
18
+
19
+ ### Patch Changes
20
+
21
+ - fix: release
22
+ - Updated dependencies
23
+ - @contractspec/lib.workflow-composer@3.7.11
24
+ - @contractspec/lib.personalization@6.0.11
25
+ - @contractspec/lib.contracts-spec@4.1.3
26
+ - @contractspec/lib.overlay-engine@3.7.11
27
+ - @contractspec/lib.logger@3.7.9
28
+
29
+ ## 3.7.10
30
+
31
+ ### Patch Changes
32
+
33
+ - 1a44cb6: feat: improve examples to increase coverage of Contracts type
34
+ - Updated dependencies [1a44cb6]
35
+ - @contractspec/lib.workflow-composer@3.7.10
36
+ - @contractspec/lib.personalization@6.0.10
37
+ - @contractspec/lib.contracts-spec@4.1.2
38
+ - @contractspec/lib.overlay-engine@3.7.10
39
+ - @contractspec/lib.logger@3.7.8
40
+
41
+ ## 3.7.9
42
+
43
+ ### Patch Changes
44
+
45
+ - fix: release
46
+ - Updated dependencies
47
+ - @contractspec/lib.workflow-composer@3.7.9
48
+ - @contractspec/lib.personalization@6.0.9
49
+ - @contractspec/lib.contracts-spec@4.1.1
50
+ - @contractspec/lib.overlay-engine@3.7.9
51
+ - @contractspec/lib.logger@3.7.7
52
+
3
53
  ## 3.7.6
4
54
 
5
55
  ### Patch Changes
@@ -483,6 +533,7 @@
483
533
  - 7f3203a: fix: make workspace test runs resilient when packages have no tests
484
534
 
485
535
  Updates package test scripts to pass cleanly when no matching test files exist:
536
+
486
537
  - Uses `bun test --pass-with-no-tests` in Bun-based packages that currently ship without test files.
487
538
  - Uses `jest --passWithNoTests` for the UI kit web package.
488
539
  - Adds `.vscode-test.mjs` for `vscode-contractspec` so VS Code extension test runs have an explicit config and stop failing on missing default configuration.
@@ -901,14 +952,17 @@
901
952
  feat: Contract layers support (features, examples, app-configs)
902
953
 
903
954
  ### New CLI Commands
955
+
904
956
  - `contractspec list layers` - List all contract layers with filtering
905
957
 
906
958
  ### Enhanced Commands
959
+
907
960
  - `contractspec ci` - New `layers` check category validates features/examples/config
908
961
  - `contractspec doctor` - New `layers` health checks
909
962
  - `contractspec integrity` - Now shows layer statistics
910
963
 
911
964
  ### New APIs
965
+
912
966
  - `discoverLayers()` - Scan workspace for all layer files
913
967
  - `scanExampleSource()` - Parse ExampleSpec from source code
914
968
  - `isExampleFile()` - Check if file is an example spec
package/README.md CHANGED
@@ -7,11 +7,12 @@ Website: https://contractspec.io
7
7
  ## What This Demonstrates
8
8
 
9
9
  - Behavior tracking integration pattern.
10
+ - Canonical `experiment` export via `PersonalizationExperiment`.
10
11
  - Overlay customization via overlay-engine.
12
+ - Canonical `theme` export via `PersonalizationTheme`.
11
13
  - Workflow extension via workflow-composer.
12
14
  - Multi-lib composition in a single example.
13
15
  - `src/docs/` contains docblocks and documentation-facing exports.
14
- - `src/docs/` contains docblocks and documentation-facing exports.
15
16
 
16
17
  ## Running Locally
17
18
 
@@ -32,7 +33,9 @@ Use `@contractspec/example.personalization` as a reference implementation, or im
32
33
  - `src/example.ts` is the runnable example entrypoint.
33
34
  - `src/index.ts` is the root public barrel and package entrypoint.
34
35
  - `src/overlay-customization.ts` is part of the package's public or composition surface.
36
+ - `src/personalization.experiment.ts` defines the exported experiment spec.
35
37
  - `src/personalization.feature.ts` defines a feature entrypoint.
38
+ - `src/personalization.theme.ts` defines the exported theme spec.
36
39
  - `src/workflow-extension.ts` is part of the package's public or composition surface.
37
40
 
38
41
  ## Public Entry Points
@@ -43,8 +46,11 @@ Use `@contractspec/example.personalization` as a reference implementation, or im
43
46
  - Export `./docs/personalization.docblock` resolves through `./src/docs/personalization.docblock.ts`.
44
47
  - Export `./example` resolves through `./src/example.ts`.
45
48
  - Export `./overlay-customization` resolves through `./src/overlay-customization.ts`.
49
+ - Export `./personalization.experiment` resolves through `./src/personalization.experiment.ts`.
46
50
  - Export `./personalization.feature` resolves through `./src/personalization.feature.ts`.
51
+ - Export `./personalization.theme` resolves through `./src/personalization.theme.ts`.
47
52
  - Export `./workflow-extension` resolves through `./src/workflow-extension.ts`.
53
+ - The package publishes 9 total export subpaths; keep docs aligned with `package.json`.
48
54
 
49
55
  ## Local Commands
50
56
 
@@ -162,6 +162,66 @@ async function runOverlayCustomizationExample() {
162
162
  logger2.info("Overlay applied", { fields: result.target.fields });
163
163
  }
164
164
 
165
+ // src/personalization.experiment.ts
166
+ import {
167
+ OwnersEnum,
168
+ StabilityEnum
169
+ } from "@contractspec/lib.contracts-spec/ownership";
170
+ var PersonalizationExperiment = {
171
+ meta: {
172
+ key: "personalization.experiment.overlay-copy",
173
+ version: "1.0.0",
174
+ title: "Personalization Overlay Copy Experiment",
175
+ description: "Tests a control onboarding copy against a personalized overlay variant.",
176
+ domain: "personalization",
177
+ owners: [OwnersEnum.PlatformCore],
178
+ tags: ["personalization", "experiment", "overlay"],
179
+ stability: StabilityEnum.Experimental
180
+ },
181
+ controlVariant: "control",
182
+ variants: [
183
+ {
184
+ id: "control",
185
+ key: "control",
186
+ description: "Default onboarding copy and standard workflow."
187
+ },
188
+ {
189
+ id: "personalized-overlay",
190
+ key: "personalized-overlay",
191
+ description: "Personalized copy with a branded theme override.",
192
+ overrides: [
193
+ {
194
+ type: "theme",
195
+ target: "personalization.theme.guided-onboarding",
196
+ version: "1.0.0"
197
+ },
198
+ {
199
+ type: "workflow",
200
+ target: "billing.invoiceApproval",
201
+ version: "1.0.0"
202
+ }
203
+ ]
204
+ }
205
+ ],
206
+ allocation: {
207
+ type: "sticky",
208
+ attribute: "userId",
209
+ salt: "personalization-overlay-copy"
210
+ },
211
+ successMetrics: [
212
+ {
213
+ key: "checklist-completion-rate",
214
+ telemetryEvent: {
215
+ key: "personalization.assignment.completed",
216
+ version: "1.0.0"
217
+ },
218
+ aggregation: "count",
219
+ target: 1
220
+ }
221
+ ],
222
+ tags: ["personalization", "experiment"]
223
+ };
224
+
165
225
  // src/personalization.feature.ts
166
226
  import { defineFeature } from "@contractspec/lib.contracts-spec";
167
227
  var PersonalizationFeature = defineFeature({
@@ -182,8 +242,70 @@ var PersonalizationFeature = defineFeature({
182
242
  ]
183
243
  });
184
244
 
245
+ // src/personalization.theme.ts
246
+ import {
247
+ OwnersEnum as OwnersEnum2,
248
+ StabilityEnum as StabilityEnum2
249
+ } from "@contractspec/lib.contracts-spec/ownership";
250
+ var PersonalizationTheme = {
251
+ meta: {
252
+ key: "personalization.theme.guided-onboarding",
253
+ version: "1.0.0",
254
+ title: "Guided Onboarding Theme",
255
+ description: "Theme tokens used when the personalized onboarding experience is active.",
256
+ domain: "personalization",
257
+ owners: [OwnersEnum2.PlatformCore],
258
+ tags: ["personalization", "theme", "onboarding"],
259
+ stability: StabilityEnum2.Experimental,
260
+ scopes: ["tenant", "user"]
261
+ },
262
+ tokens: {
263
+ colors: {
264
+ surface: { value: "#FCF6E8" },
265
+ accent: { value: "#C8742A" },
266
+ text: { value: "#2F2419" }
267
+ },
268
+ radii: {
269
+ card: { value: 18 }
270
+ },
271
+ space: {
272
+ panel: { value: 24 }
273
+ },
274
+ typography: {
275
+ body: { value: 16 },
276
+ title: { value: 28 }
277
+ },
278
+ motion: {
279
+ stagger: { value: "180ms" }
280
+ }
281
+ },
282
+ components: [
283
+ {
284
+ component: "OnboardingChecklist",
285
+ variants: {
286
+ guided: {
287
+ props: {
288
+ emphasis: "warm"
289
+ }
290
+ }
291
+ }
292
+ }
293
+ ],
294
+ overrides: [
295
+ {
296
+ scope: "tenant",
297
+ target: "tenant:acme",
298
+ tokens: {
299
+ colors: {
300
+ accent: { value: "#8A4B12" }
301
+ }
302
+ }
303
+ }
304
+ ]
305
+ };
306
+
185
307
  // src/workflow-extension.ts
186
- import { StabilityEnum } from "@contractspec/lib.contracts-spec";
308
+ import { StabilityEnum as StabilityEnum3 } from "@contractspec/lib.contracts-spec";
187
309
  import { Logger as Logger3, LogLevel as LogLevel3 } from "@contractspec/lib.logger";
188
310
  import { WorkflowComposer } from "@contractspec/lib.workflow-composer";
189
311
  var logger3 = new Logger3({
@@ -200,7 +322,7 @@ var BaseWorkflow = {
200
322
  tags: [],
201
323
  description: "",
202
324
  domain: "billing",
203
- stability: StabilityEnum.Stable
325
+ stability: StabilityEnum3.Stable
204
326
  },
205
327
  definition: {
206
328
  steps: [
@@ -244,5 +366,7 @@ export {
244
366
  logTenantWorkflowSteps,
245
367
  example_default as example,
246
368
  composeTenantWorkflowExample,
247
- PersonalizationFeature
369
+ PersonalizationTheme,
370
+ PersonalizationFeature,
371
+ PersonalizationExperiment
248
372
  };
@@ -0,0 +1,62 @@
1
+ // src/personalization.experiment.ts
2
+ import {
3
+ OwnersEnum,
4
+ StabilityEnum
5
+ } from "@contractspec/lib.contracts-spec/ownership";
6
+ var PersonalizationExperiment = {
7
+ meta: {
8
+ key: "personalization.experiment.overlay-copy",
9
+ version: "1.0.0",
10
+ title: "Personalization Overlay Copy Experiment",
11
+ description: "Tests a control onboarding copy against a personalized overlay variant.",
12
+ domain: "personalization",
13
+ owners: [OwnersEnum.PlatformCore],
14
+ tags: ["personalization", "experiment", "overlay"],
15
+ stability: StabilityEnum.Experimental
16
+ },
17
+ controlVariant: "control",
18
+ variants: [
19
+ {
20
+ id: "control",
21
+ key: "control",
22
+ description: "Default onboarding copy and standard workflow."
23
+ },
24
+ {
25
+ id: "personalized-overlay",
26
+ key: "personalized-overlay",
27
+ description: "Personalized copy with a branded theme override.",
28
+ overrides: [
29
+ {
30
+ type: "theme",
31
+ target: "personalization.theme.guided-onboarding",
32
+ version: "1.0.0"
33
+ },
34
+ {
35
+ type: "workflow",
36
+ target: "billing.invoiceApproval",
37
+ version: "1.0.0"
38
+ }
39
+ ]
40
+ }
41
+ ],
42
+ allocation: {
43
+ type: "sticky",
44
+ attribute: "userId",
45
+ salt: "personalization-overlay-copy"
46
+ },
47
+ successMetrics: [
48
+ {
49
+ key: "checklist-completion-rate",
50
+ telemetryEvent: {
51
+ key: "personalization.assignment.completed",
52
+ version: "1.0.0"
53
+ },
54
+ aggregation: "count",
55
+ target: 1
56
+ }
57
+ ],
58
+ tags: ["personalization", "experiment"]
59
+ };
60
+ export {
61
+ PersonalizationExperiment
62
+ };
@@ -0,0 +1,64 @@
1
+ // src/personalization.theme.ts
2
+ import {
3
+ OwnersEnum,
4
+ StabilityEnum
5
+ } from "@contractspec/lib.contracts-spec/ownership";
6
+ var PersonalizationTheme = {
7
+ meta: {
8
+ key: "personalization.theme.guided-onboarding",
9
+ version: "1.0.0",
10
+ title: "Guided Onboarding Theme",
11
+ description: "Theme tokens used when the personalized onboarding experience is active.",
12
+ domain: "personalization",
13
+ owners: [OwnersEnum.PlatformCore],
14
+ tags: ["personalization", "theme", "onboarding"],
15
+ stability: StabilityEnum.Experimental,
16
+ scopes: ["tenant", "user"]
17
+ },
18
+ tokens: {
19
+ colors: {
20
+ surface: { value: "#FCF6E8" },
21
+ accent: { value: "#C8742A" },
22
+ text: { value: "#2F2419" }
23
+ },
24
+ radii: {
25
+ card: { value: 18 }
26
+ },
27
+ space: {
28
+ panel: { value: 24 }
29
+ },
30
+ typography: {
31
+ body: { value: 16 },
32
+ title: { value: 28 }
33
+ },
34
+ motion: {
35
+ stagger: { value: "180ms" }
36
+ }
37
+ },
38
+ components: [
39
+ {
40
+ component: "OnboardingChecklist",
41
+ variants: {
42
+ guided: {
43
+ props: {
44
+ emphasis: "warm"
45
+ }
46
+ }
47
+ }
48
+ }
49
+ ],
50
+ overrides: [
51
+ {
52
+ scope: "tenant",
53
+ target: "tenant:acme",
54
+ tokens: {
55
+ colors: {
56
+ accent: { value: "#8A4B12" }
57
+ }
58
+ }
59
+ }
60
+ ]
61
+ };
62
+ export {
63
+ PersonalizationTheme
64
+ };
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  export * from './behavior-tracking';
2
2
  export { default as example } from './example';
3
3
  export * from './overlay-customization';
4
+ export * from './personalization.experiment';
4
5
  export * from './personalization.feature';
6
+ export * from './personalization.theme';
5
7
  export * from './workflow-extension';
6
8
  import './docs';
package/dist/index.js CHANGED
@@ -163,6 +163,66 @@ async function runOverlayCustomizationExample() {
163
163
  logger2.info("Overlay applied", { fields: result.target.fields });
164
164
  }
165
165
 
166
+ // src/personalization.experiment.ts
167
+ import {
168
+ OwnersEnum,
169
+ StabilityEnum
170
+ } from "@contractspec/lib.contracts-spec/ownership";
171
+ var PersonalizationExperiment = {
172
+ meta: {
173
+ key: "personalization.experiment.overlay-copy",
174
+ version: "1.0.0",
175
+ title: "Personalization Overlay Copy Experiment",
176
+ description: "Tests a control onboarding copy against a personalized overlay variant.",
177
+ domain: "personalization",
178
+ owners: [OwnersEnum.PlatformCore],
179
+ tags: ["personalization", "experiment", "overlay"],
180
+ stability: StabilityEnum.Experimental
181
+ },
182
+ controlVariant: "control",
183
+ variants: [
184
+ {
185
+ id: "control",
186
+ key: "control",
187
+ description: "Default onboarding copy and standard workflow."
188
+ },
189
+ {
190
+ id: "personalized-overlay",
191
+ key: "personalized-overlay",
192
+ description: "Personalized copy with a branded theme override.",
193
+ overrides: [
194
+ {
195
+ type: "theme",
196
+ target: "personalization.theme.guided-onboarding",
197
+ version: "1.0.0"
198
+ },
199
+ {
200
+ type: "workflow",
201
+ target: "billing.invoiceApproval",
202
+ version: "1.0.0"
203
+ }
204
+ ]
205
+ }
206
+ ],
207
+ allocation: {
208
+ type: "sticky",
209
+ attribute: "userId",
210
+ salt: "personalization-overlay-copy"
211
+ },
212
+ successMetrics: [
213
+ {
214
+ key: "checklist-completion-rate",
215
+ telemetryEvent: {
216
+ key: "personalization.assignment.completed",
217
+ version: "1.0.0"
218
+ },
219
+ aggregation: "count",
220
+ target: 1
221
+ }
222
+ ],
223
+ tags: ["personalization", "experiment"]
224
+ };
225
+
166
226
  // src/personalization.feature.ts
167
227
  import { defineFeature } from "@contractspec/lib.contracts-spec";
168
228
  var PersonalizationFeature = defineFeature({
@@ -183,8 +243,70 @@ var PersonalizationFeature = defineFeature({
183
243
  ]
184
244
  });
185
245
 
246
+ // src/personalization.theme.ts
247
+ import {
248
+ OwnersEnum as OwnersEnum2,
249
+ StabilityEnum as StabilityEnum2
250
+ } from "@contractspec/lib.contracts-spec/ownership";
251
+ var PersonalizationTheme = {
252
+ meta: {
253
+ key: "personalization.theme.guided-onboarding",
254
+ version: "1.0.0",
255
+ title: "Guided Onboarding Theme",
256
+ description: "Theme tokens used when the personalized onboarding experience is active.",
257
+ domain: "personalization",
258
+ owners: [OwnersEnum2.PlatformCore],
259
+ tags: ["personalization", "theme", "onboarding"],
260
+ stability: StabilityEnum2.Experimental,
261
+ scopes: ["tenant", "user"]
262
+ },
263
+ tokens: {
264
+ colors: {
265
+ surface: { value: "#FCF6E8" },
266
+ accent: { value: "#C8742A" },
267
+ text: { value: "#2F2419" }
268
+ },
269
+ radii: {
270
+ card: { value: 18 }
271
+ },
272
+ space: {
273
+ panel: { value: 24 }
274
+ },
275
+ typography: {
276
+ body: { value: 16 },
277
+ title: { value: 28 }
278
+ },
279
+ motion: {
280
+ stagger: { value: "180ms" }
281
+ }
282
+ },
283
+ components: [
284
+ {
285
+ component: "OnboardingChecklist",
286
+ variants: {
287
+ guided: {
288
+ props: {
289
+ emphasis: "warm"
290
+ }
291
+ }
292
+ }
293
+ }
294
+ ],
295
+ overrides: [
296
+ {
297
+ scope: "tenant",
298
+ target: "tenant:acme",
299
+ tokens: {
300
+ colors: {
301
+ accent: { value: "#8A4B12" }
302
+ }
303
+ }
304
+ }
305
+ ]
306
+ };
307
+
186
308
  // src/workflow-extension.ts
187
- import { StabilityEnum } from "@contractspec/lib.contracts-spec";
309
+ import { StabilityEnum as StabilityEnum3 } from "@contractspec/lib.contracts-spec";
188
310
  import { Logger as Logger3, LogLevel as LogLevel3 } from "@contractspec/lib.logger";
189
311
  import { WorkflowComposer } from "@contractspec/lib.workflow-composer";
190
312
  var logger3 = new Logger3({
@@ -201,7 +323,7 @@ var BaseWorkflow = {
201
323
  tags: [],
202
324
  description: "",
203
325
  domain: "billing",
204
- stability: StabilityEnum.Stable
326
+ stability: StabilityEnum3.Stable
205
327
  },
206
328
  definition: {
207
329
  steps: [
@@ -245,5 +367,7 @@ export {
245
367
  logTenantWorkflowSteps,
246
368
  example_default as example,
247
369
  composeTenantWorkflowExample,
248
- PersonalizationFeature
370
+ PersonalizationTheme,
371
+ PersonalizationFeature,
372
+ PersonalizationExperiment
249
373
  };
@@ -162,6 +162,66 @@ async function runOverlayCustomizationExample() {
162
162
  logger2.info("Overlay applied", { fields: result.target.fields });
163
163
  }
164
164
 
165
+ // src/personalization.experiment.ts
166
+ import {
167
+ OwnersEnum,
168
+ StabilityEnum
169
+ } from "@contractspec/lib.contracts-spec/ownership";
170
+ var PersonalizationExperiment = {
171
+ meta: {
172
+ key: "personalization.experiment.overlay-copy",
173
+ version: "1.0.0",
174
+ title: "Personalization Overlay Copy Experiment",
175
+ description: "Tests a control onboarding copy against a personalized overlay variant.",
176
+ domain: "personalization",
177
+ owners: [OwnersEnum.PlatformCore],
178
+ tags: ["personalization", "experiment", "overlay"],
179
+ stability: StabilityEnum.Experimental
180
+ },
181
+ controlVariant: "control",
182
+ variants: [
183
+ {
184
+ id: "control",
185
+ key: "control",
186
+ description: "Default onboarding copy and standard workflow."
187
+ },
188
+ {
189
+ id: "personalized-overlay",
190
+ key: "personalized-overlay",
191
+ description: "Personalized copy with a branded theme override.",
192
+ overrides: [
193
+ {
194
+ type: "theme",
195
+ target: "personalization.theme.guided-onboarding",
196
+ version: "1.0.0"
197
+ },
198
+ {
199
+ type: "workflow",
200
+ target: "billing.invoiceApproval",
201
+ version: "1.0.0"
202
+ }
203
+ ]
204
+ }
205
+ ],
206
+ allocation: {
207
+ type: "sticky",
208
+ attribute: "userId",
209
+ salt: "personalization-overlay-copy"
210
+ },
211
+ successMetrics: [
212
+ {
213
+ key: "checklist-completion-rate",
214
+ telemetryEvent: {
215
+ key: "personalization.assignment.completed",
216
+ version: "1.0.0"
217
+ },
218
+ aggregation: "count",
219
+ target: 1
220
+ }
221
+ ],
222
+ tags: ["personalization", "experiment"]
223
+ };
224
+
165
225
  // src/personalization.feature.ts
166
226
  import { defineFeature } from "@contractspec/lib.contracts-spec";
167
227
  var PersonalizationFeature = defineFeature({
@@ -182,8 +242,70 @@ var PersonalizationFeature = defineFeature({
182
242
  ]
183
243
  });
184
244
 
245
+ // src/personalization.theme.ts
246
+ import {
247
+ OwnersEnum as OwnersEnum2,
248
+ StabilityEnum as StabilityEnum2
249
+ } from "@contractspec/lib.contracts-spec/ownership";
250
+ var PersonalizationTheme = {
251
+ meta: {
252
+ key: "personalization.theme.guided-onboarding",
253
+ version: "1.0.0",
254
+ title: "Guided Onboarding Theme",
255
+ description: "Theme tokens used when the personalized onboarding experience is active.",
256
+ domain: "personalization",
257
+ owners: [OwnersEnum2.PlatformCore],
258
+ tags: ["personalization", "theme", "onboarding"],
259
+ stability: StabilityEnum2.Experimental,
260
+ scopes: ["tenant", "user"]
261
+ },
262
+ tokens: {
263
+ colors: {
264
+ surface: { value: "#FCF6E8" },
265
+ accent: { value: "#C8742A" },
266
+ text: { value: "#2F2419" }
267
+ },
268
+ radii: {
269
+ card: { value: 18 }
270
+ },
271
+ space: {
272
+ panel: { value: 24 }
273
+ },
274
+ typography: {
275
+ body: { value: 16 },
276
+ title: { value: 28 }
277
+ },
278
+ motion: {
279
+ stagger: { value: "180ms" }
280
+ }
281
+ },
282
+ components: [
283
+ {
284
+ component: "OnboardingChecklist",
285
+ variants: {
286
+ guided: {
287
+ props: {
288
+ emphasis: "warm"
289
+ }
290
+ }
291
+ }
292
+ }
293
+ ],
294
+ overrides: [
295
+ {
296
+ scope: "tenant",
297
+ target: "tenant:acme",
298
+ tokens: {
299
+ colors: {
300
+ accent: { value: "#8A4B12" }
301
+ }
302
+ }
303
+ }
304
+ ]
305
+ };
306
+
185
307
  // src/workflow-extension.ts
186
- import { StabilityEnum } from "@contractspec/lib.contracts-spec";
308
+ import { StabilityEnum as StabilityEnum3 } from "@contractspec/lib.contracts-spec";
187
309
  import { Logger as Logger3, LogLevel as LogLevel3 } from "@contractspec/lib.logger";
188
310
  import { WorkflowComposer } from "@contractspec/lib.workflow-composer";
189
311
  var logger3 = new Logger3({
@@ -200,7 +322,7 @@ var BaseWorkflow = {
200
322
  tags: [],
201
323
  description: "",
202
324
  domain: "billing",
203
- stability: StabilityEnum.Stable
325
+ stability: StabilityEnum3.Stable
204
326
  },
205
327
  definition: {
206
328
  steps: [
@@ -244,5 +366,7 @@ export {
244
366
  logTenantWorkflowSteps,
245
367
  example_default as example,
246
368
  composeTenantWorkflowExample,
247
- PersonalizationFeature
369
+ PersonalizationTheme,
370
+ PersonalizationFeature,
371
+ PersonalizationExperiment
248
372
  };
@@ -0,0 +1,62 @@
1
+ // src/personalization.experiment.ts
2
+ import {
3
+ OwnersEnum,
4
+ StabilityEnum
5
+ } from "@contractspec/lib.contracts-spec/ownership";
6
+ var PersonalizationExperiment = {
7
+ meta: {
8
+ key: "personalization.experiment.overlay-copy",
9
+ version: "1.0.0",
10
+ title: "Personalization Overlay Copy Experiment",
11
+ description: "Tests a control onboarding copy against a personalized overlay variant.",
12
+ domain: "personalization",
13
+ owners: [OwnersEnum.PlatformCore],
14
+ tags: ["personalization", "experiment", "overlay"],
15
+ stability: StabilityEnum.Experimental
16
+ },
17
+ controlVariant: "control",
18
+ variants: [
19
+ {
20
+ id: "control",
21
+ key: "control",
22
+ description: "Default onboarding copy and standard workflow."
23
+ },
24
+ {
25
+ id: "personalized-overlay",
26
+ key: "personalized-overlay",
27
+ description: "Personalized copy with a branded theme override.",
28
+ overrides: [
29
+ {
30
+ type: "theme",
31
+ target: "personalization.theme.guided-onboarding",
32
+ version: "1.0.0"
33
+ },
34
+ {
35
+ type: "workflow",
36
+ target: "billing.invoiceApproval",
37
+ version: "1.0.0"
38
+ }
39
+ ]
40
+ }
41
+ ],
42
+ allocation: {
43
+ type: "sticky",
44
+ attribute: "userId",
45
+ salt: "personalization-overlay-copy"
46
+ },
47
+ successMetrics: [
48
+ {
49
+ key: "checklist-completion-rate",
50
+ telemetryEvent: {
51
+ key: "personalization.assignment.completed",
52
+ version: "1.0.0"
53
+ },
54
+ aggregation: "count",
55
+ target: 1
56
+ }
57
+ ],
58
+ tags: ["personalization", "experiment"]
59
+ };
60
+ export {
61
+ PersonalizationExperiment
62
+ };
@@ -0,0 +1,64 @@
1
+ // src/personalization.theme.ts
2
+ import {
3
+ OwnersEnum,
4
+ StabilityEnum
5
+ } from "@contractspec/lib.contracts-spec/ownership";
6
+ var PersonalizationTheme = {
7
+ meta: {
8
+ key: "personalization.theme.guided-onboarding",
9
+ version: "1.0.0",
10
+ title: "Guided Onboarding Theme",
11
+ description: "Theme tokens used when the personalized onboarding experience is active.",
12
+ domain: "personalization",
13
+ owners: [OwnersEnum.PlatformCore],
14
+ tags: ["personalization", "theme", "onboarding"],
15
+ stability: StabilityEnum.Experimental,
16
+ scopes: ["tenant", "user"]
17
+ },
18
+ tokens: {
19
+ colors: {
20
+ surface: { value: "#FCF6E8" },
21
+ accent: { value: "#C8742A" },
22
+ text: { value: "#2F2419" }
23
+ },
24
+ radii: {
25
+ card: { value: 18 }
26
+ },
27
+ space: {
28
+ panel: { value: 24 }
29
+ },
30
+ typography: {
31
+ body: { value: 16 },
32
+ title: { value: 28 }
33
+ },
34
+ motion: {
35
+ stagger: { value: "180ms" }
36
+ }
37
+ },
38
+ components: [
39
+ {
40
+ component: "OnboardingChecklist",
41
+ variants: {
42
+ guided: {
43
+ props: {
44
+ emphasis: "warm"
45
+ }
46
+ }
47
+ }
48
+ }
49
+ ],
50
+ overrides: [
51
+ {
52
+ scope: "tenant",
53
+ target: "tenant:acme",
54
+ tokens: {
55
+ colors: {
56
+ accent: { value: "#8A4B12" }
57
+ }
58
+ }
59
+ }
60
+ ]
61
+ };
62
+ export {
63
+ PersonalizationTheme
64
+ };
@@ -0,0 +1,2 @@
1
+ import type { ExperimentSpec } from '@contractspec/lib.contracts-spec/experiments/spec';
2
+ export declare const PersonalizationExperiment: ExperimentSpec;
@@ -0,0 +1,63 @@
1
+ // @bun
2
+ // src/personalization.experiment.ts
3
+ import {
4
+ OwnersEnum,
5
+ StabilityEnum
6
+ } from "@contractspec/lib.contracts-spec/ownership";
7
+ var PersonalizationExperiment = {
8
+ meta: {
9
+ key: "personalization.experiment.overlay-copy",
10
+ version: "1.0.0",
11
+ title: "Personalization Overlay Copy Experiment",
12
+ description: "Tests a control onboarding copy against a personalized overlay variant.",
13
+ domain: "personalization",
14
+ owners: [OwnersEnum.PlatformCore],
15
+ tags: ["personalization", "experiment", "overlay"],
16
+ stability: StabilityEnum.Experimental
17
+ },
18
+ controlVariant: "control",
19
+ variants: [
20
+ {
21
+ id: "control",
22
+ key: "control",
23
+ description: "Default onboarding copy and standard workflow."
24
+ },
25
+ {
26
+ id: "personalized-overlay",
27
+ key: "personalized-overlay",
28
+ description: "Personalized copy with a branded theme override.",
29
+ overrides: [
30
+ {
31
+ type: "theme",
32
+ target: "personalization.theme.guided-onboarding",
33
+ version: "1.0.0"
34
+ },
35
+ {
36
+ type: "workflow",
37
+ target: "billing.invoiceApproval",
38
+ version: "1.0.0"
39
+ }
40
+ ]
41
+ }
42
+ ],
43
+ allocation: {
44
+ type: "sticky",
45
+ attribute: "userId",
46
+ salt: "personalization-overlay-copy"
47
+ },
48
+ successMetrics: [
49
+ {
50
+ key: "checklist-completion-rate",
51
+ telemetryEvent: {
52
+ key: "personalization.assignment.completed",
53
+ version: "1.0.0"
54
+ },
55
+ aggregation: "count",
56
+ target: 1
57
+ }
58
+ ],
59
+ tags: ["personalization", "experiment"]
60
+ };
61
+ export {
62
+ PersonalizationExperiment
63
+ };
@@ -0,0 +1,2 @@
1
+ import type { ThemeSpec } from '@contractspec/lib.contracts-spec/themes';
2
+ export declare const PersonalizationTheme: ThemeSpec;
@@ -0,0 +1,65 @@
1
+ // @bun
2
+ // src/personalization.theme.ts
3
+ import {
4
+ OwnersEnum,
5
+ StabilityEnum
6
+ } from "@contractspec/lib.contracts-spec/ownership";
7
+ var PersonalizationTheme = {
8
+ meta: {
9
+ key: "personalization.theme.guided-onboarding",
10
+ version: "1.0.0",
11
+ title: "Guided Onboarding Theme",
12
+ description: "Theme tokens used when the personalized onboarding experience is active.",
13
+ domain: "personalization",
14
+ owners: [OwnersEnum.PlatformCore],
15
+ tags: ["personalization", "theme", "onboarding"],
16
+ stability: StabilityEnum.Experimental,
17
+ scopes: ["tenant", "user"]
18
+ },
19
+ tokens: {
20
+ colors: {
21
+ surface: { value: "#FCF6E8" },
22
+ accent: { value: "#C8742A" },
23
+ text: { value: "#2F2419" }
24
+ },
25
+ radii: {
26
+ card: { value: 18 }
27
+ },
28
+ space: {
29
+ panel: { value: 24 }
30
+ },
31
+ typography: {
32
+ body: { value: 16 },
33
+ title: { value: 28 }
34
+ },
35
+ motion: {
36
+ stagger: { value: "180ms" }
37
+ }
38
+ },
39
+ components: [
40
+ {
41
+ component: "OnboardingChecklist",
42
+ variants: {
43
+ guided: {
44
+ props: {
45
+ emphasis: "warm"
46
+ }
47
+ }
48
+ }
49
+ }
50
+ ],
51
+ overrides: [
52
+ {
53
+ scope: "tenant",
54
+ target: "tenant:acme",
55
+ tokens: {
56
+ colors: {
57
+ accent: { value: "#8A4B12" }
58
+ }
59
+ }
60
+ }
61
+ ]
62
+ };
63
+ export {
64
+ PersonalizationTheme
65
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractspec/example.personalization",
3
- "version": "3.7.7",
3
+ "version": "3.7.12",
4
4
  "description": "Personalization examples: behavior tracking, overlay customization, workflow extension.",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -47,6 +47,13 @@
47
47
  "node": "./dist/node/overlay-customization.js",
48
48
  "default": "./dist/overlay-customization.js"
49
49
  },
50
+ "./personalization.experiment": {
51
+ "types": "./dist/personalization.experiment.d.ts",
52
+ "browser": "./dist/browser/personalization.experiment.js",
53
+ "bun": "./dist/personalization.experiment.js",
54
+ "node": "./dist/node/personalization.experiment.js",
55
+ "default": "./dist/personalization.experiment.js"
56
+ },
50
57
  "./personalization.feature": {
51
58
  "types": "./dist/personalization.feature.d.ts",
52
59
  "browser": "./dist/browser/personalization.feature.js",
@@ -54,6 +61,13 @@
54
61
  "node": "./dist/node/personalization.feature.js",
55
62
  "default": "./dist/personalization.feature.js"
56
63
  },
64
+ "./personalization.theme": {
65
+ "types": "./dist/personalization.theme.d.ts",
66
+ "browser": "./dist/browser/personalization.theme.js",
67
+ "bun": "./dist/personalization.theme.js",
68
+ "node": "./dist/node/personalization.theme.js",
69
+ "default": "./dist/personalization.theme.js"
70
+ },
57
71
  "./workflow-extension": {
58
72
  "types": "./dist/workflow-extension.d.ts",
59
73
  "browser": "./dist/browser/workflow-extension.js",
@@ -78,16 +92,16 @@
78
92
  "typecheck": "tsc --noEmit"
79
93
  },
80
94
  "dependencies": {
81
- "@contractspec/lib.personalization": "6.0.7",
82
- "@contractspec/lib.overlay-engine": "3.7.7",
83
- "@contractspec/lib.workflow-composer": "3.7.7",
84
- "@contractspec/lib.contracts-spec": "4.0.0",
85
- "@contractspec/lib.logger": "3.7.6"
95
+ "@contractspec/lib.personalization": "6.0.12",
96
+ "@contractspec/lib.overlay-engine": "3.7.12",
97
+ "@contractspec/lib.workflow-composer": "3.7.12",
98
+ "@contractspec/lib.contracts-spec": "5.0.0",
99
+ "@contractspec/lib.logger": "3.7.9"
86
100
  },
87
101
  "devDependencies": {
88
- "@contractspec/tool.typescript": "3.7.6",
102
+ "@contractspec/tool.typescript": "3.7.9",
89
103
  "typescript": "^5.9.3",
90
- "@contractspec/tool.bun": "3.7.6"
104
+ "@contractspec/tool.bun": "3.7.9"
91
105
  },
92
106
  "publishConfig": {
93
107
  "access": "public",
@@ -134,6 +148,13 @@
134
148
  "node": "./dist/node/overlay-customization.js",
135
149
  "default": "./dist/overlay-customization.js"
136
150
  },
151
+ "./personalization.experiment": {
152
+ "types": "./dist/personalization.experiment.d.ts",
153
+ "browser": "./dist/browser/personalization.experiment.js",
154
+ "bun": "./dist/personalization.experiment.js",
155
+ "node": "./dist/node/personalization.experiment.js",
156
+ "default": "./dist/personalization.experiment.js"
157
+ },
137
158
  "./personalization.feature": {
138
159
  "types": "./dist/personalization.feature.d.ts",
139
160
  "browser": "./dist/browser/personalization.feature.js",
@@ -141,6 +162,13 @@
141
162
  "node": "./dist/node/personalization.feature.js",
142
163
  "default": "./dist/personalization.feature.js"
143
164
  },
165
+ "./personalization.theme": {
166
+ "types": "./dist/personalization.theme.d.ts",
167
+ "browser": "./dist/browser/personalization.theme.js",
168
+ "bun": "./dist/personalization.theme.js",
169
+ "node": "./dist/node/personalization.theme.js",
170
+ "default": "./dist/personalization.theme.js"
171
+ },
144
172
  "./workflow-extension": {
145
173
  "types": "./dist/workflow-extension.d.ts",
146
174
  "browser": "./dist/browser/workflow-extension.js",
@@ -0,0 +1,20 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import {
3
+ PersonalizationExperiment,
4
+ PersonalizationFeature,
5
+ PersonalizationTheme,
6
+ } from './index';
7
+
8
+ describe('@contractspec/example.personalization', () => {
9
+ test('exports the canonical experiment and theme', () => {
10
+ expect(PersonalizationExperiment.meta.key).toBe(
11
+ 'personalization.experiment.overlay-copy'
12
+ );
13
+ expect(PersonalizationExperiment.variants).toHaveLength(2);
14
+ expect(PersonalizationTheme.meta.key).toBe(
15
+ 'personalization.theme.guided-onboarding'
16
+ );
17
+ expect(PersonalizationTheme.overrides).toHaveLength(1);
18
+ expect(PersonalizationFeature.meta.key).toBe('personalization');
19
+ });
20
+ });
package/src/index.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  export * from './behavior-tracking';
2
2
  export { default as example } from './example';
3
3
  export * from './overlay-customization';
4
+ export * from './personalization.experiment';
4
5
  export * from './personalization.feature';
6
+ export * from './personalization.theme';
5
7
  export * from './workflow-extension';
6
8
  import './docs';
@@ -0,0 +1,61 @@
1
+ import type { ExperimentSpec } from '@contractspec/lib.contracts-spec/experiments/spec';
2
+ import {
3
+ OwnersEnum,
4
+ StabilityEnum,
5
+ } from '@contractspec/lib.contracts-spec/ownership';
6
+
7
+ export const PersonalizationExperiment: ExperimentSpec = {
8
+ meta: {
9
+ key: 'personalization.experiment.overlay-copy',
10
+ version: '1.0.0',
11
+ title: 'Personalization Overlay Copy Experiment',
12
+ description:
13
+ 'Tests a control onboarding copy against a personalized overlay variant.',
14
+ domain: 'personalization',
15
+ owners: [OwnersEnum.PlatformCore],
16
+ tags: ['personalization', 'experiment', 'overlay'],
17
+ stability: StabilityEnum.Experimental,
18
+ },
19
+ controlVariant: 'control',
20
+ variants: [
21
+ {
22
+ id: 'control',
23
+ key: 'control',
24
+ description: 'Default onboarding copy and standard workflow.',
25
+ },
26
+ {
27
+ id: 'personalized-overlay',
28
+ key: 'personalized-overlay',
29
+ description: 'Personalized copy with a branded theme override.',
30
+ overrides: [
31
+ {
32
+ type: 'theme',
33
+ target: 'personalization.theme.guided-onboarding',
34
+ version: '1.0.0',
35
+ },
36
+ {
37
+ type: 'workflow',
38
+ target: 'billing.invoiceApproval',
39
+ version: '1.0.0',
40
+ },
41
+ ],
42
+ },
43
+ ],
44
+ allocation: {
45
+ type: 'sticky',
46
+ attribute: 'userId',
47
+ salt: 'personalization-overlay-copy',
48
+ },
49
+ successMetrics: [
50
+ {
51
+ key: 'checklist-completion-rate',
52
+ telemetryEvent: {
53
+ key: 'personalization.assignment.completed',
54
+ version: '1.0.0',
55
+ },
56
+ aggregation: 'count',
57
+ target: 1,
58
+ },
59
+ ],
60
+ tags: ['personalization', 'experiment'],
61
+ };
@@ -0,0 +1,63 @@
1
+ import {
2
+ OwnersEnum,
3
+ StabilityEnum,
4
+ } from '@contractspec/lib.contracts-spec/ownership';
5
+ import type { ThemeSpec } from '@contractspec/lib.contracts-spec/themes';
6
+
7
+ export const PersonalizationTheme: ThemeSpec = {
8
+ meta: {
9
+ key: 'personalization.theme.guided-onboarding',
10
+ version: '1.0.0',
11
+ title: 'Guided Onboarding Theme',
12
+ description:
13
+ 'Theme tokens used when the personalized onboarding experience is active.',
14
+ domain: 'personalization',
15
+ owners: [OwnersEnum.PlatformCore],
16
+ tags: ['personalization', 'theme', 'onboarding'],
17
+ stability: StabilityEnum.Experimental,
18
+ scopes: ['tenant', 'user'],
19
+ },
20
+ tokens: {
21
+ colors: {
22
+ surface: { value: '#FCF6E8' },
23
+ accent: { value: '#C8742A' },
24
+ text: { value: '#2F2419' },
25
+ },
26
+ radii: {
27
+ card: { value: 18 },
28
+ },
29
+ space: {
30
+ panel: { value: 24 },
31
+ },
32
+ typography: {
33
+ body: { value: 16 },
34
+ title: { value: 28 },
35
+ },
36
+ motion: {
37
+ stagger: { value: '180ms' },
38
+ },
39
+ },
40
+ components: [
41
+ {
42
+ component: 'OnboardingChecklist',
43
+ variants: {
44
+ guided: {
45
+ props: {
46
+ emphasis: 'warm',
47
+ },
48
+ },
49
+ },
50
+ },
51
+ ],
52
+ overrides: [
53
+ {
54
+ scope: 'tenant',
55
+ target: 'tenant:acme',
56
+ tokens: {
57
+ colors: {
58
+ accent: { value: '#8A4B12' },
59
+ },
60
+ },
61
+ },
62
+ ],
63
+ };