feedback-kit-skills 0.1.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.
- package/README.md +323 -0
- package/package.json +47 -0
- package/skills/setup/README.md +19 -0
- package/skills/setup/setup-ios-sdk/SKILL.md +210 -0
- package/skills/setup/setup-macos-sdk/SKILL.md +159 -0
- package/skills/setup/setup-mcp-server/SKILL.md +122 -0
- package/skills/setup/setup-watchos-sdk/SKILL.md +136 -0
package/README.md
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
# FeedbackKit
|
|
2
|
+
|
|
3
|
+
[](https://github.com/tianhaoz95/feedback-kit/actions/workflows/testflight.yml)
|
|
4
|
+
[](https://github.com/tianhaoz95/feedback-kit/actions/workflows/release-macos-demo.yml)
|
|
5
|
+
[](https://github.com/tianhaoz95/feedback-kit/actions/workflows/publish-cli.yml)
|
|
6
|
+
[](https://github.com/tianhaoz95/feedback-kit/actions/workflows/publish-skills.yml)
|
|
7
|
+
[](https://github.com/tianhaoz95/feedback-kit/actions/workflows/deploy-web.yml)
|
|
8
|
+
|
|
9
|
+
An iOS + macOS + watchOS SDK for capturing in-app user feedback (screenshot +
|
|
10
|
+
annotations + description + device/app/screen info on iOS/macOS; text +
|
|
11
|
+
context only on watchOS), plus an optional Supabase-backed dashboard for
|
|
12
|
+
collecting it and turning it into prompts for a coding agent.
|
|
13
|
+
|
|
14
|
+
See [DESIGN.md](DESIGN.md) for how it's put together and why.
|
|
15
|
+
|
|
16
|
+
## Quickstart
|
|
17
|
+
|
|
18
|
+
Prerequisites: Xcode, Homebrew, Node.js — all standard on a dev Mac. The one
|
|
19
|
+
thing you may need to install yourself is **Docker Desktop**
|
|
20
|
+
(https://www.docker.com/products/docker-desktop/), needed only for running
|
|
21
|
+
Supabase locally.
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
./scripts/setup.sh # installs xcodegen + Supabase CLI, npm install for web/
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Run the iOS demo app
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
./scripts/run-ios.sh
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Builds and launches `DemoApp` (a small sample app with FeedbackKit wired up —
|
|
34
|
+
shake-to-report, a floating trigger button, and manual "Report a Problem"
|
|
35
|
+
buttons on both a SwiftUI and a UIKit screen) in the iOS Simulator.
|
|
36
|
+
|
|
37
|
+
### Run the macOS demo app
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
./scripts/run-macos.sh
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Builds and launches natively — no simulator needed. Exercises the floating
|
|
44
|
+
trigger button, a Help-menu "Report a Problem…" item (⌘⇧R, the menu-item
|
|
45
|
+
trigger style the SDK's docs show), and manual "Report a Problem" buttons on
|
|
46
|
+
a sidebar Home/Cart pair sharing the same `CartStore` the iOS demo uses.
|
|
47
|
+
`FeedbackKit.present(from: window)` and `FeedbackKit.showFloatingTriggerButton { ... }`
|
|
48
|
+
are the macOS equivalents of the iOS calls above, minus a shake trigger (no
|
|
49
|
+
motion sensor on a Mac).
|
|
50
|
+
|
|
51
|
+
You can also build/test just the SDK itself, without the demo app:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
swift build
|
|
55
|
+
swift test
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Run the watchOS demo app
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
./scripts/run-watchos.sh
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
A standalone watch app (no iOS companion needed) built and launched on a
|
|
65
|
+
watch simulator. watchOS is a deliberately stripped-down flow — no
|
|
66
|
+
screenshot, no annotation tools, just a text description plus device/app
|
|
67
|
+
context — via `FeedbackQuickNoteView`, a plain SwiftUI view embedded in a
|
|
68
|
+
`.sheet`. See [DESIGN.md](DESIGN.md) for why.
|
|
69
|
+
|
|
70
|
+
To test just the SDK itself on a watch simulator instead:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Find a watch simulator id: xcrun simctl list devices available
|
|
74
|
+
xcodebuild test -scheme FeedbackKit -destination 'id=<WATCH_SIMULATOR_UDID>'
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Run the web dashboard
|
|
78
|
+
|
|
79
|
+
Needs Docker Desktop running first (see above).
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
./scripts/start-web.sh
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Starts a local Supabase stack (Postgres, Auth, Storage, Edge Functions —
|
|
86
|
+
with this project's schema and the `ingest-feedback` function already
|
|
87
|
+
applied), points the dashboard at it, and starts it at http://localhost:3000.
|
|
88
|
+
Supabase Studio (to poke at the database/storage directly) is at
|
|
89
|
+
http://127.0.0.1:54323.
|
|
90
|
+
|
|
91
|
+
Sign up on the dashboard, create a project, and copy the Swift snippet shown
|
|
92
|
+
on the project page into `DemoApp/DemoApp/FeedbackKitDemoApp.swift` (it's
|
|
93
|
+
already there, commented out) to see feedback submitted from the simulator
|
|
94
|
+
show up live.
|
|
95
|
+
|
|
96
|
+
### Use the CLI / MCP server
|
|
97
|
+
|
|
98
|
+
Install globally from npm (or run directly with `npx feedbackkit-cli`):
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npm install -g feedbackkit-cli
|
|
102
|
+
feedbackkit login # sign in via browser
|
|
103
|
+
feedbackkit list
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Or connect it to your local dev stack:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
feedbackkit login --dashboard-url http://localhost:3000
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Lets a coding agent fetch a feedback report's generated prompt directly
|
|
113
|
+
(`feedbackkit mcp`) instead of a human copying it out of the dashboard —
|
|
114
|
+
see [cli/README.md](cli/README.md) for the full command/tool list and how
|
|
115
|
+
its browser-based login works.
|
|
116
|
+
|
|
117
|
+
### Agent Skills
|
|
118
|
+
|
|
119
|
+
FeedbackKit provides a catalog of [Agent Skills](https://github.com/vercel-labs/skills) compatible with
|
|
120
|
+
Claude Code, Cursor, Antigravity, Gemini CLI, and other AI coding assistants to automate SDK setup and MCP integration.
|
|
121
|
+
|
|
122
|
+
## Skills Catalog
|
|
123
|
+
|
|
124
|
+
| Category | Skill | Description |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| [`setup/`](skills/setup/README.md) | [`setup-ios-sdk`](skills/setup/setup-ios-sdk/SKILL.md) | Integrate FeedbackKit SDK into an iOS project (SwiftUI or UIKit). |
|
|
127
|
+
| [`setup/`](skills/setup/README.md) | [`setup-macos-sdk`](skills/setup/setup-macos-sdk/SKILL.md) | Integrate FeedbackKit SDK into a macOS desktop app (SwiftUI or AppKit). |
|
|
128
|
+
| [`setup/`](skills/setup/README.md) | [`setup-watchos-sdk`](skills/setup/setup-watchos-sdk/SKILL.md) | Integrate FeedbackKit SDK into a watchOS app using FeedbackQuickNoteView. |
|
|
129
|
+
| [`setup/`](skills/setup/README.md) | [`setup-mcp-server`](skills/setup/setup-mcp-server/SKILL.md) | Configure FeedbackKit CLI and MCP server for AI coding agents. |
|
|
130
|
+
|
|
131
|
+
#### Layout
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
skills/
|
|
135
|
+
<category>/
|
|
136
|
+
<skill-name>/
|
|
137
|
+
SKILL.md # required: frontmatter (name, description) + agent instructions
|
|
138
|
+
templates/ # optional: code/config template files (.template)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### Commands
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
npm run new # Interactively scaffold a new skill with @clack/prompts
|
|
145
|
+
npm run validate # Validate all SKILL.md frontmatter
|
|
146
|
+
npm run list # List all discoverable skills via npx skills
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
You can also pass arguments directly to scaffold non-interactively:
|
|
150
|
+
```bash
|
|
151
|
+
npm run new -- <category>/<skill-name> "one-line description"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
#### Installing into an Agent
|
|
155
|
+
|
|
156
|
+
From within your agent CLI or another project's working directory, install using the dedicated npm package name:
|
|
157
|
+
```bash
|
|
158
|
+
npx skills add feedback-kit-skills
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
To install a specific skill directly:
|
|
162
|
+
```bash
|
|
163
|
+
npx skills add feedback-kit-skills --skill setup-ios-sdk --yes
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
You can also install directly using the GitHub repository shorthand:
|
|
167
|
+
```bash
|
|
168
|
+
npx skills add tianhaoz95/feedback-kit --skill setup-ios-sdk --yes
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Deploying the web dashboard to GitHub Pages
|
|
172
|
+
|
|
173
|
+
`.github/workflows/deploy-web.yml` builds `web/` and deploys it to GitHub
|
|
174
|
+
Pages via GitHub Actions (`actions/deploy-pages` — no `gh-pages` branch)
|
|
175
|
+
on every push to `main` that touches `web/`. One-time setup:
|
|
176
|
+
|
|
177
|
+
1. **Settings → Pages → Source: "GitHub Actions"** on the repo (not "Deploy
|
|
178
|
+
from a branch").
|
|
179
|
+
2. **Settings → Secrets and variables → Actions → Variables**, add:
|
|
180
|
+
- `VITE_SUPABASE_URL`
|
|
181
|
+
- `VITE_SUPABASE_ANON_KEY`
|
|
182
|
+
|
|
183
|
+
These are the anon/publishable key and project URL — safe to expose in a
|
|
184
|
+
client bundle, so repo **variables** (not secrets) are the right place for
|
|
185
|
+
them, same as `web/.env.local`.
|
|
186
|
+
|
|
187
|
+
The workflow assumes the site is served from `https://<user>.github.io/feedback-kit/`
|
|
188
|
+
(a project page, not a `<user>.github.io` user/org page) — see the `base` in
|
|
189
|
+
`web/vite.config.ts` and `basename` in `web/src/main.tsx` if that ever
|
|
190
|
+
changes. It also copies `dist/index.html` to `dist/404.html` after building
|
|
191
|
+
so direct loads/refreshes of deep links (e.g. `/projects/abc`) still resolve
|
|
192
|
+
client-side, since GitHub Pages has no server-side rewrites.
|
|
193
|
+
|
|
194
|
+
## Deploying Supabase (migrations + edge functions)
|
|
195
|
+
|
|
196
|
+
**Migrations** deploy automatically via Supabase's own native GitHub
|
|
197
|
+
integration (Dashboard → Project Settings → Integrations → GitHub), not a
|
|
198
|
+
custom Actions workflow — it applies `supabase/migrations/` to the
|
|
199
|
+
production database whenever `main` changes. This is deliberately preferred
|
|
200
|
+
over a custom workflow: it's a GitHub App connection Supabase manages and
|
|
201
|
+
scopes to this repo/project itself, so no Postgres password or access token
|
|
202
|
+
needs to live in this repo's GitHub Secrets at all. One-time setup, on that
|
|
203
|
+
integration page:
|
|
204
|
+
|
|
205
|
+
- GitHub repository: this repo
|
|
206
|
+
- Working directory: `.` (repo root, since `supabase/` lives directly there)
|
|
207
|
+
- Deploy to production: on, with production branch `main`
|
|
208
|
+
|
|
209
|
+
**Edge Functions** (`ingest-feedback`, plus `create-checkout-session` /
|
|
210
|
+
`create-portal-session` / `stripe-webhook` for billing — see below) are
|
|
211
|
+
deployed manually:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
supabase login # once per machine — interactive browser OAuth
|
|
215
|
+
./scripts/deploy-functions.sh # deploy every function
|
|
216
|
+
./scripts/deploy-functions.sh ingest-feedback # or just one
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
This isn't automated because, unlike the database sync above, there's no
|
|
220
|
+
project-scoped credential for it — `supabase functions deploy` needs a
|
|
221
|
+
Supabase personal access token, which grants Management API access to
|
|
222
|
+
every project on the account, not just this one. Not worth storing an
|
|
223
|
+
account-wide secret in CI for a function that changes rarely.
|
|
224
|
+
|
|
225
|
+
### Turning on real billing
|
|
226
|
+
|
|
227
|
+
FeedbackKit is free today — every organization is permanently on the free
|
|
228
|
+
plan (`organization_billing`, `supabase/migrations/0009_billing.sql`) until
|
|
229
|
+
a real Stripe account exists. The dashboard's Billing page and the three
|
|
230
|
+
billing Edge Functions are already built and deployed; they just detect the
|
|
231
|
+
missing Stripe credentials and say so (`{"error": "billing_not_configured"}`)
|
|
232
|
+
instead of doing anything. To make it real:
|
|
233
|
+
|
|
234
|
+
1. Create the Stripe product/price for the paid plan, and a webhook
|
|
235
|
+
endpoint pointed at
|
|
236
|
+
`https://<project-ref>.supabase.co/functions/v1/stripe-webhook`
|
|
237
|
+
subscribed to at least `checkout.session.completed`,
|
|
238
|
+
`customer.subscription.updated`, and `customer.subscription.deleted`.
|
|
239
|
+
2. Set the secrets the functions read (`supabase/functions/_shared/stripe.ts`):
|
|
240
|
+
```bash
|
|
241
|
+
supabase secrets set STRIPE_SECRET_KEY=sk_live_... STRIPE_WEBHOOK_SECRET=whsec_... STRIPE_PRICE_ID_PRO=price_...
|
|
242
|
+
```
|
|
243
|
+
3. Nothing else — no schema change, no dashboard code change. The next
|
|
244
|
+
request to any billing function picks up the new secrets immediately.
|
|
245
|
+
|
|
246
|
+
**Auth/MFA/pooler/storage config** (`supabase config push`) isn't automated
|
|
247
|
+
either, and for a sharper reason: unlike migrations or function code, it
|
|
248
|
+
syncs config.toml's *entire* declared state to the project on every push,
|
|
249
|
+
which risks silently overwriting live settings that were never meant to
|
|
250
|
+
match config.toml's (often local-dev-oriented) defaults — this happened
|
|
251
|
+
during development (see git history around the GitHub-auth config).
|
|
252
|
+
Always review `supabase config diff --project-ref <ref>` yourself before
|
|
253
|
+
`supabase config push --project-ref <ref>`.
|
|
254
|
+
|
|
255
|
+
## Releasing the demo app to TestFlight
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
APPLE_TEAM_ID=68CTFST8W2 ./scripts/release_testflight.sh
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Archives `DemoApp` (Release configuration) and uploads it to App Store
|
|
262
|
+
Connect for TestFlight, directly from this Mac — no Fastlane, no manually
|
|
263
|
+
exported `.p12`. Signing is automatic via an App Store Connect API key
|
|
264
|
+
(`FA_ASC_KEY_ID` / `FA_ASC_ISSUER_ID` / `FA_KEY_LOCATION`, set in `~/.zshrc`
|
|
265
|
+
on this machine). `APPLE_TEAM_ID` is passed per invocation rather than
|
|
266
|
+
defaulting globally, since this machine has signing identities for more
|
|
267
|
+
than one Apple Developer Team — `68CTFST8W2` (HEJI TECHNOLOGY LLC) is the
|
|
268
|
+
team that owns the `com.feedbackkit.demo` app record in App Store Connect.
|
|
269
|
+
An app record with that bundle ID must already exist there before you run
|
|
270
|
+
this; the script doesn't create one.
|
|
271
|
+
|
|
272
|
+
## Cutting a release
|
|
273
|
+
|
|
274
|
+
Release the entire suite with a single command:
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
./scripts/cut_release.sh 1.0.0 --notes "Version 1.0.0 release"
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
This publishes the GitHub release and triggers all release pipelines in parallel:
|
|
281
|
+
1. **`.github/workflows/testflight.yml`**: Archives `FeedbackKitDemo` and uploads it to App Store Connect for TestFlight.
|
|
282
|
+
2. **`.github/workflows/release-macos-demo.yml`**: Archives `FeedbackKitDemoMac`, signs it with a **Developer ID Application** certificate, notarizes with Apple, and attaches the notarized `FeedbackKitDemoMac-1.0.0.dmg` directly to the GitHub release.
|
|
283
|
+
3. **`.github/workflows/publish-cli.yml`**: Builds, tests, and publishes `feedbackkit-cli` to both the public npm registry (`feedbackkit-cli`) and GitHub Packages (`@tianhaoz95/feedbackkit-cli`).
|
|
284
|
+
4. **`.github/workflows/publish-skills.yml`**: Validates and publishes `feedback-kit-skills` to both the public npm registry (`feedback-kit-skills`) and GitHub Packages (`@tianhaoz95/feedback-kit-skills`).
|
|
285
|
+
|
|
286
|
+
Unlike TestFlight signing (an "Apple Development" identity Xcode manages
|
|
287
|
+
automatically), Developer ID distribution needs a real exported `.p12` in CI,
|
|
288
|
+
so `release-macos-demo.yml` imports one into a throwaway keychain rather than relying on
|
|
289
|
+
`-allowProvisioningUpdates`. You can also trigger either workflow by hand from the Actions tab
|
|
290
|
+
(`workflow_dispatch`) — for macOS, check "Pipeline validation (no-upload)" there to validate
|
|
291
|
+
the full build, sign, and notarization pipeline without touching a real release.
|
|
292
|
+
|
|
293
|
+
To verify your local credentials and tooling before releasing:
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
./scripts/release-mac.sh --check
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
To build, sign, and notarize locally instead (e.g. to debug a notarization
|
|
300
|
+
rejection without spending a CI run):
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
./scripts/release-mac.sh --version 1.0.0 --no-upload
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Needs a "Developer ID Application" certificate already in your keychain
|
|
307
|
+
(Xcode > Settings > Accounts > Manage Certificates > +) and the same
|
|
308
|
+
`FA_ASC_KEY_ID`/`FA_ASC_ISSUER_ID`/`FA_KEY_LOCATION` App Store Connect API
|
|
309
|
+
key the TestFlight release above uses — notarization just needs *an* ASC
|
|
310
|
+
API key with access to the team, the same one works for both.
|
|
311
|
+
|
|
312
|
+
## Repo layout
|
|
313
|
+
|
|
314
|
+
| Path | What |
|
|
315
|
+
|---|---|
|
|
316
|
+
| `Sources/FeedbackKit/` | The iOS SDK (Swift Package) |
|
|
317
|
+
| `Tests/FeedbackKitTests/` | SDK unit tests |
|
|
318
|
+
| `DemoApp/` | Sample apps exercising the SDK on iOS, macOS, and watchOS (one XcodeGen project, three targets) |
|
|
319
|
+
| `web/` | Static SPA dashboard (Vite + React), deployable to any static host |
|
|
320
|
+
| `supabase/` | Postgres migrations, storage policies, the ingestion Edge Function, billing (Stripe) Edge Functions |
|
|
321
|
+
| `cli/` | `feedbackkit` CLI + MCP server (Node/TypeScript) |
|
|
322
|
+
| `skills/` | Agent Skills catalog (`vercel-labs/skills`) for automated setup via AI coding agents |
|
|
323
|
+
| `scripts/` | `setup.sh`, `run-ios.sh`, `run-macos.sh`, `run-watchos.sh`, `start-web.sh`, `deploy-functions.sh`, `cut_release.sh`, `generate_mac_icon.py`, `release_testflight.sh`, `release-mac.sh`, `release_macos_demo.sh` |
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "feedback-kit-skills",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Agent Skills for FeedbackKit — automated setup for iOS, macOS, watchOS, and MCP server",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/tianhaoz95/feedback-kit.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/tianhaoz95/feedback-kit#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/tianhaoz95/feedback-kit/issues"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"skills",
|
|
16
|
+
"agent-skills",
|
|
17
|
+
"feedbackkit",
|
|
18
|
+
"ios",
|
|
19
|
+
"macos",
|
|
20
|
+
"watchos",
|
|
21
|
+
"mcp",
|
|
22
|
+
"claude-code",
|
|
23
|
+
"cursor",
|
|
24
|
+
"antigravity",
|
|
25
|
+
"codex"
|
|
26
|
+
],
|
|
27
|
+
"author": "Tianhao Zhao",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"files": [
|
|
30
|
+
"skills",
|
|
31
|
+
"README.md"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"new": "node scripts/new-skill.mjs",
|
|
35
|
+
"validate": "node scripts/validate-skills.mjs",
|
|
36
|
+
"list": "npx skills add . --list",
|
|
37
|
+
"prepublishOnly": "npm run validate"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@clack/core": "^0.4.1",
|
|
41
|
+
"@clack/prompts": "^0.9.1",
|
|
42
|
+
"picocolors": "^1.1.1"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# FeedbackKit Setup Skills
|
|
2
|
+
|
|
3
|
+
This category contains [Agent Skills](https://github.com/vercel-labs/skills) that guide AI coding agents (Claude Code, Cursor, Antigravity, Codex, etc.) to set up and configure FeedbackKit across Apple platforms (iOS, macOS, watchOS) and configure the MCP server.
|
|
4
|
+
|
|
5
|
+
## Skills in this Category
|
|
6
|
+
|
|
7
|
+
| Skill | Description |
|
|
8
|
+
|---|---|
|
|
9
|
+
| [`setup-ios-sdk`](setup-ios-sdk/SKILL.md) | Integrate FeedbackKit into an iOS app (SwiftUI or UIKit) with package setup, triggers, and screen tracking. |
|
|
10
|
+
| [`setup-macos-sdk`](setup-macos-sdk/SKILL.md) | Integrate FeedbackKit into a macOS app (SwiftUI or AppKit) with window triggers, menu items, and screen tracking. |
|
|
11
|
+
| [`setup-watchos-sdk`](setup-watchos-sdk/SKILL.md) | Integrate FeedbackKit into a watchOS app using `FeedbackQuickNoteView`. |
|
|
12
|
+
| [`setup-mcp-server`](setup-mcp-server/SKILL.md) | Configure the FeedbackKit CLI and MCP server for Claude Code, Cursor, Antigravity, and Codex. |
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
- **Xcode 14+** installed with Swift 5.7+ toolchain.
|
|
17
|
+
- For hosted dashboard sync: A FeedbackKit project key and endpoint URL from your dashboard.
|
|
18
|
+
- For local development: FeedbackKit local development stack running via `./scripts/start-web.sh`.
|
|
19
|
+
- For MCP server: Node.js 18+ and an active FeedbackKit dashboard account.
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup-ios-sdk
|
|
3
|
+
description: Integrate FeedbackKit SDK into an iOS project (SwiftUI or UIKit) — adds package dependency, configures project key/endpoint at app launch, sets up shake or floating triggers, and adds screen tracking.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# setup-ios-sdk
|
|
7
|
+
|
|
8
|
+
Integrates the FeedbackKit SDK into an iOS application (SwiftUI or UIKit). The agent inspects the project structure, adds the Swift Package dependency, initializes the SDK with project credentials, wires up user triggers (shake-to-report or floating button), and adds screen tracking.
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
- Use when integrating FeedbackKit into a new or existing iOS project.
|
|
13
|
+
- Trigger phrases: "add feedbackkit to ios", "setup feedbackkit in swiftui", "install feedbackkit", "add feedback reporting to ios app", "configure feedbackkit".
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
- iOS 15.0+ deployment target.
|
|
18
|
+
- Xcode 14+ / Swift 5.7+ toolchain.
|
|
19
|
+
- A FeedbackKit project key and endpoint URL (if sending to the dashboard; optional for standalone local capture).
|
|
20
|
+
|
|
21
|
+
## Step-by-Step Instructions
|
|
22
|
+
|
|
23
|
+
### Step 1 -- Detect Project Type and Architecture
|
|
24
|
+
|
|
25
|
+
Inspect the repository root and project files to determine:
|
|
26
|
+
1. **Project Definition**: Is it defined by an Xcode project (`.xcodeproj`), an XcodeGen specification (`project.yml`), or a Swift Package (`Package.swift`)?
|
|
27
|
+
2. **UI Framework & Lifecycle**: Is the app using SwiftUI (`@main struct App: App`) or UIKit (`AppDelegate` / `SceneDelegate`)?
|
|
28
|
+
|
|
29
|
+
### Step 2 -- Add Swift Package Dependency
|
|
30
|
+
|
|
31
|
+
#### XcodeGen (`project.yml`)
|
|
32
|
+
If the project uses XcodeGen, add the dependency to `project.yml` under `packages` and target `dependencies`:
|
|
33
|
+
```yaml
|
|
34
|
+
packages:
|
|
35
|
+
FeedbackKit:
|
|
36
|
+
url: https://github.com/tianhaoz95/feedback-kit
|
|
37
|
+
from: 1.0.0
|
|
38
|
+
targets:
|
|
39
|
+
YourAppTarget:
|
|
40
|
+
dependencies:
|
|
41
|
+
- package: FeedbackKit
|
|
42
|
+
```
|
|
43
|
+
Then regenerate the Xcode project:
|
|
44
|
+
```bash
|
|
45
|
+
xcodegen generate
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### Swift Package (`Package.swift`)
|
|
49
|
+
If the target is a Swift package:
|
|
50
|
+
```swift
|
|
51
|
+
dependencies: [
|
|
52
|
+
.package(url: "https://github.com/tianhaoz95/feedback-kit", from: "1.0.0")
|
|
53
|
+
],
|
|
54
|
+
targets: [
|
|
55
|
+
.target(
|
|
56
|
+
name: "YourAppTarget",
|
|
57
|
+
dependencies: [
|
|
58
|
+
.product(name: "FeedbackKit", package: "feedback-kit")
|
|
59
|
+
]
|
|
60
|
+
)
|
|
61
|
+
]
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
#### Xcode Project (`.xcodeproj`)
|
|
65
|
+
Add the package dependency using Xcode or by referencing the package URL:
|
|
66
|
+
- Repository URL: `https://github.com/tianhaoz95/feedback-kit`
|
|
67
|
+
- Version rule: Up to Next Major from `1.0.0` (or branch `main`)
|
|
68
|
+
- Add product `FeedbackKit` to your main iOS app target.
|
|
69
|
+
|
|
70
|
+
### Step 3 -- Configure FeedbackKit at App Launch
|
|
71
|
+
|
|
72
|
+
Initialize `FeedbackKit.configure` at the earliest point in the application lifecycle.
|
|
73
|
+
|
|
74
|
+
#### SwiftUI (`@main App`)
|
|
75
|
+
Place inside your `App` struct's `init()` method:
|
|
76
|
+
```swift
|
|
77
|
+
import SwiftUI
|
|
78
|
+
import FeedbackKit
|
|
79
|
+
|
|
80
|
+
@main
|
|
81
|
+
struct MyApp: App {
|
|
82
|
+
init() {
|
|
83
|
+
FeedbackKit.configure(.init(
|
|
84
|
+
endpointURL: URL(string: "https://<your-project-ref>.supabase.co/functions/v1/ingest-feedback")!,
|
|
85
|
+
projectKey: "<your-project-key>"
|
|
86
|
+
))
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
var body: some Scene {
|
|
90
|
+
WindowGroup {
|
|
91
|
+
ContentView()
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### UIKit (`AppDelegate.swift`)
|
|
98
|
+
Place in `application(_:didFinishLaunchingWithOptions:)`:
|
|
99
|
+
```swift
|
|
100
|
+
import UIKit
|
|
101
|
+
import FeedbackKit
|
|
102
|
+
|
|
103
|
+
@main
|
|
104
|
+
class AppDelegate: UIResponder, UIApplicationDelegate {
|
|
105
|
+
func application(
|
|
106
|
+
_ application: UIApplication,
|
|
107
|
+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
|
108
|
+
) -> Bool {
|
|
109
|
+
FeedbackKit.configure(.init(
|
|
110
|
+
endpointURL: URL(string: "https://<your-project-ref>.supabase.co/functions/v1/ingest-feedback")!,
|
|
111
|
+
projectKey: "<your-project-key>"
|
|
112
|
+
))
|
|
113
|
+
return true
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Step 4 -- Install User Feedback Triggers
|
|
119
|
+
|
|
120
|
+
FeedbackKit provides multiple trigger options. Install one or more based on user needs:
|
|
121
|
+
|
|
122
|
+
#### Option A: Shake to Report (Recommended for iOS)
|
|
123
|
+
Triggers the capture and annotation UI whenever the user physically shakes the device or triggers a shake in the Simulator (`Device > Shake Gesture` / `⌃⌘Z`):
|
|
124
|
+
|
|
125
|
+
```swift
|
|
126
|
+
FeedbackKit.enableShakeToReport {
|
|
127
|
+
UIApplication.shared.connectedScenes
|
|
128
|
+
.compactMap { $0 as? UIWindowScene }
|
|
129
|
+
.flatMap { $0.windows }
|
|
130
|
+
.first { $0.isKeyWindow }?
|
|
131
|
+
.rootViewController
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### Option B: Draggable Floating Trigger Button
|
|
136
|
+
Places a persistent, draggable floating button over the UI:
|
|
137
|
+
|
|
138
|
+
```swift
|
|
139
|
+
FeedbackKit.showFloatingTriggerButton {
|
|
140
|
+
UIApplication.shared.connectedScenes
|
|
141
|
+
.compactMap { $0 as? UIWindowScene }
|
|
142
|
+
.flatMap { $0.windows }
|
|
143
|
+
.first { $0.isKeyWindow }?
|
|
144
|
+
.rootViewController
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### Option C: Programmatic Presentation from UI
|
|
149
|
+
Call directly from a button, menu item, or help screen:
|
|
150
|
+
|
|
151
|
+
```swift
|
|
152
|
+
// Present and automatically submit to the configured dashboard:
|
|
153
|
+
FeedbackKit.presentAndSubmit(from: viewController)
|
|
154
|
+
|
|
155
|
+
// Or present and handle the FeedbackReport manually:
|
|
156
|
+
FeedbackKit.present(from: viewController) { report in
|
|
157
|
+
guard let report else { return } // User canceled
|
|
158
|
+
print("Report description: \(report.userDescription)")
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Step 5 -- Track Screens (Recommended)
|
|
163
|
+
|
|
164
|
+
Keep `FeedbackKit.currentScreen` updated during navigation so reports capture the active screen name:
|
|
165
|
+
|
|
166
|
+
#### SwiftUI
|
|
167
|
+
```swift
|
|
168
|
+
struct CheckoutView: View {
|
|
169
|
+
var body: some View {
|
|
170
|
+
VStack {
|
|
171
|
+
// view content
|
|
172
|
+
}
|
|
173
|
+
.onAppear {
|
|
174
|
+
FeedbackKit.currentScreen = "Checkout"
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
#### UIKit
|
|
181
|
+
```swift
|
|
182
|
+
override func viewDidAppear(_ animated: Bool) {
|
|
183
|
+
super.viewDidAppear(animated)
|
|
184
|
+
FeedbackKit.currentScreen = "Checkout"
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Step 6 -- Optional Theming
|
|
189
|
+
|
|
190
|
+
Customize the accent colors to match the app branding (hex color strings):
|
|
191
|
+
```swift
|
|
192
|
+
FeedbackKit.theme = .init(
|
|
193
|
+
primaryColorHex: "#0A84FF",
|
|
194
|
+
secondaryColorHex: "#64D2FF"
|
|
195
|
+
)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Step 7 -- Verify the Build
|
|
199
|
+
|
|
200
|
+
Build the project to verify clean compilation:
|
|
201
|
+
```bash
|
|
202
|
+
xcodebuild build -scheme YourScheme -destination 'generic/platform=iOS Simulator'
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Non-Obvious Pitfalls
|
|
206
|
+
|
|
207
|
+
- **Key Window Resolution**: In iOS 15+, `UIApplication.shared.keyWindow` is deprecated. Use the multi-scene resolution pattern shown in Step 4 (`connectedScenes -> UIWindowScene -> windows -> isKeyWindow`).
|
|
208
|
+
- **Simulator Shake Testing**: To test shake-to-report in the iOS Simulator, select `Features > Shake Gesture` or press `Ctrl + Cmd + Z`.
|
|
209
|
+
- **Window-Level Capture**: FeedbackKit captures screenshot at the window level (`UIWindow`), rendering both UIKit and SwiftUI hierarchies without needing view-controller-specific hooks.
|
|
210
|
+
- **Optional Screenshot**: `FeedbackReport.screenshotRawPNG` and `FeedbackReport.screenshotAnnotatedPNG` are `Data?` (nullable) because users can toggle the screenshot off in the composer UI. Always handle optionality when processing reports manually.
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup-macos-sdk
|
|
3
|
+
description: Integrate FeedbackKit SDK into a macOS desktop app (SwiftUI or AppKit) — adds package dependency, configures project credentials, sets up floating button or menu item triggers, and configures screen tracking.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# setup-macos-sdk
|
|
7
|
+
|
|
8
|
+
Integrates the FeedbackKit SDK into a macOS desktop application (SwiftUI or AppKit). The agent adds the Swift package, initializes credentials at application startup, wires up macOS triggers (floating button or menu item), and configures screen tracking.
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
- Use when adding FeedbackKit feedback reporting to a macOS desktop application.
|
|
13
|
+
- Trigger phrases: "add feedbackkit to macos", "setup feedbackkit in mac app", "install feedbackkit macos", "add feedback to appkit app".
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
- macOS 12.0+ deployment target.
|
|
18
|
+
- Xcode 14+ / Swift 5.7+ toolchain.
|
|
19
|
+
- A FeedbackKit project key and endpoint URL (optional if only handling local reports).
|
|
20
|
+
|
|
21
|
+
## Step-by-Step Instructions
|
|
22
|
+
|
|
23
|
+
### Step 1 -- Add Swift Package Dependency
|
|
24
|
+
|
|
25
|
+
#### XcodeGen (`project.yml`)
|
|
26
|
+
```yaml
|
|
27
|
+
packages:
|
|
28
|
+
FeedbackKit:
|
|
29
|
+
url: https://github.com/tianhaoz95/feedback-kit
|
|
30
|
+
from: 1.0.0
|
|
31
|
+
targets:
|
|
32
|
+
YourMacAppTarget:
|
|
33
|
+
dependencies:
|
|
34
|
+
- package: FeedbackKit
|
|
35
|
+
```
|
|
36
|
+
Regenerate Xcode project if using XcodeGen:
|
|
37
|
+
```bash
|
|
38
|
+
xcodegen generate
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
#### Swift Package (`Package.swift`)
|
|
42
|
+
```swift
|
|
43
|
+
dependencies: [
|
|
44
|
+
.package(url: "https://github.com/tianhaoz95/feedback-kit", from: "1.0.0")
|
|
45
|
+
],
|
|
46
|
+
targets: [
|
|
47
|
+
.target(
|
|
48
|
+
name: "YourMacAppTarget",
|
|
49
|
+
dependencies: [
|
|
50
|
+
.product(name: "FeedbackKit", package: "feedback-kit")
|
|
51
|
+
]
|
|
52
|
+
)
|
|
53
|
+
]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Step 2 -- Configure FeedbackKit at Launch
|
|
57
|
+
|
|
58
|
+
#### SwiftUI (`@main App`)
|
|
59
|
+
```swift
|
|
60
|
+
import SwiftUI
|
|
61
|
+
import FeedbackKit
|
|
62
|
+
|
|
63
|
+
@main
|
|
64
|
+
struct MyMacApp: App {
|
|
65
|
+
init() {
|
|
66
|
+
FeedbackKit.configure(.init(
|
|
67
|
+
endpointURL: URL(string: "https://<your-project-ref>.supabase.co/functions/v1/ingest-feedback")!,
|
|
68
|
+
projectKey: "<your-project-key>"
|
|
69
|
+
))
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
var body: some Scene {
|
|
73
|
+
WindowGroup {
|
|
74
|
+
ContentView()
|
|
75
|
+
}
|
|
76
|
+
.commands {
|
|
77
|
+
// Optional: Help menu feedback item
|
|
78
|
+
CommandGroup(replacing: .help) {
|
|
79
|
+
Button("Report a Problem…") {
|
|
80
|
+
FeedbackKit.presentAndSubmit(from: NSApplication.shared.keyWindow)
|
|
81
|
+
}
|
|
82
|
+
.keyboardShortcut("r", modifiers: [.command, .shift])
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### AppKit (`NSApplicationDelegate`)
|
|
90
|
+
```swift
|
|
91
|
+
import AppKit
|
|
92
|
+
import FeedbackKit
|
|
93
|
+
|
|
94
|
+
@main
|
|
95
|
+
class AppDelegate: NSObject, NSApplicationDelegate {
|
|
96
|
+
func applicationDidFinishLaunching(_ notification: Notification) {
|
|
97
|
+
FeedbackKit.configure(.init(
|
|
98
|
+
endpointURL: URL(string: "https://<your-project-ref>.supabase.co/functions/v1/ingest-feedback")!,
|
|
99
|
+
projectKey: "<your-project-key>"
|
|
100
|
+
))
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Step 3 -- Install Feedback Triggers on macOS
|
|
106
|
+
|
|
107
|
+
macOS apps do not have shake sensors. The recommended triggers are floating buttons and menu items:
|
|
108
|
+
|
|
109
|
+
#### Option A: Floating Trigger Button (Recommended)
|
|
110
|
+
Places a draggable button over the main window content:
|
|
111
|
+
```swift
|
|
112
|
+
FeedbackKit.showFloatingTriggerButton {
|
|
113
|
+
NSApplication.shared.keyWindow
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### Option B: Menu Bar Item
|
|
118
|
+
Add a menu item in SwiftUI commands or an AppKit `NSMenuItem` action:
|
|
119
|
+
```swift
|
|
120
|
+
FeedbackKit.presentAndSubmit(from: NSApplication.shared.keyWindow)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### Option C: Custom Button or Settings Action
|
|
124
|
+
```swift
|
|
125
|
+
// Present sheet and automatically submit to dashboard:
|
|
126
|
+
FeedbackKit.presentAndSubmit(from: NSApplication.shared.keyWindow)
|
|
127
|
+
|
|
128
|
+
// Or present sheet and process report manually:
|
|
129
|
+
FeedbackKit.present(from: NSApplication.shared.keyWindow) { report in
|
|
130
|
+
guard let report else { return }
|
|
131
|
+
print("Report submitted: \(report.id)")
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Step 4 -- Configure Screen Tracking
|
|
136
|
+
|
|
137
|
+
Because macOS does not have a single mobile view-controller stack, set `FeedbackKit.currentScreen` when the user navigates:
|
|
138
|
+
|
|
139
|
+
```swift
|
|
140
|
+
.onAppear {
|
|
141
|
+
FeedbackKit.currentScreen = "Preferences"
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Step 5 -- Verify the Build
|
|
146
|
+
|
|
147
|
+
Verify that the macOS app compiles cleanly:
|
|
148
|
+
```bash
|
|
149
|
+
swift build
|
|
150
|
+
# or
|
|
151
|
+
xcodebuild build -scheme YourMacScheme
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Non-Obvious Pitfalls
|
|
155
|
+
|
|
156
|
+
- **Sheet Presentation**: On macOS, FeedbackKit presents as a sheet attached to the target `NSWindow` rather than taking over the entire screen. Ensure `NSApplication.shared.keyWindow` or a specific window reference is non-nil when presenting.
|
|
157
|
+
- **No Shake Sensor**: `FeedbackKit.enableShakeToReport` is iOS-only and does not exist on macOS. Use `showFloatingTriggerButton` or menu commands instead.
|
|
158
|
+
- **No Screen Recording Permission Needed**: The SDK uses `NSView.cacheDisplay(in:to:)` to render the window's content hierarchy, which does not require macOS Screen Recording permissions.
|
|
159
|
+
- **Trackpad Gestures**: Scaling and rotating annotations on macOS uses two-finger trackpad pinch and rotation (`NSMagnificationGestureRecognizer` and `NSRotationGestureRecognizer`).
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup-mcp-server
|
|
3
|
+
description: Configure the FeedbackKit CLI and Model Context Protocol (MCP) server for AI coding agents — installs feedbackkit-cli, completes browser-based authentication, and registers MCP server in Claude Code, Cursor, Antigravity, or Codex.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# setup-mcp-server
|
|
7
|
+
|
|
8
|
+
Configures the FeedbackKit CLI and Model Context Protocol (MCP) server so that AI coding agents (Claude Code, Cursor, Antigravity, Codex, etc.) can directly query user feedback reports, inspect annotated screenshots, retrieve generated debugging prompts, and update ticket statuses without human copy-pasting.
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
- Use when connecting an AI coding agent to the FeedbackKit dashboard.
|
|
13
|
+
- Trigger phrases: "setup feedbackkit mcp", "connect feedbackkit to claude code", "add feedbackkit mcp to cursor", "configure feedbackkit agent".
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
- Node.js 18+ and npm installed.
|
|
18
|
+
- An account on the FeedbackKit hosted dashboard (or a running local instance).
|
|
19
|
+
- An AI coding assistant that supports MCP (Claude Code, Cursor, Antigravity, Codex, Windsurf, etc.).
|
|
20
|
+
|
|
21
|
+
## Step-by-Step Instructions
|
|
22
|
+
|
|
23
|
+
### Step 1 -- Install the FeedbackKit CLI
|
|
24
|
+
|
|
25
|
+
Install the CLI globally from npm, or run via `npx`:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install -g feedbackkit-cli
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Verify installation:
|
|
32
|
+
```bash
|
|
33
|
+
feedbackkit --version
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Step 2 -- Authenticate the CLI
|
|
37
|
+
|
|
38
|
+
Log in to your FeedbackKit account. This launches a browser window to complete GitHub OAuth and seamlessly passes credentials back to a temporary local server:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
feedbackkit login
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
If connecting to a self-hosted or local development stack:
|
|
45
|
+
```bash
|
|
46
|
+
feedbackkit login --dashboard-url http://localhost:3000
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Verify that access is active by listing projects:
|
|
50
|
+
```bash
|
|
51
|
+
feedbackkit list
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Step 3 -- Register the MCP Server with Your AI Agent
|
|
55
|
+
|
|
56
|
+
The MCP server runs over stdio via `feedbackkit mcp` (or `npx -y feedbackkit-cli mcp`).
|
|
57
|
+
|
|
58
|
+
#### Claude Code
|
|
59
|
+
Add the MCP server to Claude Code using the CLI:
|
|
60
|
+
```bash
|
|
61
|
+
claude mcp add feedbackkit -- npx -y feedbackkit-cli mcp
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Or configure Claude Desktop in `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"mcpServers": {
|
|
68
|
+
"feedbackkit": {
|
|
69
|
+
"command": "npx",
|
|
70
|
+
"args": ["-y", "feedbackkit-cli", "mcp"]
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### Cursor
|
|
77
|
+
Open Cursor Settings > MCP (or edit `.cursor/mcp.json` in your workspace):
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"mcpServers": {
|
|
81
|
+
"feedbackkit": {
|
|
82
|
+
"command": "npx",
|
|
83
|
+
"args": ["-y", "feedbackkit-cli", "mcp"]
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### Google Antigravity
|
|
90
|
+
Add via the `agy` CLI:
|
|
91
|
+
```bash
|
|
92
|
+
agy mcp add feedbackkit --command npx --args -y,feedbackkit-cli,mcp
|
|
93
|
+
```
|
|
94
|
+
Or add to your project's `.gemini/settings.json` under `mcpServers`.
|
|
95
|
+
|
|
96
|
+
#### OpenAI Codex / Generic MCP Clients
|
|
97
|
+
Configure an stdio server with:
|
|
98
|
+
- **Command**: `npx`
|
|
99
|
+
- **Arguments**: `["-y", "feedbackkit-cli", "mcp"]`
|
|
100
|
+
|
|
101
|
+
### Step 4 -- Verify Available Tools
|
|
102
|
+
|
|
103
|
+
Once connected, your agent will have access to five FeedbackKit tools:
|
|
104
|
+
|
|
105
|
+
1. `list_feedback`: List feedback items filtered by project or status (`new`, `in_progress`, `resolved`, `closed`).
|
|
106
|
+
2. `get_feedback`: Retrieve full details of an item including signed URLs for raw and annotated screenshots.
|
|
107
|
+
3. `get_feedback_prompt`: Fetch the pre-formatted coding prompt generated by the dashboard's prompt template.
|
|
108
|
+
4. `update_feedback_status`: Update the status of a feedback item (e.g. mark as `in_progress` or `resolved`).
|
|
109
|
+
5. `get_docs`: Retrieve FeedbackKit documentation topics directly inside agent context.
|
|
110
|
+
|
|
111
|
+
### Step 5 -- Test MCP Integration
|
|
112
|
+
|
|
113
|
+
Prompt your agent:
|
|
114
|
+
> "Use the feedbackkit MCP server to list any open feedback reports for this project."
|
|
115
|
+
|
|
116
|
+
The agent should invoke `list_feedback` and present the feedback items.
|
|
117
|
+
|
|
118
|
+
## Non-Obvious Pitfalls
|
|
119
|
+
|
|
120
|
+
- **Authentication Storage**: `feedbackkit login` stores tokens securely in `~/.config/feedbackkit/config.json` (or OS equivalent). The MCP server automatically reads these credentials.
|
|
121
|
+
- **Revocation**: Sessions can be audited or revoked at any time from the dashboard under **CLI Sessions** (`/cli-sessions`).
|
|
122
|
+
- **No Token Overhead**: FeedbackKit does not require special API tokens or secret management for MCP — authentication inherits your dashboard account permissions and respects PostgreSQL Row-Level Security (RLS).
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup-watchos-sdk
|
|
3
|
+
description: Integrate FeedbackKit SDK into a watchOS app using FeedbackQuickNoteView — adds package dependency, configures project credentials, presents quick note modal, and tracks watch screen state.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# setup-watchos-sdk
|
|
7
|
+
|
|
8
|
+
Integrates the FeedbackKit SDK into a watchOS application. Because Apple Watch screens are too small for freehand screenshot annotation, FeedbackKit provides `FeedbackQuickNoteView` — a streamlined text and context reporting interface embedded directly in SwiftUI.
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
- Use when adding in-app feedback to a standalone or companion watchOS app.
|
|
13
|
+
- Trigger phrases: "add feedbackkit to watchos", "setup feedbackkit in apple watch app", "install feedbackkit watchos", "apple watch feedback reporting".
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
- watchOS 8.0+ deployment target (9.0+ for standalone watch apps).
|
|
18
|
+
- SwiftUI-based watchOS project.
|
|
19
|
+
- A FeedbackKit project key and endpoint URL (optional if consuming reports locally).
|
|
20
|
+
|
|
21
|
+
## Step-by-Step Instructions
|
|
22
|
+
|
|
23
|
+
### Step 1 -- Add Swift Package Dependency
|
|
24
|
+
|
|
25
|
+
#### XcodeGen (`project.yml`)
|
|
26
|
+
```yaml
|
|
27
|
+
packages:
|
|
28
|
+
FeedbackKit:
|
|
29
|
+
url: https://github.com/tianhaoz95/feedback-kit
|
|
30
|
+
from: 1.0.0
|
|
31
|
+
targets:
|
|
32
|
+
YourWatchAppTarget:
|
|
33
|
+
dependencies:
|
|
34
|
+
- package: FeedbackKit
|
|
35
|
+
```
|
|
36
|
+
Regenerate Xcode project if using XcodeGen:
|
|
37
|
+
```bash
|
|
38
|
+
xcodegen generate
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
#### Swift Package (`Package.swift`)
|
|
42
|
+
```swift
|
|
43
|
+
dependencies: [
|
|
44
|
+
.package(url: "https://github.com/tianhaoz95/feedback-kit", from: "1.0.0")
|
|
45
|
+
],
|
|
46
|
+
targets: [
|
|
47
|
+
.target(
|
|
48
|
+
name: "YourWatchAppTarget",
|
|
49
|
+
dependencies: [
|
|
50
|
+
.product(name: "FeedbackKit", package: "feedback-kit")
|
|
51
|
+
]
|
|
52
|
+
)
|
|
53
|
+
]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Step 2 -- Configure FeedbackKit at Launch
|
|
57
|
+
|
|
58
|
+
Initialize FeedbackKit inside your watchOS `@main App` struct's `init()`:
|
|
59
|
+
|
|
60
|
+
```swift
|
|
61
|
+
import SwiftUI
|
|
62
|
+
import FeedbackKit
|
|
63
|
+
|
|
64
|
+
@main
|
|
65
|
+
struct MyWatchApp: App {
|
|
66
|
+
init() {
|
|
67
|
+
FeedbackKit.configure(.init(
|
|
68
|
+
endpointURL: URL(string: "https://<your-project-ref>.supabase.co/functions/v1/ingest-feedback")!,
|
|
69
|
+
projectKey: "<your-project-key>"
|
|
70
|
+
))
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
var body: some Scene {
|
|
74
|
+
WindowGroup {
|
|
75
|
+
ContentView()
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Step 3 -- Present `FeedbackQuickNoteView`
|
|
82
|
+
|
|
83
|
+
watchOS does not support modal window overlays or shake triggers. Embed `FeedbackQuickNoteView` inside a SwiftUI `.sheet`:
|
|
84
|
+
|
|
85
|
+
```swift
|
|
86
|
+
import SwiftUI
|
|
87
|
+
import FeedbackKit
|
|
88
|
+
|
|
89
|
+
struct ContentView: View {
|
|
90
|
+
@State private var showingFeedback = false
|
|
91
|
+
|
|
92
|
+
var body: some View {
|
|
93
|
+
List {
|
|
94
|
+
Section("Settings") {
|
|
95
|
+
Button {
|
|
96
|
+
showingFeedback = true
|
|
97
|
+
} label: {
|
|
98
|
+
Label("Send Feedback", systemImage: "bubble.left.and.exclamationmark")
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
.sheet(isPresented: $showingFeedback) {
|
|
103
|
+
FeedbackQuickNoteView { report in
|
|
104
|
+
guard let report else {
|
|
105
|
+
// User canceled
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
print("Submitted watch feedback: \(report.userDescription)")
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Step 4 -- Configure Screen Tracking
|
|
116
|
+
|
|
117
|
+
Set `FeedbackKit.currentScreen` on active watch views:
|
|
118
|
+
|
|
119
|
+
```swift
|
|
120
|
+
.onAppear {
|
|
121
|
+
FeedbackKit.currentScreen = "HeartRateMonitor"
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Step 5 -- Verify the Build
|
|
126
|
+
|
|
127
|
+
Verify the watchOS target compiles cleanly:
|
|
128
|
+
```bash
|
|
129
|
+
xcodebuild build -scheme YourWatchScheme -destination 'generic/platform=watchOS Simulator'
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Non-Obvious Pitfalls
|
|
133
|
+
|
|
134
|
+
- **No Window Overlay or Shake**: `FeedbackKit.present(from:)`, `FeedbackKit.enableShakeToReport`, and `FeedbackKit.showFloatingTriggerButton` are not available on watchOS (there is no `UIWindow` or shake responder). Use `FeedbackQuickNoteView` directly in a SwiftUI sheet or view hierarchy.
|
|
135
|
+
- **Placeholder Screenshot**: Since watchOS does not offer a public window-capture API, FeedbackKit automatically generates a lightweight, labeled placeholder card for `FeedbackReport.screenshotRawPNG` so that database fields and downstream prompt generators receive valid images.
|
|
136
|
+
- **Dictation and Scribble**: `FeedbackQuickNoteView` uses standard SwiftUI text fields, enabling watchOS voice dictation, scribble, and QWERTY keyboards automatically.
|