opencodekit 0.8.0 → 0.9.1
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/README.md +35 -43
- package/dist/index.js +16 -4
- package/dist/template/.opencode/AGENTS.md +5 -6
- package/dist/template/.opencode/README.md +24 -25
- package/dist/template/.opencode/agent/build.md +20 -6
- package/dist/template/.opencode/agent/explore.md +18 -18
- package/dist/template/.opencode/agent/planner.md +4 -7
- package/dist/template/.opencode/agent/review.md +1 -2
- package/dist/template/.opencode/agent/rush.md +13 -6
- package/dist/template/.opencode/agent/scout.md +45 -38
- package/dist/template/.opencode/agent/vision.md +16 -24
- package/dist/template/.opencode/command/handoff.md +8 -12
- package/dist/template/.opencode/command/research.md +10 -10
- package/dist/template/.opencode/command/status.md +4 -6
- package/dist/template/.opencode/opencode.json +1 -23
- package/dist/template/.opencode/package.json +1 -1
- package/dist/template/.opencode/plugin/compaction.ts +87 -4
- package/dist/template/.opencode/plugin/skill-mcp.ts +458 -0
- package/dist/template/.opencode/skill/chrome-devtools/SKILL.md +88 -0
- package/dist/template/.opencode/skill/figma/SKILL.md +214 -0
- package/dist/template/.opencode/skill/playwright/SKILL.md +187 -0
- package/dist/template/.opencode/skill/polar/SKILL.md +92 -0
- package/package.json +63 -51
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: figma
|
|
3
|
+
description: Access Figma design data via Framelink MCP. Fetch layout, styles, components from Figma files/frames. Use when implementing UI from Figma designs, extracting design tokens, or downloading assets.
|
|
4
|
+
mcp:
|
|
5
|
+
figma:
|
|
6
|
+
command: npx
|
|
7
|
+
args: ["-y", "figma-developer-mcp", "--stdio"]
|
|
8
|
+
env:
|
|
9
|
+
FIGMA_API_KEY: "${FIGMA_API_KEY}"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Figma Design Data (MCP)
|
|
13
|
+
|
|
14
|
+
Access Figma design data via the Framelink MCP server. When this skill is loaded, the `figma` MCP server auto-starts and exposes tools to fetch design data and download images.
|
|
15
|
+
|
|
16
|
+
## Prerequisites
|
|
17
|
+
|
|
18
|
+
Set your Figma API key as an environment variable:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
export FIGMA_API_KEY="your-figma-personal-access-token"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
To create a Figma Personal Access Token:
|
|
25
|
+
|
|
26
|
+
1. Go to Figma → Settings → Account → Personal access tokens
|
|
27
|
+
2. Create a new token with read access
|
|
28
|
+
3. See: https://help.figma.com/hc/en-us/articles/8085703771159-Manage-personal-access-tokens
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
After loading this skill, use `skill_mcp` to invoke Figma tools:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
skill_mcp(skill_name="figma", tool_name="get_figma_data", arguments='{"fileKey": "abc123", "nodeId": "1234:5678"}')
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Available Tools
|
|
39
|
+
|
|
40
|
+
### get_figma_data
|
|
41
|
+
|
|
42
|
+
Fetch comprehensive Figma file data including layout, content, visuals, and component information.
|
|
43
|
+
|
|
44
|
+
| Parameter | Type | Required | Description |
|
|
45
|
+
| --------- | ------ | -------- | ------------------------------------------------------------------------------------------------- |
|
|
46
|
+
| `fileKey` | string | Yes | The Figma file key (from URL: `figma.com/file/<fileKey>/...` or `figma.com/design/<fileKey>/...`) |
|
|
47
|
+
| `nodeId` | string | No | Specific node ID (from URL param `node-id=<nodeId>`). Format: `1234:5678` or `1234-5678` |
|
|
48
|
+
| `depth` | number | No | Levels deep to traverse. Only use if explicitly requested by user. |
|
|
49
|
+
|
|
50
|
+
**Returns:** YAML-formatted design data with:
|
|
51
|
+
|
|
52
|
+
- `metadata` - File/node information
|
|
53
|
+
- `nodes` - Simplified node tree with layout, styles, text content
|
|
54
|
+
- `globalVars` - Shared styles and variables
|
|
55
|
+
|
|
56
|
+
### download_figma_images
|
|
57
|
+
|
|
58
|
+
Download SVG and PNG images/icons from a Figma file.
|
|
59
|
+
|
|
60
|
+
| Parameter | Type | Required | Description |
|
|
61
|
+
| ----------- | ------ | -------- | --------------------------------------------- |
|
|
62
|
+
| `fileKey` | string | Yes | The Figma file key |
|
|
63
|
+
| `nodes` | array | Yes | Array of node objects to download (see below) |
|
|
64
|
+
| `localPath` | string | Yes | Absolute path to save images |
|
|
65
|
+
| `pngScale` | number | No | Export scale for PNGs (default: 2) |
|
|
66
|
+
|
|
67
|
+
**Node object structure:**
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"nodeId": "1234:5678",
|
|
72
|
+
"fileName": "icon-name.svg",
|
|
73
|
+
"imageRef": "optional-for-image-fills"
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Workflow
|
|
78
|
+
|
|
79
|
+
### 1. Extract File Key and Node ID from Figma URL
|
|
80
|
+
|
|
81
|
+
Figma URLs follow these patterns:
|
|
82
|
+
|
|
83
|
+
- `https://www.figma.com/file/<fileKey>/<fileName>?node-id=<nodeId>`
|
|
84
|
+
- `https://www.figma.com/design/<fileKey>/<fileName>?node-id=<nodeId>`
|
|
85
|
+
|
|
86
|
+
Example: `https://www.figma.com/design/abc123xyz/MyDesign?node-id=1234-5678`
|
|
87
|
+
|
|
88
|
+
- `fileKey`: `abc123xyz`
|
|
89
|
+
- `nodeId`: `1234-5678` (or `1234:5678` - both formats work)
|
|
90
|
+
|
|
91
|
+
### 2. Fetch Design Data
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
# Fetch specific frame/component
|
|
95
|
+
skill_mcp(skill_name="figma", tool_name="get_figma_data", arguments='{"fileKey": "abc123xyz", "nodeId": "1234:5678"}')
|
|
96
|
+
|
|
97
|
+
# Fetch entire file (use sparingly - can be large)
|
|
98
|
+
skill_mcp(skill_name="figma", tool_name="get_figma_data", arguments='{"fileKey": "abc123xyz"}')
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 3. Download Assets (Optional)
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
skill_mcp(skill_name="figma", tool_name="download_figma_images", arguments='{
|
|
105
|
+
"fileKey": "abc123xyz",
|
|
106
|
+
"nodes": [
|
|
107
|
+
{"nodeId": "1234:5678", "fileName": "hero-image.png"},
|
|
108
|
+
{"nodeId": "5678:9012", "fileName": "icon-arrow.svg"}
|
|
109
|
+
],
|
|
110
|
+
"localPath": "/absolute/path/to/assets"
|
|
111
|
+
}')
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Examples
|
|
115
|
+
|
|
116
|
+
### Implement a Component from Figma
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
# User provides: https://www.figma.com/design/abc123/Dashboard?node-id=100-200
|
|
120
|
+
|
|
121
|
+
# 1. Fetch the design data
|
|
122
|
+
skill_mcp(skill_name="figma", tool_name="get_figma_data", arguments='{"fileKey": "abc123", "nodeId": "100-200"}')
|
|
123
|
+
|
|
124
|
+
# 2. Review the returned YAML for:
|
|
125
|
+
# - Layout structure (flex, grid, spacing)
|
|
126
|
+
# - Typography (font, size, weight, line-height)
|
|
127
|
+
# - Colors (fills, strokes)
|
|
128
|
+
# - Dimensions and constraints
|
|
129
|
+
|
|
130
|
+
# 3. Implement the component using the extracted data
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Extract Design Tokens
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
# Fetch a design system file
|
|
137
|
+
skill_mcp(skill_name="figma", tool_name="get_figma_data", arguments='{"fileKey": "designSystemKey"}')
|
|
138
|
+
|
|
139
|
+
# The globalVars section contains:
|
|
140
|
+
# - Color styles
|
|
141
|
+
# - Typography styles
|
|
142
|
+
# - Effect styles (shadows, blurs)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Download Icons
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
skill_mcp(skill_name="figma", tool_name="download_figma_images", arguments='{
|
|
149
|
+
"fileKey": "iconLibraryKey",
|
|
150
|
+
"nodes": [
|
|
151
|
+
{"nodeId": "10:20", "fileName": "icon-home.svg"},
|
|
152
|
+
{"nodeId": "10:30", "fileName": "icon-settings.svg"},
|
|
153
|
+
{"nodeId": "10:40", "fileName": "icon-user.svg"}
|
|
154
|
+
],
|
|
155
|
+
"localPath": "/project/src/assets/icons",
|
|
156
|
+
"pngScale": 2
|
|
157
|
+
}')
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Data Structure
|
|
161
|
+
|
|
162
|
+
The `get_figma_data` tool returns simplified, AI-optimized data:
|
|
163
|
+
|
|
164
|
+
```yaml
|
|
165
|
+
metadata:
|
|
166
|
+
name: "Component Name"
|
|
167
|
+
lastModified: "2024-01-15T..."
|
|
168
|
+
|
|
169
|
+
nodes:
|
|
170
|
+
- id: "1234:5678"
|
|
171
|
+
name: "Button"
|
|
172
|
+
type: "FRAME"
|
|
173
|
+
layout:
|
|
174
|
+
mode: "HORIZONTAL"
|
|
175
|
+
padding: { top: 12, right: 24, bottom: 12, left: 24 }
|
|
176
|
+
gap: 8
|
|
177
|
+
size: { width: 120, height: 48 }
|
|
178
|
+
fills:
|
|
179
|
+
- type: "SOLID"
|
|
180
|
+
color: { r: 0.2, g: 0.4, b: 1, a: 1 }
|
|
181
|
+
cornerRadius: 8
|
|
182
|
+
children:
|
|
183
|
+
- id: "1234:5679"
|
|
184
|
+
name: "Label"
|
|
185
|
+
type: "TEXT"
|
|
186
|
+
content: "Click me"
|
|
187
|
+
textStyle:
|
|
188
|
+
fontFamily: "Inter"
|
|
189
|
+
fontSize: 16
|
|
190
|
+
fontWeight: 600
|
|
191
|
+
|
|
192
|
+
globalVars:
|
|
193
|
+
styles:
|
|
194
|
+
"S:abc123": { name: "Primary", fills: [...] }
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Tips
|
|
198
|
+
|
|
199
|
+
- **Always use nodeId** when provided - fetching entire files is slow and context-heavy
|
|
200
|
+
- **Node IDs with `-` or `:`** both work - the MCP handles conversion
|
|
201
|
+
- **Check globalVars** for reusable styles before hardcoding values
|
|
202
|
+
- **Use depth parameter sparingly** - only when explicitly needed
|
|
203
|
+
- **For images/icons**, identify nodes with `imageRef` in the data for proper downloading
|
|
204
|
+
- **SVG vs PNG**: Use `.svg` for icons/vectors, `.png` for photos/complex images
|
|
205
|
+
|
|
206
|
+
## Troubleshooting
|
|
207
|
+
|
|
208
|
+
**"Invalid API key"**: Ensure `FIGMA_API_KEY` environment variable is set correctly.
|
|
209
|
+
|
|
210
|
+
**"File not found"**: Verify the fileKey is correct and you have access to the file.
|
|
211
|
+
|
|
212
|
+
**"Node not found"**: Check the nodeId format. Try both `1234:5678` and `1234-5678`.
|
|
213
|
+
|
|
214
|
+
**Large response**: Use `nodeId` to fetch specific frames instead of entire files.
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: playwright
|
|
3
|
+
description: Browser automation with Playwright MCP. Test pages, fill forms, take screenshots, check responsive design, validate UX, test login flows. Use when user wants to test websites or automate browser interactions.
|
|
4
|
+
mcp:
|
|
5
|
+
playwright:
|
|
6
|
+
command: npx
|
|
7
|
+
args: ["@playwright/mcp@latest"]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Playwright Browser Automation (MCP)
|
|
11
|
+
|
|
12
|
+
Browser automation via Playwright MCP server. When this skill is loaded, the `playwright` MCP server auto-starts and exposes browser tools.
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
After loading this skill, use `skill_mcp` to invoke browser tools:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_navigate", arguments='{"url": "https://example.com"}')
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Available Tools
|
|
23
|
+
|
|
24
|
+
### Navigation & Page
|
|
25
|
+
|
|
26
|
+
| Tool | Description | Arguments |
|
|
27
|
+
| -------------------- | ---------------------- | ----------------------------------- |
|
|
28
|
+
| `browser_navigate` | Navigate to URL | `{"url": "https://..."}` |
|
|
29
|
+
| `browser_go_back` | Go back | `{}` |
|
|
30
|
+
| `browser_go_forward` | Go forward | `{}` |
|
|
31
|
+
| `browser_wait_for` | Wait for text/selector | `{"text": "...", "timeout": 10000}` |
|
|
32
|
+
|
|
33
|
+
### Interaction
|
|
34
|
+
|
|
35
|
+
| Tool | Description | Arguments |
|
|
36
|
+
| ----------------------- | ------------------------- | ---------------------------------------------------------------------------------- |
|
|
37
|
+
| `browser_click` | Click element | `{"element": "Submit button", "ref": "e123"}` |
|
|
38
|
+
| `browser_type` | Type text | `{"element": "Search input", "ref": "e456", "text": "query"}` |
|
|
39
|
+
| `browser_fill` | Fill input (clears first) | `{"element": "Email field", "ref": "e789", "text": "test@example.com"}` |
|
|
40
|
+
| `browser_select_option` | Select dropdown option | `{"element": "Country", "ref": "e012", "values": ["US"]}` |
|
|
41
|
+
| `browser_hover` | Hover over element | `{"element": "Menu", "ref": "e345"}` |
|
|
42
|
+
| `browser_drag` | Drag and drop | `{"startElement": "...", "startRef": "...", "endElement": "...", "endRef": "..."}` |
|
|
43
|
+
|
|
44
|
+
### Screenshots & Content
|
|
45
|
+
|
|
46
|
+
| Tool | Description | Arguments |
|
|
47
|
+
| ------------------------- | ------------------------------- | -------------------------------------- |
|
|
48
|
+
| `browser_take_screenshot` | Capture screenshot | `{"filename": "screenshot.png"}` |
|
|
49
|
+
| `browser_snapshot` | Get page accessibility snapshot | `{}` |
|
|
50
|
+
| `browser_evaluate` | Run JavaScript | `{"function": "() => document.title"}` |
|
|
51
|
+
| `browser_pdf_save` | Save page as PDF | `{"filename": "page.pdf"}` |
|
|
52
|
+
|
|
53
|
+
### Viewport & Device
|
|
54
|
+
|
|
55
|
+
| Tool | Description | Arguments |
|
|
56
|
+
| ---------------- | --------------- | ------------------------------------------------------------ |
|
|
57
|
+
| `browser_resize` | Resize viewport | `{"width": 375, "height": 667}` or `{"device": "iPhone 13"}` |
|
|
58
|
+
|
|
59
|
+
### Tabs
|
|
60
|
+
|
|
61
|
+
| Tool | Description | Arguments |
|
|
62
|
+
| -------------------- | -------------- | ------------------------ |
|
|
63
|
+
| `browser_tab_list` | List open tabs | `{}` |
|
|
64
|
+
| `browser_tab_new` | Open new tab | `{"url": "https://..."}` |
|
|
65
|
+
| `browser_tab_select` | Switch to tab | `{"index": 0}` |
|
|
66
|
+
| `browser_tab_close` | Close tab | `{"index": 0}` |
|
|
67
|
+
|
|
68
|
+
## Workflow
|
|
69
|
+
|
|
70
|
+
1. **Navigate** to the target URL
|
|
71
|
+
2. **Snapshot** to see page structure and element refs
|
|
72
|
+
3. **Interact** using element refs from snapshot
|
|
73
|
+
4. **Screenshot** to capture results
|
|
74
|
+
|
|
75
|
+
## Examples
|
|
76
|
+
|
|
77
|
+
### Test a Page
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
# Navigate
|
|
81
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_navigate", arguments='{"url": "http://localhost:3000"}')
|
|
82
|
+
|
|
83
|
+
# Get page snapshot (shows elements with refs)
|
|
84
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_snapshot")
|
|
85
|
+
|
|
86
|
+
# Take screenshot
|
|
87
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_take_screenshot", arguments='{"filename": "/tmp/homepage.png"}')
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Fill a Form
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
# Navigate to form
|
|
94
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_navigate", arguments='{"url": "http://localhost:3000/contact"}')
|
|
95
|
+
|
|
96
|
+
# Get snapshot to find element refs
|
|
97
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_snapshot")
|
|
98
|
+
|
|
99
|
+
# Fill fields (use refs from snapshot)
|
|
100
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_fill", arguments='{"element": "Name input", "ref": "e12", "text": "John Doe"}')
|
|
101
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_fill", arguments='{"element": "Email input", "ref": "e34", "text": "john@example.com"}')
|
|
102
|
+
|
|
103
|
+
# Submit
|
|
104
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_click", arguments='{"element": "Submit button", "ref": "e56"}')
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Test Responsive Design
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
# Navigate
|
|
111
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_navigate", arguments='{"url": "http://localhost:3000"}')
|
|
112
|
+
|
|
113
|
+
# Desktop
|
|
114
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_resize", arguments='{"width": 1920, "height": 1080}')
|
|
115
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_take_screenshot", arguments='{"filename": "/tmp/desktop.png"}')
|
|
116
|
+
|
|
117
|
+
# Tablet
|
|
118
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_resize", arguments='{"device": "iPad Pro 11"}')
|
|
119
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_take_screenshot", arguments='{"filename": "/tmp/tablet.png"}')
|
|
120
|
+
|
|
121
|
+
# Mobile
|
|
122
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_resize", arguments='{"device": "iPhone 13"}')
|
|
123
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_take_screenshot", arguments='{"filename": "/tmp/mobile.png"}')
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Test Login Flow
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
# Navigate to login
|
|
130
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_navigate", arguments='{"url": "http://localhost:3000/login"}')
|
|
131
|
+
|
|
132
|
+
# Snapshot to get refs
|
|
133
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_snapshot")
|
|
134
|
+
|
|
135
|
+
# Fill credentials
|
|
136
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_fill", arguments='{"element": "Email", "ref": "e10", "text": "test@example.com"}')
|
|
137
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_fill", arguments='{"element": "Password", "ref": "e20", "text": "password123"}')
|
|
138
|
+
|
|
139
|
+
# Click login
|
|
140
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_click", arguments='{"element": "Login button", "ref": "e30"}')
|
|
141
|
+
|
|
142
|
+
# Wait for redirect
|
|
143
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_wait_for", arguments='{"text": "Dashboard", "timeout": 10000}')
|
|
144
|
+
|
|
145
|
+
# Screenshot success
|
|
146
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_take_screenshot", arguments='{"filename": "/tmp/logged-in.png"}')
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Run JavaScript
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
# Get page title
|
|
153
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_evaluate", arguments='{"function": "() => document.title"}')
|
|
154
|
+
|
|
155
|
+
# Get all links
|
|
156
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_evaluate", arguments='{"function": "() => Array.from(document.querySelectorAll(\"a\")).map(a => a.href)"}')
|
|
157
|
+
|
|
158
|
+
# Scroll to bottom
|
|
159
|
+
skill_mcp(mcp_name="playwright", tool_name="browser_evaluate", arguments='{"function": "() => window.scrollTo(0, document.body.scrollHeight)"}')
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Server Options
|
|
163
|
+
|
|
164
|
+
For advanced usage, modify the MCP args in frontmatter:
|
|
165
|
+
|
|
166
|
+
```yaml
|
|
167
|
+
mcp:
|
|
168
|
+
playwright:
|
|
169
|
+
command: npx
|
|
170
|
+
args: ["@playwright/mcp@latest", "--headless", "--browser=firefox"]
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Common options:
|
|
174
|
+
|
|
175
|
+
- `--headless` - Run without visible browser
|
|
176
|
+
- `--browser=chrome|firefox|webkit` - Choose browser
|
|
177
|
+
- `--device="iPhone 13"` - Emulate device
|
|
178
|
+
- `--viewport-size=1280x720` - Set viewport
|
|
179
|
+
- `--user-data-dir=/path` - Persist browser data
|
|
180
|
+
|
|
181
|
+
## Tips
|
|
182
|
+
|
|
183
|
+
- **Always snapshot first** to get element refs before interacting
|
|
184
|
+
- **Use descriptive element names** in click/fill for clarity
|
|
185
|
+
- **Save screenshots to /tmp** for easy access
|
|
186
|
+
- **Use device presets** for accurate mobile emulation
|
|
187
|
+
- **Chain wait_for** after navigation for dynamic pages
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: polar
|
|
3
|
+
description: Polar payment platform integration for monetization, subscriptions, and license keys. Use when implementing checkout, managing products, or building customer portals.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Polar Integration
|
|
7
|
+
|
|
8
|
+
Polar is a merchant-of-record platform for digital products, subscriptions, and license keys.
|
|
9
|
+
|
|
10
|
+
## What I Do
|
|
11
|
+
|
|
12
|
+
- Guide implementation of Polar checkout and payments
|
|
13
|
+
- Help with subscription management and billing
|
|
14
|
+
- Assist with license key validation
|
|
15
|
+
- Set up webhook handlers for payment events
|
|
16
|
+
|
|
17
|
+
## When to Use Me
|
|
18
|
+
|
|
19
|
+
- Implementing checkout flow for a product
|
|
20
|
+
- Adding subscription billing to an app
|
|
21
|
+
- Setting up license key validation
|
|
22
|
+
- Building a customer portal
|
|
23
|
+
- Handling payment webhooks
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install @polar-sh/sdk
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { Polar } from "@polar-sh/sdk";
|
|
33
|
+
|
|
34
|
+
const polar = new Polar({
|
|
35
|
+
accessToken: process.env.POLAR_ACCESS_TOKEN!,
|
|
36
|
+
server: "production", // or "sandbox"
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Key APIs
|
|
41
|
+
|
|
42
|
+
| API | Purpose |
|
|
43
|
+
| ----------------------- | --------------------------------- |
|
|
44
|
+
| `polar.products.*` | Create/manage products and prices |
|
|
45
|
+
| `polar.checkouts.*` | Create checkout sessions |
|
|
46
|
+
| `polar.subscriptions.*` | Manage subscriptions |
|
|
47
|
+
| `polar.orders.*` | View order history |
|
|
48
|
+
| `polar.customers.*` | Customer management |
|
|
49
|
+
| `polar.licenseKeys.*` | Issue and validate licenses |
|
|
50
|
+
|
|
51
|
+
## Environment Variables
|
|
52
|
+
|
|
53
|
+
| Variable | Description |
|
|
54
|
+
| ---------------------- | ------------------------------- |
|
|
55
|
+
| `POLAR_ACCESS_TOKEN` | Organization Access Token (OAT) |
|
|
56
|
+
| `POLAR_WEBHOOK_SECRET` | Webhook signing secret |
|
|
57
|
+
|
|
58
|
+
## Common Patterns
|
|
59
|
+
|
|
60
|
+
### Create Checkout
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
const checkout = await polar.checkouts.create({
|
|
64
|
+
productId: "prod_xxx",
|
|
65
|
+
successUrl: "https://myapp.com/success",
|
|
66
|
+
});
|
|
67
|
+
// Redirect to checkout.url
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Validate License Key
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
const result = await polar.licenseKeys.validate({
|
|
74
|
+
key: "XXXX-XXXX-XXXX-XXXX",
|
|
75
|
+
organizationId: "org_xxx",
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Handle Webhook
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { validateEvent } from "@polar-sh/sdk/webhooks";
|
|
83
|
+
|
|
84
|
+
const event = validateEvent(body, signature, process.env.POLAR_WEBHOOK_SECRET!);
|
|
85
|
+
// event.type: "subscription.created", "order.created", etc.
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Links
|
|
89
|
+
|
|
90
|
+
- [Dashboard](https://polar.sh)
|
|
91
|
+
- [API Docs](https://docs.polar.sh/api-reference)
|
|
92
|
+
- [SDK](https://www.npmjs.com/package/@polar-sh/sdk)
|
package/package.json
CHANGED
|
@@ -1,53 +1,65 @@
|
|
|
1
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
|
-
|
|
2
|
+
"name": "opencodekit",
|
|
3
|
+
"version": "0.9.1",
|
|
4
|
+
"description": "CLI tool for bootstrapping and managing OpenCodeKit projects",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/opencodekit/opencodekit-template.git"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public",
|
|
12
|
+
"registry": "https://registry.npmjs.org"
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"ock": "dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"dev": "bun run src/index.ts",
|
|
23
|
+
"build": "bun build src/index.ts --outdir dist --target node && mkdir -p dist/template && rsync -av --exclude=node_modules --exclude=dist --exclude=.git --exclude=coverage --exclude=.next --exclude=.turbo --exclude=logs --exclude=package-lock.json .opencode/ dist/template/.opencode/",
|
|
24
|
+
"compile": "bun build src/index.ts --compile --outfile ock",
|
|
25
|
+
"compile:binary": "bun build src/index.ts --compile --outfile bin/ock",
|
|
26
|
+
"typecheck": "tsc --noEmit",
|
|
27
|
+
"test": "bun test",
|
|
28
|
+
"test:watch": "bun test --watch",
|
|
29
|
+
"lint": "biome check .",
|
|
30
|
+
"lint:fix": "biome check --fix ."
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"cli",
|
|
34
|
+
"opencodekit",
|
|
35
|
+
"template",
|
|
36
|
+
"agents",
|
|
37
|
+
"mcp",
|
|
38
|
+
"opencode"
|
|
39
|
+
],
|
|
40
|
+
"author": "OpenCodeKit",
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"engines": {
|
|
43
|
+
"bun": ">=1.3.2"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@clack/prompts": "^0.7.0",
|
|
47
|
+
"@opencode-ai/plugin": "^1.0.141",
|
|
48
|
+
"beads-village": "^1.3.3",
|
|
49
|
+
"cac": "^6.7.14",
|
|
50
|
+
"cli-table3": "^0.6.5",
|
|
51
|
+
"ora": "^9.0.0",
|
|
52
|
+
"picocolors": "^1.1.1",
|
|
53
|
+
"zod": "^3.23.8"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@beads/bd": "^0.29.0",
|
|
57
|
+
"@biomejs/biome": "^1.9.4",
|
|
58
|
+
"@types/bun": "latest",
|
|
59
|
+
"@types/node": "^22.10.1",
|
|
60
|
+
"typescript": "^5.7.2"
|
|
61
|
+
},
|
|
62
|
+
"trustedDependencies": [
|
|
63
|
+
"@beads/bd"
|
|
64
|
+
]
|
|
53
65
|
}
|