@contractspec/example.learning-journey-quest-challenges 3.7.6 → 3.7.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +3 -3
- package/AGENTS.md +40 -18
- package/CHANGELOG.md +21 -0
- package/README.md +58 -19
- package/dist/browser/index.js +16 -16
- package/dist/index.d.ts +2 -2
- package/dist/index.js +16 -16
- package/dist/node/index.js +16 -16
- package/package.json +7 -7
- package/src/docs/quest-challenges.docblock.ts +11 -11
- package/src/example.ts +25 -25
- package/src/index.ts +2 -2
- package/src/learning-journey-quest-challenges.feature.ts +12 -12
- package/src/track.test.ts +39 -39
- package/src/track.ts +66 -66
- package/tsconfig.json +7 -7
- package/tsdown.config.js +7 -13
package/.turbo/turbo-build.log
CHANGED
|
@@ -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
|
|
6
|
+
Bundled 6 modules in 16ms
|
|
7
7
|
|
|
8
8
|
docs/index.js 1.53 KB (entry point)
|
|
9
9
|
./index.js 4.57 KB (entry point)
|
|
@@ -13,7 +13,7 @@ Bundled 6 modules in 29ms
|
|
|
13
13
|
./track.js 1.43 KB (entry point)
|
|
14
14
|
|
|
15
15
|
[contractspec-bun-build] transpile target=node root=src entries=6 noBundle=false
|
|
16
|
-
Bundled 6 modules in
|
|
16
|
+
Bundled 6 modules in 27ms
|
|
17
17
|
|
|
18
18
|
docs/index.js 1.50 KB (entry point)
|
|
19
19
|
./index.js 4.53 KB (entry point)
|
|
@@ -23,7 +23,7 @@ Bundled 6 modules in 13ms
|
|
|
23
23
|
./track.js 1.42 KB (entry point)
|
|
24
24
|
|
|
25
25
|
[contractspec-bun-build] transpile target=browser root=src entries=6 noBundle=false
|
|
26
|
-
Bundled 6 modules in
|
|
26
|
+
Bundled 6 modules in 15ms
|
|
27
27
|
|
|
28
28
|
docs/index.js 1.50 KB (entry point)
|
|
29
29
|
./index.js 4.53 KB (entry point)
|
package/AGENTS.md
CHANGED
|
@@ -1,31 +1,53 @@
|
|
|
1
|
-
# AI Agent Guide
|
|
1
|
+
# AI Agent Guide — `@contractspec/example.learning-journey-quest-challenges`
|
|
2
2
|
|
|
3
3
|
Scope: `packages/examples/learning-journey-quest-challenges/*`
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Time-bound quest/challenge learning journey example.
|
|
6
6
|
|
|
7
7
|
## Quick Context
|
|
8
8
|
|
|
9
|
-
-
|
|
10
|
-
-
|
|
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
|
-
##
|
|
14
|
+
## Architecture
|
|
13
15
|
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
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-quest-challenges.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
|
|
23
|
+
## Public Surface
|
|
20
24
|
|
|
21
|
-
- `.`
|
|
22
|
-
- `./docs`
|
|
23
|
-
- `./
|
|
24
|
-
- `./
|
|
25
|
+
- Export `.` resolves through `./src/index.ts`.
|
|
26
|
+
- Export `./docs` resolves through `./src/docs/index.ts`.
|
|
27
|
+
- Export `./docs/quest-challenges.docblock` resolves through `./src/docs/quest-challenges.docblock.ts`.
|
|
28
|
+
- Export `./example` resolves through `./src/example.ts`.
|
|
29
|
+
- Export `./learning-journey-quest-challenges.feature` resolves through `./src/learning-journey-quest-challenges.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
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @contractspec/example.learning-journey-quest-challenges
|
|
2
2
|
|
|
3
|
+
## 3.7.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1a44cb6: feat: improve examples to increase coverage of Contracts type
|
|
8
|
+
- Updated dependencies [1a44cb6]
|
|
9
|
+
- @contractspec/module.learning-journey@3.7.10
|
|
10
|
+
- @contractspec/lib.contracts-spec@4.1.2
|
|
11
|
+
|
|
12
|
+
## 3.7.9
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- fix: release
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- @contractspec/module.learning-journey@3.7.9
|
|
19
|
+
- @contractspec/lib.contracts-spec@4.1.1
|
|
20
|
+
|
|
3
21
|
## 3.7.6
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
|
@@ -708,14 +726,17 @@
|
|
|
708
726
|
feat: Contract layers support (features, examples, app-configs)
|
|
709
727
|
|
|
710
728
|
### New CLI Commands
|
|
729
|
+
|
|
711
730
|
- `contractspec list layers` - List all contract layers with filtering
|
|
712
731
|
|
|
713
732
|
### Enhanced Commands
|
|
733
|
+
|
|
714
734
|
- `contractspec ci` - New `layers` check category validates features/examples/config
|
|
715
735
|
- `contractspec doctor` - New `layers` health checks
|
|
716
736
|
- `contractspec integrity` - Now shows layer statistics
|
|
717
737
|
|
|
718
738
|
### New APIs
|
|
739
|
+
|
|
719
740
|
- `discoverLayers()` - Scan workspace for all layer files
|
|
720
741
|
- `scanExampleSource()` - Parse ExampleSpec from source code
|
|
721
742
|
- `isExampleFile()` - Check if file is an example spec
|
package/README.md
CHANGED
|
@@ -1,30 +1,69 @@
|
|
|
1
1
|
# @contractspec/example.learning-journey-quest-challenges
|
|
2
2
|
|
|
3
|
-
Website: https://contractspec.io
|
|
3
|
+
Website: https://contractspec.io
|
|
4
4
|
|
|
5
|
+
**Time-bound quest/challenge learning journey example.**
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
## What This Demonstrates
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
- Quest/challenge track with time-bound objectives.
|
|
10
|
+
- Completion tracking and deadline enforcement.
|
|
11
|
+
- Lightweight track + example pattern.
|
|
12
|
+
- Integration with the learning-journey module.
|
|
13
|
+
- `src/docs/` contains docblocks and documentation-facing exports.
|
|
14
|
+
- `src/docs/` contains docblocks and documentation-facing exports.
|
|
9
15
|
|
|
10
|
-
|
|
11
|
-
- Event-based completions for each day
|
|
12
|
-
- XP per day with completion bonus when finished within duration
|
|
13
|
-
- Optional recap via SRS mastery events
|
|
16
|
+
## Running Locally
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
From `packages/examples/learning-journey-quest-challenges`:
|
|
19
|
+
- `bun run dev`
|
|
20
|
+
- `bun run build`
|
|
21
|
+
- `bun run test`
|
|
22
|
+
- `bun run typecheck`
|
|
16
23
|
|
|
17
|
-
|
|
18
|
-
2. Emit events in order with `recordEvent` from the registry:
|
|
24
|
+
## Usage
|
|
19
25
|
|
|
20
|
-
|
|
21
|
-
recordEvent({ name: 'accounts.mapped', learnerId: 'u1' });
|
|
22
|
-
recordEvent({ name: 'transactions.categorized', learnerId: 'u1' });
|
|
23
|
-
// ...
|
|
24
|
-
```
|
|
26
|
+
Use `@contractspec/example.learning-journey-quest-challenges` as a reference implementation, or import its exported surfaces into a workspace that composes ContractSpec examples and bundles.
|
|
25
27
|
|
|
26
|
-
##
|
|
28
|
+
## Architecture
|
|
27
29
|
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
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-quest-challenges.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/quest-challenges.docblock` resolves through `./src/docs/quest-challenges.docblock.ts`.
|
|
42
|
+
- Export `./example` resolves through `./src/example.ts`.
|
|
43
|
+
- Export `./learning-journey-quest-challenges.feature` resolves through `./src/learning-journey-quest-challenges.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`.
|
package/dist/browser/index.js
CHANGED
|
@@ -61,6 +61,22 @@ var example = defineExample({
|
|
|
61
61
|
});
|
|
62
62
|
var example_default = example;
|
|
63
63
|
|
|
64
|
+
// src/learning-journey-quest-challenges.feature.ts
|
|
65
|
+
import { defineFeature } from "@contractspec/lib.contracts-spec";
|
|
66
|
+
var LearningJourneyQuestChallengesFeature = defineFeature({
|
|
67
|
+
meta: {
|
|
68
|
+
key: "learning-journey-quest-challenges",
|
|
69
|
+
version: "1.0.0",
|
|
70
|
+
title: "Learning Journey: Quest Challenges",
|
|
71
|
+
description: "Quest and challenge-based learning with deadlines and completion tracking",
|
|
72
|
+
domain: "learning-journey",
|
|
73
|
+
owners: ["@examples"],
|
|
74
|
+
tags: ["learning", "quests", "challenges", "gamification"],
|
|
75
|
+
stability: "experimental"
|
|
76
|
+
},
|
|
77
|
+
docs: ["docs.learning-journey.quest-challenges"]
|
|
78
|
+
});
|
|
79
|
+
|
|
64
80
|
// src/track.ts
|
|
65
81
|
var dayStep = (id, day, eventName, description) => ({
|
|
66
82
|
id,
|
|
@@ -93,22 +109,6 @@ var moneyResetQuestTrack = {
|
|
|
93
109
|
]
|
|
94
110
|
};
|
|
95
111
|
var questTracks = [moneyResetQuestTrack];
|
|
96
|
-
|
|
97
|
-
// src/learning-journey-quest-challenges.feature.ts
|
|
98
|
-
import { defineFeature } from "@contractspec/lib.contracts-spec";
|
|
99
|
-
var LearningJourneyQuestChallengesFeature = defineFeature({
|
|
100
|
-
meta: {
|
|
101
|
-
key: "learning-journey-quest-challenges",
|
|
102
|
-
version: "1.0.0",
|
|
103
|
-
title: "Learning Journey: Quest Challenges",
|
|
104
|
-
description: "Quest and challenge-based learning with deadlines and completion tracking",
|
|
105
|
-
domain: "learning-journey",
|
|
106
|
-
owners: ["@examples"],
|
|
107
|
-
tags: ["learning", "quests", "challenges", "gamification"],
|
|
108
|
-
stability: "experimental"
|
|
109
|
-
},
|
|
110
|
-
docs: ["docs.learning-journey.quest-challenges"]
|
|
111
|
-
});
|
|
112
112
|
export {
|
|
113
113
|
questTracks,
|
|
114
114
|
moneyResetQuestTrack,
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -62,6 +62,22 @@ var example = defineExample({
|
|
|
62
62
|
});
|
|
63
63
|
var example_default = example;
|
|
64
64
|
|
|
65
|
+
// src/learning-journey-quest-challenges.feature.ts
|
|
66
|
+
import { defineFeature } from "@contractspec/lib.contracts-spec";
|
|
67
|
+
var LearningJourneyQuestChallengesFeature = defineFeature({
|
|
68
|
+
meta: {
|
|
69
|
+
key: "learning-journey-quest-challenges",
|
|
70
|
+
version: "1.0.0",
|
|
71
|
+
title: "Learning Journey: Quest Challenges",
|
|
72
|
+
description: "Quest and challenge-based learning with deadlines and completion tracking",
|
|
73
|
+
domain: "learning-journey",
|
|
74
|
+
owners: ["@examples"],
|
|
75
|
+
tags: ["learning", "quests", "challenges", "gamification"],
|
|
76
|
+
stability: "experimental"
|
|
77
|
+
},
|
|
78
|
+
docs: ["docs.learning-journey.quest-challenges"]
|
|
79
|
+
});
|
|
80
|
+
|
|
65
81
|
// src/track.ts
|
|
66
82
|
var dayStep = (id, day, eventName, description) => ({
|
|
67
83
|
id,
|
|
@@ -94,22 +110,6 @@ var moneyResetQuestTrack = {
|
|
|
94
110
|
]
|
|
95
111
|
};
|
|
96
112
|
var questTracks = [moneyResetQuestTrack];
|
|
97
|
-
|
|
98
|
-
// src/learning-journey-quest-challenges.feature.ts
|
|
99
|
-
import { defineFeature } from "@contractspec/lib.contracts-spec";
|
|
100
|
-
var LearningJourneyQuestChallengesFeature = defineFeature({
|
|
101
|
-
meta: {
|
|
102
|
-
key: "learning-journey-quest-challenges",
|
|
103
|
-
version: "1.0.0",
|
|
104
|
-
title: "Learning Journey: Quest Challenges",
|
|
105
|
-
description: "Quest and challenge-based learning with deadlines and completion tracking",
|
|
106
|
-
domain: "learning-journey",
|
|
107
|
-
owners: ["@examples"],
|
|
108
|
-
tags: ["learning", "quests", "challenges", "gamification"],
|
|
109
|
-
stability: "experimental"
|
|
110
|
-
},
|
|
111
|
-
docs: ["docs.learning-journey.quest-challenges"]
|
|
112
|
-
});
|
|
113
113
|
export {
|
|
114
114
|
questTracks,
|
|
115
115
|
moneyResetQuestTrack,
|
package/dist/node/index.js
CHANGED
|
@@ -61,6 +61,22 @@ var example = defineExample({
|
|
|
61
61
|
});
|
|
62
62
|
var example_default = example;
|
|
63
63
|
|
|
64
|
+
// src/learning-journey-quest-challenges.feature.ts
|
|
65
|
+
import { defineFeature } from "@contractspec/lib.contracts-spec";
|
|
66
|
+
var LearningJourneyQuestChallengesFeature = defineFeature({
|
|
67
|
+
meta: {
|
|
68
|
+
key: "learning-journey-quest-challenges",
|
|
69
|
+
version: "1.0.0",
|
|
70
|
+
title: "Learning Journey: Quest Challenges",
|
|
71
|
+
description: "Quest and challenge-based learning with deadlines and completion tracking",
|
|
72
|
+
domain: "learning-journey",
|
|
73
|
+
owners: ["@examples"],
|
|
74
|
+
tags: ["learning", "quests", "challenges", "gamification"],
|
|
75
|
+
stability: "experimental"
|
|
76
|
+
},
|
|
77
|
+
docs: ["docs.learning-journey.quest-challenges"]
|
|
78
|
+
});
|
|
79
|
+
|
|
64
80
|
// src/track.ts
|
|
65
81
|
var dayStep = (id, day, eventName, description) => ({
|
|
66
82
|
id,
|
|
@@ -93,22 +109,6 @@ var moneyResetQuestTrack = {
|
|
|
93
109
|
]
|
|
94
110
|
};
|
|
95
111
|
var questTracks = [moneyResetQuestTrack];
|
|
96
|
-
|
|
97
|
-
// src/learning-journey-quest-challenges.feature.ts
|
|
98
|
-
import { defineFeature } from "@contractspec/lib.contracts-spec";
|
|
99
|
-
var LearningJourneyQuestChallengesFeature = defineFeature({
|
|
100
|
-
meta: {
|
|
101
|
-
key: "learning-journey-quest-challenges",
|
|
102
|
-
version: "1.0.0",
|
|
103
|
-
title: "Learning Journey: Quest Challenges",
|
|
104
|
-
description: "Quest and challenge-based learning with deadlines and completion tracking",
|
|
105
|
-
domain: "learning-journey",
|
|
106
|
-
owners: ["@examples"],
|
|
107
|
-
tags: ["learning", "quests", "challenges", "gamification"],
|
|
108
|
-
stability: "experimental"
|
|
109
|
-
},
|
|
110
|
-
docs: ["docs.learning-journey.quest-challenges"]
|
|
111
|
-
});
|
|
112
112
|
export {
|
|
113
113
|
questTracks,
|
|
114
114
|
moneyResetQuestTrack,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contractspec/example.learning-journey-quest-challenges",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.10",
|
|
4
4
|
"description": "Time-bound quest/challenge learning journey example.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -57,20 +57,20 @@
|
|
|
57
57
|
"dev": "contractspec-bun-build dev",
|
|
58
58
|
"clean": "rimraf dist .turbo",
|
|
59
59
|
"lint": "bun lint:fix",
|
|
60
|
-
"lint:fix": "
|
|
61
|
-
"lint:check": "
|
|
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.
|
|
68
|
-
"@contractspec/lib.contracts-spec": "
|
|
67
|
+
"@contractspec/module.learning-journey": "3.7.10",
|
|
68
|
+
"@contractspec/lib.contracts-spec": "4.1.2"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@contractspec/tool.typescript": "3.7.
|
|
71
|
+
"@contractspec/tool.typescript": "3.7.8",
|
|
72
72
|
"typescript": "^5.9.3",
|
|
73
|
-
"@contractspec/tool.bun": "3.7.
|
|
73
|
+
"@contractspec/tool.bun": "3.7.8"
|
|
74
74
|
},
|
|
75
75
|
"publishConfig": {
|
|
76
76
|
"exports": {
|
|
@@ -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 questDocBlocks: DocBlock[] = [
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
{
|
|
6
|
+
id: 'docs.learning-journey.quest-challenges',
|
|
7
|
+
title: 'Learning Journey — Quest Challenges',
|
|
8
|
+
summary:
|
|
9
|
+
'Time-bound challenge pattern (7-day money reset) with day unlocks and event-driven completion.',
|
|
10
|
+
kind: 'reference',
|
|
11
|
+
visibility: 'public',
|
|
12
|
+
route: '/docs/learning-journey/quest-challenges',
|
|
13
|
+
tags: ['learning', 'quest', 'challenge'],
|
|
14
|
+
body: `## Track
|
|
15
15
|
- **Key**: \`money_reset_7day\`
|
|
16
16
|
- **Duration**: 7 days, steps unlock day by day
|
|
17
17
|
|
|
@@ -30,7 +30,7 @@ XP: 15 per day, completion bonus 30 if finished within duration. Optional recap
|
|
|
30
30
|
- Exported via \`@contractspec/example.learning-journey-quest-challenges/track\`.
|
|
31
31
|
- Step availability uses \`availability.unlockOnDay\` to gate days.
|
|
32
32
|
- Registry progression handles event matching and XP application.`,
|
|
33
|
-
|
|
33
|
+
},
|
|
34
34
|
];
|
|
35
35
|
|
|
36
36
|
registerDocBlocks(questDocBlocks);
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
4
|
+
meta: {
|
|
5
|
+
key: 'learning-journey-quest-challenges',
|
|
6
|
+
version: '1.0.0',
|
|
7
|
+
title: 'Learning Journey — Quest Challenges',
|
|
8
|
+
description:
|
|
9
|
+
'Quest/challenge pattern: multi-step goals with progress events, rewards, and streak hooks.',
|
|
10
|
+
kind: 'template',
|
|
11
|
+
visibility: 'public',
|
|
12
|
+
stability: 'experimental',
|
|
13
|
+
owners: ['@platform.core'],
|
|
14
|
+
tags: ['learning', 'quests', 'challenges'],
|
|
15
|
+
},
|
|
16
|
+
docs: {
|
|
17
|
+
rootDocId: 'docs.learning-journey.quest-challenges',
|
|
18
|
+
},
|
|
19
|
+
entrypoints: {
|
|
20
|
+
packageName: '@contractspec/example.learning-journey-quest-challenges',
|
|
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,17 +1,17 @@
|
|
|
1
1
|
import { defineFeature } from '@contractspec/lib.contracts-spec';
|
|
2
2
|
|
|
3
3
|
export const LearningJourneyQuestChallengesFeature = defineFeature({
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
4
|
+
meta: {
|
|
5
|
+
key: 'learning-journey-quest-challenges',
|
|
6
|
+
version: '1.0.0',
|
|
7
|
+
title: 'Learning Journey: Quest Challenges',
|
|
8
|
+
description:
|
|
9
|
+
'Quest and challenge-based learning with deadlines and completion tracking',
|
|
10
|
+
domain: 'learning-journey',
|
|
11
|
+
owners: ['@examples'],
|
|
12
|
+
tags: ['learning', 'quests', 'challenges', 'gamification'],
|
|
13
|
+
stability: 'experimental',
|
|
14
|
+
},
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
docs: ['docs.learning-journey.quest-challenges'],
|
|
17
17
|
});
|
package/src/track.test.ts
CHANGED
|
@@ -3,50 +3,50 @@ import { describe, expect, it } from 'bun:test';
|
|
|
3
3
|
import { moneyResetQuestTrack } from './track';
|
|
4
4
|
|
|
5
5
|
const addDays = (date: Date, days: number) =>
|
|
6
|
-
|
|
6
|
+
new Date(date.getTime() + days * 24 * 60 * 60 * 1000);
|
|
7
7
|
|
|
8
8
|
type StepStatus = 'PENDING' | 'COMPLETED';
|
|
9
9
|
|
|
10
10
|
describe('quest challenges track', () => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
it('unlocks by day and completes within window', () => {
|
|
12
|
+
const start = new Date('2024-01-01T09:00:00Z');
|
|
13
|
+
const events = [
|
|
14
|
+
{ name: 'accounts.mapped', dayOffset: 0 },
|
|
15
|
+
{ name: 'transactions.categorized', dayOffset: 1 },
|
|
16
|
+
{ name: 'goals.created', dayOffset: 2 },
|
|
17
|
+
{ name: 'recurring_rule.created', dayOffset: 3 },
|
|
18
|
+
{ name: 'subscription.flagged_or_cancelled', dayOffset: 4 },
|
|
19
|
+
{ name: 'emergency_plan.completed', dayOffset: 5 },
|
|
20
|
+
{ name: 'quest.review.completed', dayOffset: 6 },
|
|
21
|
+
];
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
const progress = moneyResetQuestTrack.steps.map((step) => ({
|
|
24
|
+
id: step.id,
|
|
25
|
+
status: 'PENDING' as StepStatus,
|
|
26
|
+
}));
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
28
|
+
events.forEach((evt) => {
|
|
29
|
+
const now = addDays(start, evt.dayOffset);
|
|
30
|
+
moneyResetQuestTrack.steps.forEach((spec, idx) => {
|
|
31
|
+
const step = progress[idx];
|
|
32
|
+
if (!step || step.status === 'COMPLETED') return;
|
|
33
|
+
const availableAt =
|
|
34
|
+
spec.availability?.unlockOnDay !== undefined
|
|
35
|
+
? addDays(start, spec.availability.unlockOnDay - 1)
|
|
36
|
+
: start;
|
|
37
|
+
if (now < availableAt) return;
|
|
38
|
+
const within =
|
|
39
|
+
spec.completion.kind === 'time_window' &&
|
|
40
|
+
spec.completion.withinHoursOfStart !== undefined
|
|
41
|
+
? (now.getTime() - start.getTime()) / (1000 * 60 * 60) <=
|
|
42
|
+
spec.completion.withinHoursOfStart
|
|
43
|
+
: true;
|
|
44
|
+
if (!within) return;
|
|
45
|
+
if (spec.completion.eventName !== evt.name) return;
|
|
46
|
+
step.status = 'COMPLETED';
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
expect(progress.every((s) => s.status === 'COMPLETED')).toBeTrue();
|
|
51
|
+
});
|
|
52
52
|
});
|
package/src/track.ts
CHANGED
|
@@ -1,76 +1,76 @@
|
|
|
1
1
|
import type { LearningJourneyTrackSpec } from '@contractspec/module.learning-journey/track-spec';
|
|
2
2
|
|
|
3
3
|
const dayStep = (
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
id: string,
|
|
5
|
+
day: number,
|
|
6
|
+
eventName: string,
|
|
7
|
+
description: string
|
|
8
8
|
): LearningJourneyTrackSpec['steps'][number] => ({
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
id,
|
|
10
|
+
title: `Day ${day}`,
|
|
11
|
+
description,
|
|
12
|
+
availability: { unlockOnDay: day },
|
|
13
|
+
completion: {
|
|
14
|
+
kind: 'time_window',
|
|
15
|
+
eventName,
|
|
16
|
+
withinHoursOfStart: (day + 1) * 24, // allow grace through next day
|
|
17
|
+
},
|
|
18
|
+
xpReward: 15,
|
|
19
|
+
metadata: { day },
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
export const moneyResetQuestTrack: LearningJourneyTrackSpec = {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
23
|
+
id: 'money_reset_7day',
|
|
24
|
+
name: '7-day Money Reset',
|
|
25
|
+
description:
|
|
26
|
+
'Time-bound quest to reset personal finances over a focused week.',
|
|
27
|
+
targetUserSegment: 'money_user',
|
|
28
|
+
totalXp: 105,
|
|
29
|
+
completionRewards: { xpBonus: 30 },
|
|
30
|
+
steps: [
|
|
31
|
+
dayStep(
|
|
32
|
+
'day1_map_accounts',
|
|
33
|
+
1,
|
|
34
|
+
'accounts.mapped',
|
|
35
|
+
'Map bank and card accounts.'
|
|
36
|
+
),
|
|
37
|
+
dayStep(
|
|
38
|
+
'day2_categorize_transactions',
|
|
39
|
+
2,
|
|
40
|
+
'transactions.categorized',
|
|
41
|
+
'Categorize recent transactions.'
|
|
42
|
+
),
|
|
43
|
+
dayStep(
|
|
44
|
+
'day3_define_goals',
|
|
45
|
+
3,
|
|
46
|
+
'goals.created',
|
|
47
|
+
'Define at least one savings goal.'
|
|
48
|
+
),
|
|
49
|
+
dayStep(
|
|
50
|
+
'day4_setup_recurring_savings',
|
|
51
|
+
4,
|
|
52
|
+
'recurring_rule.created',
|
|
53
|
+
'Set a recurring savings rule.'
|
|
54
|
+
),
|
|
55
|
+
dayStep(
|
|
56
|
+
'day5_review_subscriptions',
|
|
57
|
+
5,
|
|
58
|
+
'subscription.flagged_or_cancelled',
|
|
59
|
+
'Review subscriptions and flag or cancel wasteful ones.'
|
|
60
|
+
),
|
|
61
|
+
dayStep(
|
|
62
|
+
'day6_plan_emergency',
|
|
63
|
+
6,
|
|
64
|
+
'emergency_plan.completed',
|
|
65
|
+
'Draft an emergency plan and target buffer.'
|
|
66
|
+
),
|
|
67
|
+
dayStep(
|
|
68
|
+
'day7_review_commit',
|
|
69
|
+
7,
|
|
70
|
+
'quest.review.completed',
|
|
71
|
+
'Review week outcomes and commit to the next month.'
|
|
72
|
+
),
|
|
73
|
+
],
|
|
74
74
|
};
|
|
75
75
|
|
|
76
76
|
export const questTracks: LearningJourneyTrackSpec[] = [moneyResetQuestTrack];
|
package/tsconfig.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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 {
|
|
1
|
+
import {
|
|
2
|
+
defineConfig,
|
|
3
|
+
moduleLibrary,
|
|
4
|
+
withDevExports,
|
|
5
|
+
} from '@contractspec/tool.bun';
|
|
2
6
|
|
|
3
7
|
export default defineConfig(() => ({
|
|
4
|
-
|
|
5
|
-
|
|
8
|
+
...moduleLibrary,
|
|
9
|
+
...withDevExports,
|
|
6
10
|
}));
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|