@contractspec/example.learning-journey-ui-gamified 1.46.1 → 1.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  $ tsdown
2
- ℹ tsdown v0.18.3 powered by rolldown v1.0.0-beta.57
2
+ ℹ tsdown v0.19.0 powered by rolldown v1.0.0-beta.59
3
3
  ℹ config file: /home/runner/work/contractspec/contractspec/packages/examples/learning-journey-ui-gamified/tsdown.config.js
4
- ℹ entry: src/GamifiedMiniApp.tsx, src/example.ts, src/index.ts, src/docs/index.ts, src/docs/learning-journey-ui-gamified.docblock.ts, src/components/DayCalendar.tsx, src/components/FlashCard.tsx, src/components/MasteryRing.tsx, src/components/index.ts, src/views/Overview.tsx, src/views/Progress.tsx, src/views/Steps.tsx, src/views/Timeline.tsx, src/views/index.ts
4
+ ℹ entry: src/GamifiedMiniApp.tsx, src/example.ts, src/index.ts, src/components/DayCalendar.tsx, src/components/FlashCard.tsx, src/components/MasteryRing.tsx, src/components/index.ts, src/docs/index.ts, src/docs/learning-journey-ui-gamified.docblock.ts, src/views/Overview.tsx, src/views/Progress.tsx, src/views/Steps.tsx, src/views/Timeline.tsx, src/views/index.ts
5
5
  ℹ target: esnext
6
6
  ℹ tsconfig: tsconfig.json
7
7
  ℹ Build start
@@ -14,21 +14,21 @@ $ tsdown
14
14
  ℹ dist/components/MasteryRing.js 2.15 kB │ gzip: 0.88 kB
15
15
  ℹ dist/views/Steps.js 1.63 kB │ gzip: 0.68 kB
16
16
  ℹ dist/components/DayCalendar.js 1.51 kB │ gzip: 0.68 kB
17
- ℹ dist/example.js 0.88 kB │ gzip: 0.49 kB
17
+ ℹ dist/example.js 0.96 kB │ gzip: 0.52 kB
18
18
  ℹ dist/docs/learning-journey-ui-gamified.docblock.js 0.83 kB │ gzip: 0.47 kB
19
19
  ℹ dist/index.js 0.67 kB │ gzip: 0.24 kB
20
20
  ℹ dist/views/index.js 0.21 kB │ gzip: 0.11 kB
21
21
  ℹ dist/components/index.js 0.19 kB │ gzip: 0.11 kB
22
22
  ℹ dist/docs/index.js 0.05 kB │ gzip: 0.07 kB
23
23
  ℹ dist/views/Timeline.js.map 9.32 kB │ gzip: 2.53 kB
24
- ℹ dist/views/Progress.js.map 8.41 kB │ gzip: 2.54 kB
24
+ ℹ dist/views/Progress.js.map 8.35 kB │ gzip: 2.53 kB
25
25
  ℹ dist/views/Overview.js.map 7.85 kB │ gzip: 2.37 kB
26
26
  ℹ dist/components/FlashCard.js.map 4.21 kB │ gzip: 1.56 kB
27
27
  ℹ dist/GamifiedMiniApp.js.map 3.62 kB │ gzip: 1.30 kB
28
28
  ℹ dist/components/MasteryRing.js.map 3.43 kB │ gzip: 1.34 kB
29
29
  ℹ dist/views/Steps.js.map 2.36 kB │ gzip: 1.04 kB
30
30
  ℹ dist/components/DayCalendar.js.map 2.28 kB │ gzip: 0.99 kB
31
- ℹ dist/example.js.map 1.40 kB │ gzip: 0.71 kB
31
+ ℹ dist/example.js.map 1.39 kB │ gzip: 0.71 kB
32
32
  ℹ dist/docs/learning-journey-ui-gamified.docblock.js.map 1.17 kB │ gzip: 0.63 kB
33
33
  ℹ dist/components/MasteryRing.d.ts.map 0.37 kB │ gzip: 0.23 kB
34
34
  ℹ dist/components/FlashCard.d.ts.map 0.32 kB │ gzip: 0.21 kB
@@ -38,20 +38,20 @@ $ tsdown
38
38
  ℹ dist/views/Progress.d.ts.map 0.17 kB │ gzip: 0.15 kB
39
39
  ℹ dist/views/Timeline.d.ts.map 0.17 kB │ gzip: 0.15 kB
40
40
  ℹ dist/views/Steps.d.ts.map 0.17 kB │ gzip: 0.15 kB
41
- ℹ dist/example.d.ts.map 0.12 kB │ gzip: 0.12 kB
41
+ ℹ dist/example.d.ts.map 0.14 kB │ gzip: 0.13 kB
42
42
  ℹ dist/index.d.ts 0.62 kB │ gzip: 0.22 kB
43
43
  ℹ dist/GamifiedMiniApp.d.ts 0.59 kB │ gzip: 0.33 kB
44
44
  ℹ dist/components/FlashCard.d.ts 0.53 kB │ gzip: 0.31 kB
45
45
  ℹ dist/views/Overview.d.ts 0.45 kB │ gzip: 0.29 kB
46
46
  ℹ dist/components/MasteryRing.d.ts 0.45 kB │ gzip: 0.28 kB
47
- ℹ dist/components/DayCalendar.d.ts 0.41 kB │ gzip: 0.24 kB
47
+ ℹ dist/components/DayCalendar.d.ts 0.41 kB │ gzip: 0.25 kB
48
48
  ℹ dist/views/Steps.d.ts 0.36 kB │ gzip: 0.25 kB
49
49
  ℹ dist/views/Progress.d.ts 0.35 kB │ gzip: 0.24 kB
50
50
  ℹ dist/views/Timeline.d.ts 0.35 kB │ gzip: 0.24 kB
51
+ ℹ dist/example.d.ts 0.25 kB │ gzip: 0.17 kB
51
52
  ℹ dist/views/index.d.ts 0.21 kB │ gzip: 0.11 kB
52
- ℹ dist/example.d.ts 0.20 kB │ gzip: 0.16 kB
53
53
  ℹ dist/components/index.d.ts 0.19 kB │ gzip: 0.11 kB
54
54
  ℹ dist/docs/index.d.ts 0.01 kB │ gzip: 0.03 kB
55
55
  ℹ dist/docs/learning-journey-ui-gamified.docblock.d.ts 0.01 kB │ gzip: 0.03 kB
56
- ℹ 47 files, total: 81.83 kB
57
- ✔ Build complete in 8869ms
56
+ ℹ 47 files, total: 81.90 kB
57
+ ✔ Build complete in 15049ms
@@ -1,7 +1,7 @@
1
1
  $ bun build:types && bun build:bundle
2
2
  $ tsc --noEmit
3
3
  $ tsdown
4
- ℹ tsdown v0.18.3 powered by rolldown v1.0.0-beta.57
4
+ ℹ tsdown v0.19.0 powered by rolldown v1.0.0-beta.59
5
5
  ℹ config file: /home/runner/work/contractspec/contractspec/packages/examples/learning-journey-ui-gamified/tsdown.config.js
6
6
  ℹ entry: src/GamifiedMiniApp.tsx, src/example.ts, src/index.ts, src/components/DayCalendar.tsx, src/components/FlashCard.tsx, src/components/MasteryRing.tsx, src/components/index.ts, src/docs/index.ts, src/docs/learning-journey-ui-gamified.docblock.ts, src/views/Overview.tsx, src/views/Progress.tsx, src/views/Steps.tsx, src/views/Timeline.tsx, src/views/index.ts
7
7
  ℹ target: esnext
@@ -15,21 +15,21 @@ $ tsdown
15
15
  ℹ dist/components/MasteryRing.js 2.15 kB │ gzip: 0.88 kB
16
16
  ℹ dist/views/Steps.js 1.63 kB │ gzip: 0.68 kB
17
17
  ℹ dist/components/DayCalendar.js 1.51 kB │ gzip: 0.68 kB
18
- ℹ dist/example.js 0.88 kB │ gzip: 0.49 kB
18
+ ℹ dist/example.js 0.96 kB │ gzip: 0.52 kB
19
19
  ℹ dist/docs/learning-journey-ui-gamified.docblock.js 0.83 kB │ gzip: 0.47 kB
20
20
  ℹ dist/index.js 0.67 kB │ gzip: 0.24 kB
21
21
  ℹ dist/views/index.js 0.21 kB │ gzip: 0.11 kB
22
22
  ℹ dist/components/index.js 0.19 kB │ gzip: 0.11 kB
23
23
  ℹ dist/docs/index.js 0.05 kB │ gzip: 0.07 kB
24
24
  ℹ dist/views/Timeline.js.map 9.32 kB │ gzip: 2.53 kB
25
- ℹ dist/views/Progress.js.map 8.41 kB │ gzip: 2.54 kB
25
+ ℹ dist/views/Progress.js.map 8.35 kB │ gzip: 2.53 kB
26
26
  ℹ dist/views/Overview.js.map 7.85 kB │ gzip: 2.37 kB
27
27
  ℹ dist/components/FlashCard.js.map 4.21 kB │ gzip: 1.56 kB
28
28
  ℹ dist/GamifiedMiniApp.js.map 3.62 kB │ gzip: 1.30 kB
29
29
  ℹ dist/components/MasteryRing.js.map 3.43 kB │ gzip: 1.34 kB
30
30
  ℹ dist/views/Steps.js.map 2.36 kB │ gzip: 1.04 kB
31
31
  ℹ dist/components/DayCalendar.js.map 2.28 kB │ gzip: 0.99 kB
32
- ℹ dist/example.js.map 1.40 kB │ gzip: 0.71 kB
32
+ ℹ dist/example.js.map 1.39 kB │ gzip: 0.71 kB
33
33
  ℹ dist/docs/learning-journey-ui-gamified.docblock.js.map 1.17 kB │ gzip: 0.63 kB
34
34
  ℹ dist/components/MasteryRing.d.ts.map 0.37 kB │ gzip: 0.23 kB
35
35
  ℹ dist/components/FlashCard.d.ts.map 0.32 kB │ gzip: 0.21 kB
@@ -39,7 +39,7 @@ $ tsdown
39
39
  ℹ dist/views/Progress.d.ts.map 0.17 kB │ gzip: 0.15 kB
40
40
  ℹ dist/views/Timeline.d.ts.map 0.17 kB │ gzip: 0.15 kB
41
41
  ℹ dist/views/Steps.d.ts.map 0.17 kB │ gzip: 0.15 kB
42
- ℹ dist/example.d.ts.map 0.12 kB │ gzip: 0.12 kB
42
+ ℹ dist/example.d.ts.map 0.14 kB │ gzip: 0.13 kB
43
43
  ℹ dist/index.d.ts 0.62 kB │ gzip: 0.22 kB
44
44
  ℹ dist/GamifiedMiniApp.d.ts 0.59 kB │ gzip: 0.33 kB
45
45
  ℹ dist/components/FlashCard.d.ts 0.53 kB │ gzip: 0.31 kB
@@ -49,10 +49,10 @@ $ tsdown
49
49
  ℹ dist/views/Steps.d.ts 0.36 kB │ gzip: 0.25 kB
50
50
  ℹ dist/views/Progress.d.ts 0.35 kB │ gzip: 0.24 kB
51
51
  ℹ dist/views/Timeline.d.ts 0.35 kB │ gzip: 0.24 kB
52
+ ℹ dist/example.d.ts 0.25 kB │ gzip: 0.17 kB
52
53
  ℹ dist/views/index.d.ts 0.21 kB │ gzip: 0.11 kB
53
- ℹ dist/example.d.ts 0.20 kB │ gzip: 0.16 kB
54
54
  ℹ dist/components/index.d.ts 0.19 kB │ gzip: 0.11 kB
55
55
  ℹ dist/docs/index.d.ts 0.01 kB │ gzip: 0.03 kB
56
56
  ℹ dist/docs/learning-journey-ui-gamified.docblock.d.ts 0.01 kB │ gzip: 0.03 kB
57
- ℹ 47 files, total: 81.83 kB
58
- ✔ Build complete in 8200ms
57
+ ℹ 47 files, total: 81.90 kB
58
+ ✔ Build complete in 12239ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,46 @@
1
1
  # @contractspec/example.learning-journey-ui-gamified
2
2
 
3
+ ## 1.47.0
4
+
5
+ ### Minor Changes
6
+
7
+ - caf8701: feat: add cli vibe command to run workflow
8
+ - c69b849: feat: add api web services (mcp & website)
9
+ - 42b8d78: feat: add cli `contractspec vibe` workflow to simplify usage
10
+ - fd38e85: feat: auto-fix contractspec issues
11
+
12
+ ### Patch Changes
13
+
14
+ - e7ded36: feat: improve stability (adding ts-morph)
15
+ - c231a8b: test: improve workspace stability
16
+ - Updated dependencies [e7ded36]
17
+ - Updated dependencies [caf8701]
18
+ - Updated dependencies [c69b849]
19
+ - Updated dependencies [c231a8b]
20
+ - Updated dependencies [42b8d78]
21
+ - Updated dependencies [fd38e85]
22
+ - @contractspec/example.learning-journey-quest-challenges@1.47.0
23
+ - @contractspec/example.learning-journey-duo-drills@1.47.0
24
+ - @contractspec/example.learning-journey-ui-shared@1.47.0
25
+ - @contractspec/module.learning-journey@1.47.0
26
+ - @contractspec/lib.design-system@1.47.0
27
+ - @contractspec/lib.ui-kit-web@1.47.0
28
+ - @contractspec/lib.contracts@1.47.0
29
+
30
+ ## 1.46.2
31
+
32
+ ### Patch Changes
33
+
34
+ - 7e21625: feat: library services (landing page & api)
35
+ - Updated dependencies [7e21625]
36
+ - @contractspec/example.learning-journey-quest-challenges@1.46.2
37
+ - @contractspec/example.learning-journey-duo-drills@1.46.2
38
+ - @contractspec/example.learning-journey-ui-shared@1.46.2
39
+ - @contractspec/module.learning-journey@1.46.2
40
+ - @contractspec/lib.design-system@1.46.2
41
+ - @contractspec/lib.ui-kit-web@1.46.2
42
+ - @contractspec/lib.contracts@1.46.2
43
+
3
44
  ## 1.46.1
4
45
 
5
46
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime0 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime1 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/components/DayCalendar.d.ts
4
4
  interface DayCalendarProps {
@@ -10,7 +10,7 @@ declare function DayCalendar({
10
10
  totalDays,
11
11
  currentDay,
12
12
  completedDays
13
- }: DayCalendarProps): react_jsx_runtime0.JSX.Element;
13
+ }: DayCalendarProps): react_jsx_runtime1.JSX.Element;
14
14
  //#endregion
15
15
  export { DayCalendar };
16
16
  //# sourceMappingURL=DayCalendar.d.ts.map
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime1 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime2 from "react/jsx-runtime";
2
2
  import { LearningJourneyStepSpec } from "@contractspec/module.learning-journey/track-spec";
3
3
 
4
4
  //#region src/components/FlashCard.d.ts
@@ -13,7 +13,7 @@ declare function FlashCard({
13
13
  isCompleted,
14
14
  isCurrent,
15
15
  onComplete
16
- }: FlashCardProps): react_jsx_runtime1.JSX.Element;
16
+ }: FlashCardProps): react_jsx_runtime2.JSX.Element;
17
17
  //#endregion
18
18
  export { FlashCard };
19
19
  //# sourceMappingURL=FlashCard.d.ts.map
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime2 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/components/MasteryRing.d.ts
4
4
  interface MasteryRingProps {
@@ -12,7 +12,7 @@ declare function MasteryRing({
12
12
  percentage,
13
13
  size,
14
14
  color
15
- }: MasteryRingProps): react_jsx_runtime2.JSX.Element;
15
+ }: MasteryRingProps): react_jsx_runtime0.JSX.Element;
16
16
  //#endregion
17
17
  export { MasteryRing };
18
18
  //# sourceMappingURL=MasteryRing.d.ts.map
package/dist/example.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { ExampleSpec } from "@contractspec/lib.contracts";
1
+ import * as _contractspec_lib_contracts0 from "@contractspec/lib.contracts";
2
2
 
3
3
  //#region src/example.d.ts
4
- declare const example: ExampleSpec;
4
+ declare const example: _contractspec_lib_contracts0.ExampleSpec;
5
5
  //#endregion
6
6
  export { example as default };
7
7
  //# sourceMappingURL=example.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"example.d.ts","names":[],"sources":["../src/example.ts"],"sourcesContent":[],"mappings":";;;cAEM,SAAS"}
1
+ {"version":3,"file":"example.d.ts","names":[],"sources":["../src/example.ts"],"sourcesContent":[],"mappings":";;;cAEM,SA0BJ,4BAAA,CA1BW"}
package/dist/example.js CHANGED
@@ -1,5 +1,7 @@
1
+ import { defineExample } from "@contractspec/lib.contracts";
2
+
1
3
  //#region src/example.ts
2
- const example = {
4
+ const example = defineExample({
3
5
  meta: {
4
6
  key: "learning-journey-ui-gamified",
5
7
  version: "1.0.0",
@@ -32,7 +34,7 @@ const example = {
32
34
  },
33
35
  mcp: { enabled: true }
34
36
  }
35
- };
37
+ });
36
38
  var example_default = example;
37
39
 
38
40
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"example.js","names":["example: ExampleSpec"],"sources":["../src/example.ts"],"sourcesContent":["import type { ExampleSpec } from '@contractspec/lib.contracts';\n\nconst example: ExampleSpec = {\n meta: {\n key: 'learning-journey-ui-gamified',\n version: '1.0.0',\n title: 'Learning Journey UI — Gamified',\n description:\n 'UI mini-app for gamified learning: flashcards, mastery ring, calendar.',\n kind: 'ui',\n visibility: 'public',\n stability: 'experimental',\n owners: ['@platform.core'],\n tags: ['learning', 'ui', 'gamified'],\n },\n docs: {\n rootDocId: 'docs.examples.learning-journey-ui-gamified',\n },\n entrypoints: {\n packageName: '@contractspec/example.learning-journey-ui-gamified',\n docs: './docs',\n },\n surfaces: {\n templates: true,\n sandbox: { enabled: true, modes: ['playground', 'markdown'] },\n studio: { enabled: true, installable: true },\n mcp: { enabled: true },\n },\n};\n\nexport default example;\n"],"mappings":";AAEA,MAAMA,UAAuB;CAC3B,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aACE;EACF,MAAM;EACN,YAAY;EACZ,WAAW;EACX,QAAQ,CAAC,iBAAiB;EAC1B,MAAM;GAAC;GAAY;GAAM;GAAW;EACrC;CACD,MAAM,EACJ,WAAW,8CACZ;CACD,aAAa;EACX,aAAa;EACb,MAAM;EACP;CACD,UAAU;EACR,WAAW;EACX,SAAS;GAAE,SAAS;GAAM,OAAO,CAAC,cAAc,WAAW;GAAE;EAC7D,QAAQ;GAAE,SAAS;GAAM,aAAa;GAAM;EAC5C,KAAK,EAAE,SAAS,MAAM;EACvB;CACF;AAED,sBAAe"}
1
+ {"version":3,"file":"example.js","names":[],"sources":["../src/example.ts"],"sourcesContent":["import { defineExample } from '@contractspec/lib.contracts';\n\nconst example = defineExample({\n meta: {\n key: 'learning-journey-ui-gamified',\n version: '1.0.0',\n title: 'Learning Journey UI — Gamified',\n description:\n 'UI mini-app for gamified learning: flashcards, mastery ring, calendar.',\n kind: 'ui',\n visibility: 'public',\n stability: 'experimental',\n owners: ['@platform.core'],\n tags: ['learning', 'ui', 'gamified'],\n },\n docs: {\n rootDocId: 'docs.examples.learning-journey-ui-gamified',\n },\n entrypoints: {\n packageName: '@contractspec/example.learning-journey-ui-gamified',\n docs: './docs',\n },\n surfaces: {\n templates: true,\n sandbox: { enabled: true, modes: ['playground', 'markdown'] },\n studio: { enabled: true, installable: true },\n mcp: { enabled: true },\n },\n});\n\nexport default example;\n"],"mappings":";;;AAEA,MAAM,UAAU,cAAc;CAC5B,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aACE;EACF,MAAM;EACN,YAAY;EACZ,WAAW;EACX,QAAQ,CAAC,iBAAiB;EAC1B,MAAM;GAAC;GAAY;GAAM;GAAW;EACrC;CACD,MAAM,EACJ,WAAW,8CACZ;CACD,aAAa;EACX,aAAa;EACb,MAAM;EACP;CACD,UAAU;EACR,WAAW;EACX,SAAS;GAAE,SAAS;GAAM,OAAO,CAAC,cAAc,WAAW;GAAE;EAC7D,QAAQ;GAAE,SAAS;GAAM,aAAa;GAAM;EAC5C,KAAK,EAAE,SAAS,MAAM;EACvB;CACF,CAAC;AAEF,sBAAe"}
@@ -1,11 +1,11 @@
1
1
  import { LearningViewProps } from "@contractspec/example.learning-journey-ui-shared";
2
- import * as react_jsx_runtime4 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime5 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/views/Progress.d.ts
5
5
  declare function Progress({
6
6
  track,
7
7
  progress
8
- }: LearningViewProps): react_jsx_runtime4.JSX.Element;
8
+ }: LearningViewProps): react_jsx_runtime5.JSX.Element;
9
9
  //#endregion
10
10
  export { Progress };
11
11
  //# sourceMappingURL=Progress.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Progress.js","names":["surfaceColors: ('green' | 'blue' | 'violet' | 'orange')[]"],"sources":["../../src/views/Progress.tsx"],"sourcesContent":["'use client';\n\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n} from '@contractspec/lib.ui-kit-web/ui/card';\nimport {\n XpBar,\n BadgeDisplay,\n} from '@contractspec/example.learning-journey-ui-shared';\nimport { MasteryRing } from '../components/MasteryRing';\nimport type { LearningViewProps } from '@contractspec/example.learning-journey-ui-shared';\n\nexport function Progress({ track, progress }: LearningViewProps) {\n const totalXp =\n track.totalXp ??\n track.steps.reduce((sum, s) => sum + (s.xpReward ?? 0), 0) +\n (track.completionRewards?.xpBonus ?? 0);\n\n const completedSteps = progress.completedStepIds.length;\n const totalSteps = track.steps.length;\n const percentComplete =\n totalSteps > 0 ? (completedSteps / totalSteps) * 100 : 0;\n\n // Group steps by metadata surface for mastery rings\n const surfaces = new Map<string, { total: number; completed: number }>();\n track.steps.forEach((step) => {\n const surface = (step.metadata?.surface as string) ?? 'general';\n const current = surfaces.get(surface) ?? { total: 0, completed: 0 };\n surfaces.set(surface, {\n total: current.total + 1,\n completed:\n current.completed +\n (progress.completedStepIds.includes(step.id) ? 1 : 0),\n });\n });\n\n const surfaceColors: ('green' | 'blue' | 'violet' | 'orange')[] = [\n 'green',\n 'blue',\n 'violet',\n 'orange',\n ];\n\n return (\n <div className=\"space-y-6\">\n {/* XP Progress */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <span>⚡</span>\n <span>Experience Points</span>\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"flex items-baseline gap-2\">\n <span className=\"text-4xl font-bold text-violet-500\">\n {progress.xpEarned.toLocaleString()}\n </span>\n <span className=\"text-muted-foreground\">\n / {totalXp.toLocaleString()} XP\n </span>\n </div>\n <XpBar\n current={progress.xpEarned}\n max={totalXp}\n showLabel={false}\n size=\"lg\"\n />\n\n {track.completionRewards?.xpBonus && percentComplete < 100 && (\n <p className=\"text-muted-foreground text-sm\">\n 🎁 Complete all steps for a{' '}\n <span className=\"font-semibold text-green-500\">\n +{track.completionRewards.xpBonus} XP\n </span>{' '}\n bonus!\n </p>\n )}\n </CardContent>\n </Card>\n\n {/* Mastery Rings */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <span>🎯</span>\n <span>Skill Mastery</span>\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"flex flex-wrap justify-center gap-6\">\n {Array.from(surfaces.entries()).map(([surface, data], index) => (\n <MasteryRing\n key={surface}\n label={surface.charAt(0).toUpperCase() + surface.slice(1)}\n percentage={(data.completed / data.total) * 100}\n color={surfaceColors[index % surfaceColors.length]}\n size=\"lg\"\n />\n ))}\n <MasteryRing\n label=\"Overall\"\n percentage={percentComplete}\n color=\"violet\"\n size=\"lg\"\n />\n </div>\n </CardContent>\n </Card>\n\n {/* Badges */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <span>🏅</span>\n <span>Badges Earned</span>\n </CardTitle>\n </CardHeader>\n <CardContent>\n <BadgeDisplay badges={progress.badges} size=\"lg\" maxVisible={10} />\n {progress.badges.length === 0 && (\n <p className=\"text-muted-foreground text-sm\">\n Complete the track to earn your first badge!\n </p>\n )}\n </CardContent>\n </Card>\n\n {/* Step Breakdown */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <span>📊</span>\n <span>Step Breakdown</span>\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2\">\n {track.steps.map((step) => {\n const isCompleted = progress.completedStepIds.includes(step.id);\n return (\n <div\n key={step.id}\n className=\"flex items-center justify-between rounded-lg border p-3\"\n >\n <div className=\"flex items-center gap-3\">\n <span\n className={\n isCompleted ? 'text-green-500' : 'text-muted-foreground'\n }\n >\n {isCompleted ? '✓' : '○'}\n </span>\n <span\n className={\n isCompleted\n ? 'text-foreground'\n : 'text-muted-foreground'\n }\n >\n {step.title}\n </span>\n </div>\n {step.xpReward && (\n <span\n className={`text-sm font-medium ${isCompleted ? 'text-green-500' : 'text-muted-foreground'}`}\n >\n {isCompleted ? '+' : ''}\n {step.xpReward} XP\n </span>\n )}\n </div>\n );\n })}\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"Progress.js","names":[],"sources":["../../src/views/Progress.tsx"],"sourcesContent":["'use client';\n\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n} from '@contractspec/lib.ui-kit-web/ui/card';\nimport {\n XpBar,\n BadgeDisplay,\n} from '@contractspec/example.learning-journey-ui-shared';\nimport { MasteryRing } from '../components/MasteryRing';\nimport type { LearningViewProps } from '@contractspec/example.learning-journey-ui-shared';\n\nexport function Progress({ track, progress }: LearningViewProps) {\n const totalXp =\n track.totalXp ??\n track.steps.reduce((sum, s) => sum + (s.xpReward ?? 0), 0) +\n (track.completionRewards?.xpBonus ?? 0);\n\n const completedSteps = progress.completedStepIds.length;\n const totalSteps = track.steps.length;\n const percentComplete =\n totalSteps > 0 ? (completedSteps / totalSteps) * 100 : 0;\n\n // Group steps by metadata surface for mastery rings\n const surfaces = new Map<string, { total: number; completed: number }>();\n track.steps.forEach((step) => {\n const surface = (step.metadata?.surface as string) ?? 'general';\n const current = surfaces.get(surface) ?? { total: 0, completed: 0 };\n surfaces.set(surface, {\n total: current.total + 1,\n completed:\n current.completed +\n (progress.completedStepIds.includes(step.id) ? 1 : 0),\n });\n });\n\n const surfaceColors: ('green' | 'blue' | 'violet' | 'orange')[] = [\n 'green',\n 'blue',\n 'violet',\n 'orange',\n ];\n\n return (\n <div className=\"space-y-6\">\n {/* XP Progress */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <span>⚡</span>\n <span>Experience Points</span>\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"flex items-baseline gap-2\">\n <span className=\"text-4xl font-bold text-violet-500\">\n {progress.xpEarned.toLocaleString()}\n </span>\n <span className=\"text-muted-foreground\">\n / {totalXp.toLocaleString()} XP\n </span>\n </div>\n <XpBar\n current={progress.xpEarned}\n max={totalXp}\n showLabel={false}\n size=\"lg\"\n />\n\n {track.completionRewards?.xpBonus && percentComplete < 100 && (\n <p className=\"text-muted-foreground text-sm\">\n 🎁 Complete all steps for a{' '}\n <span className=\"font-semibold text-green-500\">\n +{track.completionRewards.xpBonus} XP\n </span>{' '}\n bonus!\n </p>\n )}\n </CardContent>\n </Card>\n\n {/* Mastery Rings */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <span>🎯</span>\n <span>Skill Mastery</span>\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"flex flex-wrap justify-center gap-6\">\n {Array.from(surfaces.entries()).map(([surface, data], index) => (\n <MasteryRing\n key={surface}\n label={surface.charAt(0).toUpperCase() + surface.slice(1)}\n percentage={(data.completed / data.total) * 100}\n color={surfaceColors[index % surfaceColors.length]}\n size=\"lg\"\n />\n ))}\n <MasteryRing\n label=\"Overall\"\n percentage={percentComplete}\n color=\"violet\"\n size=\"lg\"\n />\n </div>\n </CardContent>\n </Card>\n\n {/* Badges */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <span>🏅</span>\n <span>Badges Earned</span>\n </CardTitle>\n </CardHeader>\n <CardContent>\n <BadgeDisplay badges={progress.badges} size=\"lg\" maxVisible={10} />\n {progress.badges.length === 0 && (\n <p className=\"text-muted-foreground text-sm\">\n Complete the track to earn your first badge!\n </p>\n )}\n </CardContent>\n </Card>\n\n {/* Step Breakdown */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <span>📊</span>\n <span>Step Breakdown</span>\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2\">\n {track.steps.map((step) => {\n const isCompleted = progress.completedStepIds.includes(step.id);\n return (\n <div\n key={step.id}\n className=\"flex items-center justify-between rounded-lg border p-3\"\n >\n <div className=\"flex items-center gap-3\">\n <span\n className={\n isCompleted ? 'text-green-500' : 'text-muted-foreground'\n }\n >\n {isCompleted ? '✓' : '○'}\n </span>\n <span\n className={\n isCompleted\n ? 'text-foreground'\n : 'text-muted-foreground'\n }\n >\n {step.title}\n </span>\n </div>\n {step.xpReward && (\n <span\n className={`text-sm font-medium ${isCompleted ? 'text-green-500' : 'text-muted-foreground'}`}\n >\n {isCompleted ? '+' : ''}\n {step.xpReward} XP\n </span>\n )}\n </div>\n );\n })}\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  import { LearningViewProps } from "@contractspec/example.learning-journey-ui-shared";
2
- import * as react_jsx_runtime6 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime4 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/views/Steps.d.ts
5
5
  declare function Steps({
6
6
  track,
7
7
  progress,
8
8
  onStepComplete
9
- }: LearningViewProps): react_jsx_runtime6.JSX.Element;
9
+ }: LearningViewProps): react_jsx_runtime4.JSX.Element;
10
10
  //#endregion
11
11
  export { Steps };
12
12
  //# sourceMappingURL=Steps.d.ts.map
@@ -1,11 +1,11 @@
1
1
  import { LearningViewProps } from "@contractspec/example.learning-journey-ui-shared";
2
- import * as react_jsx_runtime5 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime6 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/views/Timeline.d.ts
5
5
  declare function Timeline({
6
6
  track,
7
7
  progress
8
- }: LearningViewProps): react_jsx_runtime5.JSX.Element;
8
+ }: LearningViewProps): react_jsx_runtime6.JSX.Element;
9
9
  //#endregion
10
10
  export { Timeline };
11
11
  //# sourceMappingURL=Timeline.d.ts.map
package/package.json CHANGED
@@ -1,9 +1,8 @@
1
1
  {
2
2
  "name": "@contractspec/example.learning-journey-ui-gamified",
3
- "version": "1.46.1",
3
+ "version": "1.47.0",
4
4
  "description": "Duolingo-style gamified learning UI for drills and quests.",
5
5
  "type": "module",
6
- "main": "./dist/index.js",
7
6
  "types": "./dist/index.d.ts",
8
7
  "exports": {
9
8
  ".": "./dist/index.js",
@@ -36,26 +35,25 @@
36
35
  "test": "bun test"
37
36
  },
38
37
  "dependencies": {
39
- "@contractspec/lib.contracts": "1.46.1",
40
- "@contractspec/example.learning-journey-ui-shared": "1.46.1",
41
- "@contractspec/example.learning-journey-duo-drills": "1.46.1",
42
- "@contractspec/example.learning-journey-quest-challenges": "1.46.1",
43
- "@contractspec/module.learning-journey": "1.46.1",
44
- "@contractspec/lib.design-system": "1.46.1",
45
- "@contractspec/lib.ui-kit-web": "1.46.1",
38
+ "@contractspec/lib.contracts": "1.47.0",
39
+ "@contractspec/example.learning-journey-ui-shared": "1.47.0",
40
+ "@contractspec/example.learning-journey-duo-drills": "1.47.0",
41
+ "@contractspec/example.learning-journey-quest-challenges": "1.47.0",
42
+ "@contractspec/module.learning-journey": "1.47.0",
43
+ "@contractspec/lib.design-system": "1.47.0",
44
+ "@contractspec/lib.ui-kit-web": "1.47.0",
46
45
  "react": "19.2.3"
47
46
  },
48
47
  "devDependencies": {
49
- "@contractspec/tool.tsdown": "1.46.1",
50
- "@contractspec/tool.typescript": "1.46.1",
51
- "@types/react": "^19.1.6",
52
- "tsdown": "^0.18.3",
48
+ "@contractspec/tool.tsdown": "1.47.0",
49
+ "@contractspec/tool.typescript": "1.47.0",
50
+ "@types/react": "^19.2.8",
51
+ "tsdown": "^0.19.0",
53
52
  "typescript": "^5.9.3"
54
53
  },
55
54
  "peerDependencies": {
56
55
  "react": "^19.2.3"
57
56
  },
58
- "module": "./dist/index.js",
59
57
  "publishConfig": {
60
58
  "exports": {
61
59
  ".": "./dist/index.js",
package/src/example.ts CHANGED
@@ -1,6 +1,6 @@
1
- import type { ExampleSpec } from '@contractspec/lib.contracts';
1
+ import { defineExample } from '@contractspec/lib.contracts';
2
2
 
3
- const example: ExampleSpec = {
3
+ const example = defineExample({
4
4
  meta: {
5
5
  key: 'learning-journey-ui-gamified',
6
6
  version: '1.0.0',
@@ -26,6 +26,6 @@ const example: ExampleSpec = {
26
26
  studio: { enabled: true, installable: true },
27
27
  mcp: { enabled: true },
28
28
  },
29
- };
29
+ });
30
30
 
31
31
  export default example;