-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.cursorrules
More file actions
164 lines (130 loc) · 5.39 KB
/
.cursorrules
File metadata and controls
164 lines (130 loc) · 5.39 KB
1
2
3
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
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# Experience SDK - Development Guidelines
This project follows a **spec-driven development workflow** inspired by [github/spec-kit](https://github.com/github/spec-kit).
## Development Workflow
### 1. Research Phase (Personal, Gitignored)
- Use `notes/` directory for personal research, brainstorming, and exploration
- Document findings, API comparisons, architecture ideas
- Keep it informal and iterative
- **These files are gitignored** - they're your working space
### 2. Planning Phase (Formal, Committed)
- Create specifications in `specs/phase-X-name/`:
- `spec.md` - Formal specification with goals, scope, user stories
- `plan.md` - Detailed implementation plan with code examples
- `tasks.md` - Breakdown into GitHub-ready issues
- `contracts/` - Type definitions and API contracts
### 3. Issue Creation
- Convert tasks from `tasks.md` into GitHub issues
- Tag with appropriate labels and milestone
- Include acceptance criteria as checklists
### 4. Implementation
- Follow the plan.md implementation order
- Update issue status as work progresses
- Write tests alongside implementation
### 5. Validation
- All acceptance criteria met
- Tests passing (>80% coverage)
- Linter clean
- Documentation updated
## Project Architecture
### Built on @lytics/sdk-kit
This SDK is built on top of `@lytics/sdk-kit`, an open-source plugin framework.
**Core Principle:** Leverage what exists, build what's missing.
#### ✅ Available in sdk-kit (USE THESE)
- **Core:** `SDK`, `Emitter`, `Config`, `Namespace`, `Expose`
- **Plugins:** `storagePlugin`, `contextPlugin`, `queuePlugin`, `transportPlugin`, `consentPlugin`, `pollPlugin`
#### 🔨 Build These (Experience-Specific)
- `frequencyPlugin` - Uses sdk-kit's storage underneath
- `debugPlugin` - Window event emission for Chrome extension
- `bannerPlugin` - DOM rendering for experiences
#### 💡 Design for Contribution
If we build something generic that could benefit other sdk-kit users, design it for potential contribution back to sdk-kit.
## Code Standards
### TypeScript
- Strict mode enabled
- Full type coverage
- Export all public types
- Prefer pure functions for testability
- Extract logic into pure functions when possible
#### Use of `any`
Following sdk-kit's pattern, `any` is intentionally used in **public API surfaces** only:
- **Public API files** (types.ts, runtime.ts): `any` allowed for flexibility
- Config values, event payloads, custom user data
- Provides better developer experience
- **Internal implementation**: Avoid `any`, use specific types
- **Test files**: `any` allowed for mocks/fixtures
- **Biome config**: `noExplicitAny` set to `"warn"` globally, `"off"` for specific files
- This is a conscious trade-off: type safety vs. API flexibility
### Testing
- Unit tests for all functionality
- >80% coverage minimum
- Test both happy path and error cases
- Testability-first: design code to be easily testable
### Plugins
- Follow sdk-kit plugin patterns
- Use `plugin.ns()` for namespacing
- Use `plugin.defaults()` for config
- Use `plugin.expose()` for public API
- Emit events for observability
### Explainability-First
Every decision must include:
- Human-readable reasons (`reasons: string[]`)
- Machine-readable trace (`trace: TraceStep[]`)
- Full context used for evaluation
## Package Structure
```
experience-sdk/
├── notes/ # Personal research (gitignored)
├── specs/ # Formal specifications (committed)
│ └── phase-0-foundation/
│ ├── spec.md # What we're building
│ ├── plan.md # How we're building it
│ ├── tasks.md # GitHub issues breakdown
│ └── contracts/ # Type contracts
├── packages/
│ ├── core/ # @prosdevlab/experience-sdk
│ │ └── src/
│ │ ├── types.ts # All TypeScript types
│ │ ├── runtime.ts # ExperienceRuntime class
│ │ └── index.ts # Exports (singleton + instance)
│ └── plugins/ # @prosdevlab/experience-sdk-plugins
│ └── src/
│ ├── frequency/ # Frequency capping
│ ├── debug/ # Debug/logging
│ └── banner/ # Banner rendering
└── demo/ # Interactive demo site
```
## API Design
### Hybrid Pattern (Singleton + Instance)
Support both simple script tag usage and advanced npm/bundler usage:
```typescript
// Script tag (singleton)
experiences.init({ debug: true });
experiences.register('welcome', { ... });
// npm/bundler (instance)
import { createInstance } from '@prosdevlab/experience-sdk';
const exp = createInstance({ debug: true });
exp.register('welcome', { ... });
```
### Build Outputs
- **ESM** (`dist/index.mjs`) - For npm/bundlers
- **IIFE** (`dist/index.global.js`) - For script tags
- **TypeScript** (`dist/index.d.ts`) - Type definitions
## Git Workflow
### Commits
- Use conventional commits: `feat:`, `fix:`, `docs:`, `chore:`
- Reference issues when applicable
- Keep commits focused and atomic
### Author
- Name: `prosdevlab`
- Email: `prosdevlab@gmail.com`
## Tools
- **Package Manager:** pnpm
- **Monorepo:** Turborepo
- **Bundler:** tsup
- **Testing:** Vitest
- **Linting:** Biome
- **CI/CD:** GitHub Actions
## Questions?
- Review existing specs in `specs/`
- Check sdk-kit documentation: https://github.com/Lytics/sdk-kit
- Refer to implementation plan for detailed guidance