@contractspec/example.learning-journey-ambient-coach 3.7.6 → 3.7.7

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.
@@ -3,7 +3,7 @@ $ bun run prebuild && bun run build:bundle && bun run build:types
3
3
  $ contractspec-bun-build prebuild
4
4
  $ contractspec-bun-build transpile
5
5
  [contractspec-bun-build] transpile target=bun root=src entries=6 noBundle=false
6
- Bundled 6 modules in 37ms
6
+ Bundled 6 modules in 23ms
7
7
 
8
8
  docs/ambient-coach.docblock.js 1.29 KB (entry point)
9
9
  ./index.js 4.47 KB (entry point)
@@ -13,7 +13,7 @@ Bundled 6 modules in 37ms
13
13
  ./track.js 1.63 KB (entry point)
14
14
 
15
15
  [contractspec-bun-build] transpile target=node root=src entries=6 noBundle=false
16
- Bundled 6 modules in 29ms
16
+ Bundled 6 modules in 33ms
17
17
 
18
18
  docs/ambient-coach.docblock.js 1.28 KB (entry point)
19
19
  ./index.js 4.45 KB (entry point)
@@ -23,7 +23,7 @@ Bundled 6 modules in 29ms
23
23
  ./track.js 1.61 KB (entry point)
24
24
 
25
25
  [contractspec-bun-build] transpile target=browser root=src entries=6 noBundle=false
26
- Bundled 6 modules in 31ms
26
+ Bundled 6 modules in 29ms
27
27
 
28
28
  docs/ambient-coach.docblock.js 1.28 KB (entry point)
29
29
  ./index.js 4.45 KB (entry point)
package/AGENTS.md CHANGED
@@ -1,31 +1,53 @@
1
- # AI Agent Guide -- `@contractspec/example.learning-journey-ambient-coach`
1
+ # AI Agent Guide `@contractspec/example.learning-journey-ambient-coach`
2
2
 
3
3
  Scope: `packages/examples/learning-journey-ambient-coach/*`
4
4
 
5
- Demonstrates an ambient coaching learning journey with contextual tips and follow-up actions.
5
+ Ambient coach learning journey example with contextual tips and follow-up actions.
6
6
 
7
7
  ## Quick Context
8
8
 
9
- - **Layer**: example
10
- - **Related Packages**: `module.learning-journey`, `lib.contracts-spec`
9
+ - Layer: `example`.
10
+ - Package visibility: published package.
11
+ - Primary consumers are example explorers, template authors, and documentation readers.
12
+ - Related packages: `@contractspec/lib.contracts-spec`, `@contractspec/module.learning-journey`, `@contractspec/tool.bun`, `@contractspec/tool.typescript`.
11
13
 
12
- ## What This Demonstrates
14
+ ## Architecture
13
15
 
14
- - Ambient coaching track definition using the learning-journey module
15
- - Contextual tip delivery based on user activity
16
- - Follow-up action triggers
17
- - Lightweight track + example pattern
16
+ - `src/docs/` contains docblocks and documentation-facing exports.
17
+ - `src/example.ts` is the runnable example entrypoint.
18
+ - `src/index.ts` is the root public barrel and package entrypoint.
19
+ - `src/learning-journey-ambient-coach.feature.ts` defines a feature entrypoint.
20
+ - `src/track.test.ts` is part of the package's public or composition surface.
21
+ - `src/track.ts` is part of the package's public or composition surface.
18
22
 
19
- ## Public Exports
23
+ ## Public Surface
20
24
 
21
- - `.` -- root barrel
22
- - `./docs` -- DocBlock documentation
23
- - `./example` -- runnable example entry point
24
- - `./track` -- ambient coach track definition
25
+ - Export `.` resolves through `./src/index.ts`.
26
+ - Export `./docs` resolves through `./src/docs/index.ts`.
27
+ - Export `./docs/ambient-coach.docblock` resolves through `./src/docs/ambient-coach.docblock.ts`.
28
+ - Export `./example` resolves through `./src/example.ts`.
29
+ - Export `./learning-journey-ambient-coach.feature` resolves through `./src/learning-journey-ambient-coach.feature.ts`.
30
+ - Export `./track` resolves through `./src/track.ts`.
31
+
32
+ ## Guardrails
33
+
34
+ - Keep the example package demonstrative, buildable, and aligned with the exported feature surface.
35
+ - Do not add hidden production assumptions that are not actually implemented in the example.
36
+ - Changes here can affect downstream packages such as `@contractspec/lib.contracts-spec`, `@contractspec/module.learning-journey`, `@contractspec/tool.bun`, `@contractspec/tool.typescript`.
37
+ - Changes here can affect downstream packages such as `@contractspec/lib.contracts-spec`, `@contractspec/module.learning-journey`, `@contractspec/tool.bun`, `@contractspec/tool.typescript`.
25
38
 
26
39
  ## Local Commands
27
40
 
28
- - Build: `bun run build`
29
- - Dev: `bun run dev`
30
- - Test: `bun test`
31
- - Typecheck: `bun run typecheck`
41
+ - `bun run dev` — contractspec-bun-build dev
42
+ - `bun run build`bun run prebuild && bun run build:bundle && bun run build:types
43
+ - `bun run test`bun test
44
+ - `bun run lint` — bun lint:fix
45
+ - `bun run lint:check` — biome check .
46
+ - `bun run lint:fix` — biome check --write --unsafe --only=nursery/useSortedClasses . && biome check --write .
47
+ - `bun run typecheck` — tsc --noEmit
48
+ - `bun run publish:pkg` — bun publish --tolerate-republish --ignore-scripts --verbose
49
+ - `bun run publish:pkg:canary` — bun publish:pkg --tag canary
50
+ - `bun run clean` — rimraf dist .turbo
51
+ - `bun run build:bundle` — contractspec-bun-build transpile
52
+ - `bun run build:types` — contractspec-bun-build types
53
+ - `bun run prebuild` — contractspec-bun-build prebuild
package/README.md CHANGED
@@ -1,37 +1,69 @@
1
1
  # @contractspec/example.learning-journey-ambient-coach
2
2
 
3
- Website: https://contractspec.io/
3
+ Website: https://contractspec.io
4
4
 
5
+ **Ambient coach learning journey example with contextual tips and follow-up actions.**
5
6
 
6
- Ambient coach learning journey example that surfaces contextual tips based on user behavior and marks completion when acknowledged or acted upon.
7
+ ## What This Demonstrates
7
8
 
8
- ## What it shows
9
+ - Ambient coaching track definition using the learning-journey module.
10
+ - Contextual tip delivery based on user activity.
11
+ - Follow-up action triggers.
12
+ - Lightweight track + example pattern.
13
+ - `src/docs/` contains docblocks and documentation-facing exports.
14
+ - `src/docs/` contains docblocks and documentation-facing exports.
9
15
 
10
- - Tip/insight model with trigger → show → acknowledge/action events
11
- - Track steps for money and coliving behaviors
12
- - Event and count-based completion with optional action follow-ups
13
- - XP/engagement increments for acting on tips
16
+ ## Running Locally
14
17
 
15
- ## How to run
18
+ From `packages/examples/learning-journey-ambient-coach`:
19
+ - `bun run dev`
20
+ - `bun run build`
21
+ - `bun run test`
22
+ - `bun run typecheck`
16
23
 
17
- 1. `bun test packages/examples/learning-journey-ambient-coach`
18
- 2. Use registry helper `recordEvent` with events like:
24
+ ## Usage
19
25
 
20
- ```ts
21
- recordEvent({
22
- name: 'coach.tip.triggered',
23
- learnerId: 'u1',
24
- payload: { tipId: 'cash_buffer_too_high' },
25
- });
26
- recordEvent({
27
- name: 'coach.tip.follow_up_action_taken',
28
- learnerId: 'u1',
29
- payload: { tipId: 'cash_buffer_too_high' },
30
- });
31
- ```
26
+ Use `@contractspec/example.learning-journey-ambient-coach` as a reference implementation, or import its exported surfaces into a workspace that composes ContractSpec examples and bundles.
32
27
 
33
- ## Adapting
28
+ ## Architecture
34
29
 
35
- - Swap categories for your domain (money, coliving, product adoption).
36
- - Adjust trigger payload filters to align with analytics events.
37
- - Add more steps or split tracks per persona/segment.
30
+ - `src/docs/` contains docblocks and documentation-facing exports.
31
+ - `src/example.ts` is the runnable example entrypoint.
32
+ - `src/index.ts` is the root public barrel and package entrypoint.
33
+ - `src/learning-journey-ambient-coach.feature.ts` defines a feature entrypoint.
34
+ - `src/track.test.ts` is part of the package's public or composition surface.
35
+ - `src/track.ts` is part of the package's public or composition surface.
36
+
37
+ ## Public Entry Points
38
+
39
+ - Export `.` resolves through `./src/index.ts`.
40
+ - Export `./docs` resolves through `./src/docs/index.ts`.
41
+ - Export `./docs/ambient-coach.docblock` resolves through `./src/docs/ambient-coach.docblock.ts`.
42
+ - Export `./example` resolves through `./src/example.ts`.
43
+ - Export `./learning-journey-ambient-coach.feature` resolves through `./src/learning-journey-ambient-coach.feature.ts`.
44
+ - Export `./track` resolves through `./src/track.ts`.
45
+
46
+ ## Local Commands
47
+
48
+ - `bun run dev` — contractspec-bun-build dev
49
+ - `bun run build` — bun run prebuild && bun run build:bundle && bun run build:types
50
+ - `bun run test` — bun test
51
+ - `bun run lint` — bun lint:fix
52
+ - `bun run lint:check` — biome check .
53
+ - `bun run lint:fix` — biome check --write --unsafe --only=nursery/useSortedClasses . && biome check --write .
54
+ - `bun run typecheck` — tsc --noEmit
55
+ - `bun run publish:pkg` — bun publish --tolerate-republish --ignore-scripts --verbose
56
+ - `bun run publish:pkg:canary` — bun publish:pkg --tag canary
57
+ - `bun run clean` — rimraf dist .turbo
58
+ - `bun run build:bundle` — contractspec-bun-build transpile
59
+ - `bun run build:types` — contractspec-bun-build types
60
+ - `bun run prebuild` — contractspec-bun-build prebuild
61
+
62
+ ## Recent Updates
63
+
64
+ - Replace eslint+prettier by biomejs to optimize speed.
65
+ - Missing contract layers.
66
+
67
+ ## Notes
68
+
69
+ - Works alongside `@contractspec/lib.contracts-spec`, `@contractspec/module.learning-journey`, `@contractspec/tool.bun`, `@contractspec/tool.typescript`.
@@ -57,6 +57,22 @@ var example = defineExample({
57
57
  });
58
58
  var example_default = example;
59
59
 
60
+ // src/learning-journey-ambient-coach.feature.ts
61
+ import { defineFeature } from "@contractspec/lib.contracts-spec";
62
+ var LearningJourneyAmbientCoachFeature = defineFeature({
63
+ meta: {
64
+ key: "learning-journey-ambient-coach",
65
+ version: "1.0.0",
66
+ title: "Learning Journey: Ambient Coach",
67
+ description: "Contextual coaching track with ambient tips and follow-up actions",
68
+ domain: "learning-journey",
69
+ owners: ["@examples"],
70
+ tags: ["learning", "coaching", "ambient", "journey"],
71
+ stability: "experimental"
72
+ },
73
+ docs: ["docs.learning-journey.ambient-coach"]
74
+ });
75
+
60
76
  // src/track.ts
61
77
  var makeTipStep = (id, tipId, description) => ({
62
78
  id,
@@ -98,22 +114,6 @@ var ambientCoachTracks = [
98
114
  moneyAmbientCoachTrack,
99
115
  colivingAmbientCoachTrack
100
116
  ];
101
-
102
- // src/learning-journey-ambient-coach.feature.ts
103
- import { defineFeature } from "@contractspec/lib.contracts-spec";
104
- var LearningJourneyAmbientCoachFeature = defineFeature({
105
- meta: {
106
- key: "learning-journey-ambient-coach",
107
- version: "1.0.0",
108
- title: "Learning Journey: Ambient Coach",
109
- description: "Contextual coaching track with ambient tips and follow-up actions",
110
- domain: "learning-journey",
111
- owners: ["@examples"],
112
- tags: ["learning", "coaching", "ambient", "journey"],
113
- stability: "experimental"
114
- },
115
- docs: ["docs.learning-journey.ambient-coach"]
116
- });
117
117
  export {
118
118
  moneyAmbientCoachTrack,
119
119
  example_default as example,
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * from './track';
2
- export * from './learning-journey-ambient-coach.feature';
3
1
  export { default as example } from './example';
2
+ export * from './learning-journey-ambient-coach.feature';
3
+ export * from './track';
4
4
  import './docs';
package/dist/index.js CHANGED
@@ -58,6 +58,22 @@ var example = defineExample({
58
58
  });
59
59
  var example_default = example;
60
60
 
61
+ // src/learning-journey-ambient-coach.feature.ts
62
+ import { defineFeature } from "@contractspec/lib.contracts-spec";
63
+ var LearningJourneyAmbientCoachFeature = defineFeature({
64
+ meta: {
65
+ key: "learning-journey-ambient-coach",
66
+ version: "1.0.0",
67
+ title: "Learning Journey: Ambient Coach",
68
+ description: "Contextual coaching track with ambient tips and follow-up actions",
69
+ domain: "learning-journey",
70
+ owners: ["@examples"],
71
+ tags: ["learning", "coaching", "ambient", "journey"],
72
+ stability: "experimental"
73
+ },
74
+ docs: ["docs.learning-journey.ambient-coach"]
75
+ });
76
+
61
77
  // src/track.ts
62
78
  var makeTipStep = (id, tipId, description) => ({
63
79
  id,
@@ -99,22 +115,6 @@ var ambientCoachTracks = [
99
115
  moneyAmbientCoachTrack,
100
116
  colivingAmbientCoachTrack
101
117
  ];
102
-
103
- // src/learning-journey-ambient-coach.feature.ts
104
- import { defineFeature } from "@contractspec/lib.contracts-spec";
105
- var LearningJourneyAmbientCoachFeature = defineFeature({
106
- meta: {
107
- key: "learning-journey-ambient-coach",
108
- version: "1.0.0",
109
- title: "Learning Journey: Ambient Coach",
110
- description: "Contextual coaching track with ambient tips and follow-up actions",
111
- domain: "learning-journey",
112
- owners: ["@examples"],
113
- tags: ["learning", "coaching", "ambient", "journey"],
114
- stability: "experimental"
115
- },
116
- docs: ["docs.learning-journey.ambient-coach"]
117
- });
118
118
  export {
119
119
  moneyAmbientCoachTrack,
120
120
  example_default as example,
@@ -57,6 +57,22 @@ var example = defineExample({
57
57
  });
58
58
  var example_default = example;
59
59
 
60
+ // src/learning-journey-ambient-coach.feature.ts
61
+ import { defineFeature } from "@contractspec/lib.contracts-spec";
62
+ var LearningJourneyAmbientCoachFeature = defineFeature({
63
+ meta: {
64
+ key: "learning-journey-ambient-coach",
65
+ version: "1.0.0",
66
+ title: "Learning Journey: Ambient Coach",
67
+ description: "Contextual coaching track with ambient tips and follow-up actions",
68
+ domain: "learning-journey",
69
+ owners: ["@examples"],
70
+ tags: ["learning", "coaching", "ambient", "journey"],
71
+ stability: "experimental"
72
+ },
73
+ docs: ["docs.learning-journey.ambient-coach"]
74
+ });
75
+
60
76
  // src/track.ts
61
77
  var makeTipStep = (id, tipId, description) => ({
62
78
  id,
@@ -98,22 +114,6 @@ var ambientCoachTracks = [
98
114
  moneyAmbientCoachTrack,
99
115
  colivingAmbientCoachTrack
100
116
  ];
101
-
102
- // src/learning-journey-ambient-coach.feature.ts
103
- import { defineFeature } from "@contractspec/lib.contracts-spec";
104
- var LearningJourneyAmbientCoachFeature = defineFeature({
105
- meta: {
106
- key: "learning-journey-ambient-coach",
107
- version: "1.0.0",
108
- title: "Learning Journey: Ambient Coach",
109
- description: "Contextual coaching track with ambient tips and follow-up actions",
110
- domain: "learning-journey",
111
- owners: ["@examples"],
112
- tags: ["learning", "coaching", "ambient", "journey"],
113
- stability: "experimental"
114
- },
115
- docs: ["docs.learning-journey.ambient-coach"]
116
- });
117
117
  export {
118
118
  moneyAmbientCoachTrack,
119
119
  example_default as example,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractspec/example.learning-journey-ambient-coach",
3
- "version": "3.7.6",
3
+ "version": "3.7.7",
4
4
  "description": "Ambient coach learning journey example with contextual tips and follow-up actions.",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -57,15 +57,15 @@
57
57
  "dev": "contractspec-bun-build dev",
58
58
  "clean": "rimraf dist .turbo",
59
59
  "lint": "bun lint:fix",
60
- "lint:fix": "eslint src --fix",
61
- "lint:check": "eslint src",
60
+ "lint:fix": "biome check --write --unsafe --only=nursery/useSortedClasses . && biome check --write .",
61
+ "lint:check": "biome check .",
62
62
  "test": "bun test",
63
63
  "prebuild": "contractspec-bun-build prebuild",
64
64
  "typecheck": "tsc --noEmit"
65
65
  },
66
66
  "dependencies": {
67
- "@contractspec/module.learning-journey": "3.7.6",
68
- "@contractspec/lib.contracts-spec": "3.7.6"
67
+ "@contractspec/module.learning-journey": "3.7.7",
68
+ "@contractspec/lib.contracts-spec": "4.0.0"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@contractspec/tool.typescript": "3.7.6",
@@ -2,16 +2,16 @@ import type { DocBlock } from '@contractspec/lib.contracts-spec/docs';
2
2
  import { registerDocBlocks } from '@contractspec/lib.contracts-spec/docs';
3
3
 
4
4
  const ambientCoachDocBlocks: DocBlock[] = [
5
- {
6
- id: 'docs.learning-journey.ambient-coach',
7
- title: 'Learning Journey — Ambient Coach',
8
- summary:
9
- 'Context-aware coaching pattern that triggers tips, shows them, and marks completion when users act or acknowledge.',
10
- kind: 'reference',
11
- visibility: 'public',
12
- route: '/docs/learning-journey/ambient-coach',
13
- tags: ['learning', 'coach', 'tips'],
14
- body: `## Tracks
5
+ {
6
+ id: 'docs.learning-journey.ambient-coach',
7
+ title: 'Learning Journey — Ambient Coach',
8
+ summary:
9
+ 'Context-aware coaching pattern that triggers tips, shows them, and marks completion when users act or acknowledge.',
10
+ kind: 'reference',
11
+ visibility: 'public',
12
+ route: '/docs/learning-journey/ambient-coach',
13
+ tags: ['learning', 'coach', 'tips'],
14
+ body: `## Tracks
15
15
  - \`money_ambient_coach\`: cash buffer too high, no savings goal, irregular savings
16
16
  - \`coliving_ambient_coach\`: noise late evening, guest frequency high, shared space conflicts
17
17
 
@@ -26,7 +26,7 @@ const ambientCoachDocBlocks: DocBlock[] = [
26
26
  - Tracks export from \`@contractspec/example.learning-journey-ambient-coach/track\`.
27
27
  - Registry progression is event-driven; payload filters can scope tips per category.
28
28
  - XP/engagement can be awarded on completion of each tip step.`,
29
- },
29
+ },
30
30
  ];
31
31
 
32
32
  registerDocBlocks(ambientCoachDocBlocks);
package/src/example.ts CHANGED
@@ -1,31 +1,31 @@
1
1
  import { defineExample } from '@contractspec/lib.contracts-spec';
2
2
 
3
3
  const example = defineExample({
4
- meta: {
5
- key: 'learning-journey-ambient-coach',
6
- version: '1.0.0',
7
- title: 'Learning Journey — Ambient Coach',
8
- description:
9
- 'Ambient coaching pattern: lightweight nudges driven by context and recent progress.',
10
- kind: 'template',
11
- visibility: 'public',
12
- stability: 'experimental',
13
- owners: ['@platform.core'],
14
- tags: ['learning', 'coaching', 'ambient'],
15
- },
16
- docs: {
17
- rootDocId: 'docs.learning-journey.ambient-coach',
18
- },
19
- entrypoints: {
20
- packageName: '@contractspec/example.learning-journey-ambient-coach',
21
- docs: './docs',
22
- },
23
- surfaces: {
24
- templates: true,
25
- sandbox: { enabled: true, modes: ['playground', 'markdown'] },
26
- studio: { enabled: true, installable: true },
27
- mcp: { enabled: true },
28
- },
4
+ meta: {
5
+ key: 'learning-journey-ambient-coach',
6
+ version: '1.0.0',
7
+ title: 'Learning Journey — Ambient Coach',
8
+ description:
9
+ 'Ambient coaching pattern: lightweight nudges driven by context and recent progress.',
10
+ kind: 'template',
11
+ visibility: 'public',
12
+ stability: 'experimental',
13
+ owners: ['@platform.core'],
14
+ tags: ['learning', 'coaching', 'ambient'],
15
+ },
16
+ docs: {
17
+ rootDocId: 'docs.learning-journey.ambient-coach',
18
+ },
19
+ entrypoints: {
20
+ packageName: '@contractspec/example.learning-journey-ambient-coach',
21
+ docs: './docs',
22
+ },
23
+ surfaces: {
24
+ templates: true,
25
+ sandbox: { enabled: true, modes: ['playground', 'markdown'] },
26
+ studio: { enabled: true, installable: true },
27
+ mcp: { enabled: true },
28
+ },
29
29
  });
30
30
 
31
31
  export default example;
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * from './track';
2
- export * from './learning-journey-ambient-coach.feature';
3
1
  export { default as example } from './example';
2
+ export * from './learning-journey-ambient-coach.feature';
3
+ export * from './track';
4
4
  import './docs';
@@ -1,17 +1,17 @@
1
1
  import { defineFeature } from '@contractspec/lib.contracts-spec';
2
2
 
3
3
  export const LearningJourneyAmbientCoachFeature = defineFeature({
4
- meta: {
5
- key: 'learning-journey-ambient-coach',
6
- version: '1.0.0',
7
- title: 'Learning Journey: Ambient Coach',
8
- description:
9
- 'Contextual coaching track with ambient tips and follow-up actions',
10
- domain: 'learning-journey',
11
- owners: ['@examples'],
12
- tags: ['learning', 'coaching', 'ambient', 'journey'],
13
- stability: 'experimental',
14
- },
4
+ meta: {
5
+ key: 'learning-journey-ambient-coach',
6
+ version: '1.0.0',
7
+ title: 'Learning Journey: Ambient Coach',
8
+ description:
9
+ 'Contextual coaching track with ambient tips and follow-up actions',
10
+ domain: 'learning-journey',
11
+ owners: ['@examples'],
12
+ tags: ['learning', 'coaching', 'ambient', 'journey'],
13
+ stability: 'experimental',
14
+ },
15
15
 
16
- docs: ['docs.learning-journey.ambient-coach'],
16
+ docs: ['docs.learning-journey.ambient-coach'],
17
17
  });
package/src/track.test.ts CHANGED
@@ -3,55 +3,55 @@ import { describe, expect, it } from 'bun:test';
3
3
  import { moneyAmbientCoachTrack } from './track';
4
4
 
5
5
  interface TestEvent {
6
- name: string;
7
- payload?: Record<string, unknown>;
6
+ name: string;
7
+ payload?: Record<string, unknown>;
8
8
  }
9
9
 
10
10
  const matchesFilter = (
11
- filter: Record<string, unknown> | undefined,
12
- payload: Record<string, unknown> | undefined
11
+ filter: Record<string, unknown> | undefined,
12
+ payload: Record<string, unknown> | undefined
13
13
  ) => {
14
- if (!filter) return true;
15
- if (!payload) return false;
16
- return Object.entries(filter).every(([key, value]) => payload[key] === value);
14
+ if (!filter) return true;
15
+ if (!payload) return false;
16
+ return Object.entries(filter).every(([key, value]) => payload[key] === value);
17
17
  };
18
18
 
19
19
  describe('ambient coach track', () => {
20
- it('completes steps when tips are acted upon', () => {
21
- const tipIds = [
22
- 'cash_buffer_too_high',
23
- 'no_savings_goal',
24
- 'irregular_savings',
25
- ];
26
-
27
- const events: TestEvent[] = tipIds.flatMap((tipId) => [
28
- { name: 'coach.tip.triggered', payload: { tipId } },
29
- { name: 'coach.tip.follow_up_action_taken', payload: { tipId } },
30
- ]);
31
-
32
- const progress = moneyAmbientCoachTrack.steps.map((step) => ({
33
- id: step.id,
34
- status: 'PENDING' as 'PENDING' | 'COMPLETED',
35
- }));
36
-
37
- events.forEach((event) => {
38
- moneyAmbientCoachTrack.steps.forEach((stepSpec, index) => {
39
- const step = progress[index];
40
- if (!step || step.status === 'COMPLETED') return;
41
- if (stepSpec.completion.kind !== 'event') return;
42
- if (stepSpec.completion.eventName !== event.name) return;
43
- if (
44
- !matchesFilter(
45
- stepSpec.completion.payloadFilter,
46
- event.payload as Record<string, unknown> | undefined
47
- )
48
- ) {
49
- return;
50
- }
51
- step.status = 'COMPLETED';
52
- });
53
- });
54
-
55
- expect(progress.every((s) => s.status === 'COMPLETED')).toBeTrue();
56
- });
20
+ it('completes steps when tips are acted upon', () => {
21
+ const tipIds = [
22
+ 'cash_buffer_too_high',
23
+ 'no_savings_goal',
24
+ 'irregular_savings',
25
+ ];
26
+
27
+ const events: TestEvent[] = tipIds.flatMap((tipId) => [
28
+ { name: 'coach.tip.triggered', payload: { tipId } },
29
+ { name: 'coach.tip.follow_up_action_taken', payload: { tipId } },
30
+ ]);
31
+
32
+ const progress = moneyAmbientCoachTrack.steps.map((step) => ({
33
+ id: step.id,
34
+ status: 'PENDING' as 'PENDING' | 'COMPLETED',
35
+ }));
36
+
37
+ events.forEach((event) => {
38
+ moneyAmbientCoachTrack.steps.forEach((stepSpec, index) => {
39
+ const step = progress[index];
40
+ if (!step || step.status === 'COMPLETED') return;
41
+ if (stepSpec.completion.kind !== 'event') return;
42
+ if (stepSpec.completion.eventName !== event.name) return;
43
+ if (
44
+ !matchesFilter(
45
+ stepSpec.completion.payloadFilter,
46
+ event.payload as Record<string, unknown> | undefined
47
+ )
48
+ ) {
49
+ return;
50
+ }
51
+ step.status = 'COMPLETED';
52
+ });
53
+ });
54
+
55
+ expect(progress.every((s) => s.status === 'COMPLETED')).toBeTrue();
56
+ });
57
57
  });
package/src/track.ts CHANGED
@@ -1,74 +1,74 @@
1
1
  import type { LearningJourneyTrackSpec } from '@contractspec/module.learning-journey/track-spec';
2
2
 
3
3
  const makeTipStep = (
4
- id: string,
5
- tipId: string,
6
- description: string
4
+ id: string,
5
+ tipId: string,
6
+ description: string
7
7
  ): LearningJourneyTrackSpec['steps'][number] => ({
8
- id,
9
- title: `Resolve tip: ${tipId}`,
10
- description,
11
- completion: {
12
- kind: 'event',
13
- eventName: 'coach.tip.follow_up_action_taken',
14
- payloadFilter: { tipId },
15
- },
16
- xpReward: 20,
17
- metadata: { tipId },
8
+ id,
9
+ title: `Resolve tip: ${tipId}`,
10
+ description,
11
+ completion: {
12
+ kind: 'event',
13
+ eventName: 'coach.tip.follow_up_action_taken',
14
+ payloadFilter: { tipId },
15
+ },
16
+ xpReward: 20,
17
+ metadata: { tipId },
18
18
  });
19
19
 
20
20
  export const moneyAmbientCoachTrack: LearningJourneyTrackSpec = {
21
- id: 'money_ambient_coach',
22
- name: 'Ambient Coach — Money',
23
- description:
24
- 'Subtle coaching for money patterns (cash buffer, goals, saving rhythm).',
25
- targetUserSegment: 'money_user',
26
- totalXp: 60,
27
- steps: [
28
- makeTipStep(
29
- 'cash_buffer_too_high',
30
- 'cash_buffer_too_high',
31
- 'Suggest sweeping excess cash into goals.'
32
- ),
33
- makeTipStep(
34
- 'no_savings_goal',
35
- 'no_savings_goal',
36
- 'Prompt setting a first savings goal.'
37
- ),
38
- makeTipStep(
39
- 'irregular_savings',
40
- 'irregular_savings',
41
- 'Recommend recurring saves after irregular deposits.'
42
- ),
43
- ],
21
+ id: 'money_ambient_coach',
22
+ name: 'Ambient Coach — Money',
23
+ description:
24
+ 'Subtle coaching for money patterns (cash buffer, goals, saving rhythm).',
25
+ targetUserSegment: 'money_user',
26
+ totalXp: 60,
27
+ steps: [
28
+ makeTipStep(
29
+ 'cash_buffer_too_high',
30
+ 'cash_buffer_too_high',
31
+ 'Suggest sweeping excess cash into goals.'
32
+ ),
33
+ makeTipStep(
34
+ 'no_savings_goal',
35
+ 'no_savings_goal',
36
+ 'Prompt setting a first savings goal.'
37
+ ),
38
+ makeTipStep(
39
+ 'irregular_savings',
40
+ 'irregular_savings',
41
+ 'Recommend recurring saves after irregular deposits.'
42
+ ),
43
+ ],
44
44
  };
45
45
 
46
46
  export const colivingAmbientCoachTrack: LearningJourneyTrackSpec = {
47
- id: 'coliving_ambient_coach',
48
- name: 'Ambient Coach — Coliving',
49
- description: 'Contextual tips for healthy coliving habits.',
50
- targetUserSegment: 'coliving',
51
- totalXp: 60,
52
- steps: [
53
- makeTipStep(
54
- 'noise_late_evening',
55
- 'noise_late_evening',
56
- 'Suggest updating quiet hours to reduce evening noise.'
57
- ),
58
- makeTipStep(
59
- 'guest_frequency_high',
60
- 'guest_frequency_high',
61
- 'Set guest frequency expectations for the house.'
62
- ),
63
- makeTipStep(
64
- 'shared_space_conflicts',
65
- 'shared_space_conflicts',
66
- 'Offer a shared-space checklist to reduce conflicts.'
67
- ),
68
- ],
47
+ id: 'coliving_ambient_coach',
48
+ name: 'Ambient Coach — Coliving',
49
+ description: 'Contextual tips for healthy coliving habits.',
50
+ targetUserSegment: 'coliving',
51
+ totalXp: 60,
52
+ steps: [
53
+ makeTipStep(
54
+ 'noise_late_evening',
55
+ 'noise_late_evening',
56
+ 'Suggest updating quiet hours to reduce evening noise.'
57
+ ),
58
+ makeTipStep(
59
+ 'guest_frequency_high',
60
+ 'guest_frequency_high',
61
+ 'Set guest frequency expectations for the house.'
62
+ ),
63
+ makeTipStep(
64
+ 'shared_space_conflicts',
65
+ 'shared_space_conflicts',
66
+ 'Offer a shared-space checklist to reduce conflicts.'
67
+ ),
68
+ ],
69
69
  };
70
70
 
71
71
  export const ambientCoachTracks: LearningJourneyTrackSpec[] = [
72
- moneyAmbientCoachTrack,
73
- colivingAmbientCoachTrack,
72
+ moneyAmbientCoachTrack,
73
+ colivingAmbientCoachTrack,
74
74
  ];
package/tsconfig.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
- "extends": "@contractspec/tool.typescript/react-library.json",
3
- "include": ["src"],
4
- "exclude": ["node_modules"],
5
- "compilerOptions": {
6
- "rootDir": "src",
7
- "outDir": "dist"
8
- }
2
+ "extends": "@contractspec/tool.typescript/react-library.json",
3
+ "include": ["src"],
4
+ "exclude": ["node_modules"],
5
+ "compilerOptions": {
6
+ "rootDir": "src",
7
+ "outDir": "dist"
8
+ }
9
9
  }
package/tsdown.config.js CHANGED
@@ -1,16 +1,10 @@
1
- import { defineConfig, moduleLibrary, withDevExports } from '@contractspec/tool.bun';
1
+ import {
2
+ defineConfig,
3
+ moduleLibrary,
4
+ withDevExports,
5
+ } from '@contractspec/tool.bun';
2
6
 
3
7
  export default defineConfig(() => ({
4
- ...moduleLibrary,
5
- ...withDevExports,
8
+ ...moduleLibrary,
9
+ ...withDevExports,
6
10
  }));
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-