aiblueprint-cli 1.4.80 → 1.4.82

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.
Files changed (84) hide show
  1. package/README.md +21 -17
  2. package/agents-config/claude-config/scripts/statusline/data/.gitignore +8 -0
  3. package/agents-config/claude-config/scripts/statusline/data/.gitkeep +0 -0
  4. package/agents-config/claude-config/scripts/statusline/defaults.json +10 -10
  5. package/agents-config/claude-config/scripts/statusline/src/commands/interactive-config.ts +118 -6
  6. package/agents-config/claude-config/scripts/statusline/src/index.ts +100 -9
  7. package/agents-config/claude-config/scripts/statusline/src/lib/config.ts +28 -2
  8. package/agents-config/claude-config/scripts/statusline/src/lib/features/limits/commands/weekly-analysis.ts +108 -0
  9. package/agents-config/claude-config/scripts/statusline/src/lib/features/limits/index.ts +164 -0
  10. package/agents-config/claude-config/scripts/statusline/src/lib/features/limits/types.ts +15 -0
  11. package/agents-config/claude-config/scripts/statusline/src/lib/features/spend/commands/migrate-to-sqlite.ts +136 -0
  12. package/agents-config/claude-config/scripts/statusline/src/lib/features/spend/commands/spend-day.ts +79 -0
  13. package/agents-config/claude-config/scripts/statusline/src/lib/features/spend/commands/spend-month.ts +66 -0
  14. package/agents-config/claude-config/scripts/statusline/src/lib/features/spend/commands/spend-project.ts +85 -0
  15. package/agents-config/claude-config/scripts/statusline/src/lib/features/spend/database.ts +395 -0
  16. package/agents-config/claude-config/scripts/statusline/src/lib/features/spend/index.ts +178 -0
  17. package/agents-config/claude-config/scripts/statusline/src/lib/features/spend/payload-logger.ts +163 -0
  18. package/agents-config/claude-config/scripts/statusline/src/lib/features/spend/types.ts +37 -0
  19. package/agents-config/claude-config/scripts/statusline/src/lib/presets.ts +13 -13
  20. package/agents-config/claude-config/scripts/statusline/statusline.config.free.json +4 -1
  21. package/agents-config/claude-config/scripts/statusline/statusline.config.json +44 -23
  22. package/agents-config/scripts/statusline/data/.gitignore +8 -0
  23. package/agents-config/scripts/statusline/data/.gitkeep +0 -0
  24. package/agents-config/scripts/statusline/defaults.json +10 -10
  25. package/agents-config/scripts/statusline/src/commands/interactive-config.ts +118 -6
  26. package/agents-config/scripts/statusline/src/index.ts +100 -9
  27. package/agents-config/scripts/statusline/src/lib/config.ts +28 -2
  28. package/agents-config/scripts/statusline/src/lib/features/limits/commands/weekly-analysis.ts +108 -0
  29. package/agents-config/scripts/statusline/src/lib/features/limits/index.ts +164 -0
  30. package/agents-config/scripts/statusline/src/lib/features/limits/types.ts +15 -0
  31. package/agents-config/scripts/statusline/src/lib/features/spend/commands/migrate-to-sqlite.ts +136 -0
  32. package/agents-config/scripts/statusline/src/lib/features/spend/commands/spend-day.ts +79 -0
  33. package/agents-config/scripts/statusline/src/lib/features/spend/commands/spend-month.ts +66 -0
  34. package/agents-config/scripts/statusline/src/lib/features/spend/commands/spend-project.ts +85 -0
  35. package/agents-config/scripts/statusline/src/lib/features/spend/database.ts +395 -0
  36. package/agents-config/scripts/statusline/src/lib/features/spend/index.ts +178 -0
  37. package/agents-config/scripts/statusline/src/lib/features/spend/payload-logger.ts +163 -0
  38. package/agents-config/scripts/statusline/src/lib/features/spend/types.ts +37 -0
  39. package/agents-config/scripts/statusline/src/lib/presets.ts +13 -13
  40. package/agents-config/scripts/statusline/statusline.config.free.json +4 -1
  41. package/agents-config/scripts/statusline/statusline.config.json +44 -23
  42. package/agents-config/skills/agents-managers/SKILL.md +1 -1
  43. package/agents-config/skills/agents-managers/references/writing-agent-prompts.md +1 -1
  44. package/agents-config/skills/appstore-connect/SKILL.md +104 -0
  45. package/agents-config/skills/appstore-connect/scripts/asc-api.mjs +88 -0
  46. package/agents-config/skills/appstore-connect-setup/SKILL.md +159 -0
  47. package/agents-config/{commands/prompts/create-vitejs-app.md → skills/create-vitejs-app/SKILL.md} +2 -1
  48. package/agents-config/skills/environments-manager/SKILL.md +6 -6
  49. package/agents-config/skills/environments-manager/examples/{claude/commands/dev.md → skills/dev/SKILL.md} +2 -1
  50. package/agents-config/skills/environments-manager/examples/{claude/commands/lint.md → skills/lint/SKILL.md} +2 -1
  51. package/agents-config/skills/environments-manager/examples/{claude/commands/test.md → skills/test/SKILL.md} +2 -1
  52. package/agents-config/skills/environments-manager/examples/{claude/commands/typecheck.md → skills/typecheck/SKILL.md} +2 -1
  53. package/agents-config/skills/environments-manager/references/claude.md +13 -9
  54. package/agents-config/skills/environments-manager/references/cursor.md +2 -2
  55. package/agents-config/skills/ios-testflight/SKILL.md +280 -0
  56. package/agents-config/{commands/prompts/nextjs-add-prisma-db.md → skills/nextjs-add-prisma-db/SKILL.md} +1 -0
  57. package/agents-config/{commands/prompts/nextjs-setup-better-auth.md → skills/nextjs-setup-better-auth/SKILL.md} +1 -0
  58. package/agents-config/{commands/prompts/nextjs-setup-project.md → skills/nextjs-setup-project/SKILL.md} +1 -0
  59. package/agents-config/{commands/prompts/prompt.md → skills/prompt/SKILL.md} +5 -0
  60. package/agents-config/{commands/prompts/saas-challenge-idea.md → skills/saas-challenge-idea/SKILL.md} +1 -0
  61. package/agents-config/{commands/prompts/saas-create-architecture.md → skills/saas-create-architecture/SKILL.md} +1 -0
  62. package/agents-config/{commands/prompts/saas-create-headline.md → skills/saas-create-headline/SKILL.md} +1 -0
  63. package/agents-config/{commands/prompts/saas-create-landing-copywritting.md → skills/saas-create-landing-copywritting/SKILL.md} +1 -0
  64. package/agents-config/{commands/prompts/saas-create-legals-docs.md → skills/saas-create-legals-docs/SKILL.md} +1 -0
  65. package/agents-config/{commands/prompts/saas-create-logos.md → skills/saas-create-logos/SKILL.md} +1 -0
  66. package/agents-config/{commands/prompts/saas-create-prd.md → skills/saas-create-prd/SKILL.md} +4 -3
  67. package/agents-config/{commands/prompts/saas-create-tasks.md → skills/saas-create-tasks/SKILL.md} +1 -0
  68. package/agents-config/{commands/prompts/saas-define-pricing.md → skills/saas-define-pricing/SKILL.md} +1 -0
  69. package/agents-config/{commands/prompts/saas-find-domain-name.md → skills/saas-find-domain-name/SKILL.md} +1 -0
  70. package/agents-config/{commands/prompts/saas-implement-landing-page.md → skills/saas-implement-landing-page/SKILL.md} +1 -0
  71. package/agents-config/{commands/prompts/setup-tmux.md → skills/setup-tmux/SKILL.md} +5 -0
  72. package/agents-config/{commands/prompts/tools.md → skills/tools/SKILL.md} +1 -0
  73. package/agents-config/skills/ultrathink/SKILL.md +1 -1
  74. package/agents-config/skills/use-style/SKILL.md +7 -4
  75. package/agents-config/skills/use-style/examples/luma.html +221 -0
  76. package/agents-config/skills/use-style/examples/testspirite.html +340 -0
  77. package/agents-config/skills/use-style/styles/ios-app.md +350 -0
  78. package/agents-config/skills/use-style/styles/luma.md +422 -0
  79. package/agents-config/skills/use-style/styles/new-york-times.md +1 -1
  80. package/agents-config/skills/use-style/styles/split-auth.md +2 -2
  81. package/agents-config/skills/use-style/styles/testspirite.md +397 -0
  82. package/dist/cli.js +17 -80
  83. package/package.json +1 -1
  84. package/agents-config/claude-config/scripts/.claude/commands/fix-on-my-computer.md +0 -87
@@ -0,0 +1,104 @@
1
+ ---
2
+ name: appstore-connect
3
+ description: Interact with App Store Connect via the asc CLI - apps, builds, TestFlight, beta testers, reviews, sales/analytics, metadata, IAP, signing, submissions. Use for "check my app", "App Store Connect", "TestFlight status", "app review", "my app sales", or "asc".
4
+ ---
5
+
6
+ # App Store Connect (asc)
7
+
8
+ Read, manage, and ship any of the user's App Store apps through the **`asc`** CLI (App Store Connect CLI by Rork). `asc` covers nearly the entire ASC surface; reach for the raw API only for the rare gap.
9
+
10
+ <auth>
11
+ `asc` is already authenticated on this machine (a default keychain profile). Verify before doing real work:
12
+
13
+ ```bash
14
+ asc auth status # shows stored credential profiles + which is default
15
+ asc auth status --validate # confirms a credential actually works
16
+ asc doctor # diagnose auth/config issues
17
+ ```
18
+
19
+ - Multiple accounts/teams: `asc --profile <name> <command>` selects a profile.
20
+ - A NEW account with no stored key: run the `appstore-connect-setup` skill (locates the `.p8`, key id, and issuer id, then `asc auth login`). Never print or commit `.p8` keys, key ids, or issuer ids.
21
+ </auth>
22
+
23
+ <how_to_drive>
24
+ Do NOT guess flags. `asc` is large and self-documenting — discover, then act:
25
+
26
+ ```bash
27
+ asc --help # the full command map (areas below)
28
+ asc <area> --help # subcommands + flags for an area, e.g. `asc builds --help`
29
+ asc docs list # embedded guides; `asc docs <topic>` to read one
30
+ ```
31
+
32
+ - **Read before you write.** List/inspect/validate first; mutate second.
33
+ - **Machine output:** most commands accept `--output json` (or `--output table` for humans) — use JSON when you need to parse ids.
34
+ - Resolve an app id once and reuse it: `asc apps list --output json` → the numeric App Store app id.
35
+ </how_to_drive>
36
+
37
+ <command_map>
38
+ | Goal | Area |
39
+ | --- | --- |
40
+ | List/inspect apps, app id | `asc apps`, `asc status --app <id>` |
41
+ | Builds (processing, ids) | `asc builds` |
42
+ | TestFlight: beta groups, testers, distribute a build | `asc testflight` |
43
+ | Versions / release state | `asc versions`, `asc release`, `asc status` |
44
+ | Metadata, localizations, keywords | `asc metadata`, `asc localizations` |
45
+ | Screenshots / previews | `asc screenshots`, `asc video-previews` |
46
+ | Pricing & availability | `asc pricing` |
47
+ | In-app purchases / subscriptions | `asc iap`, `asc subscriptions` |
48
+ | Age rating / privacy / encryption / EULA | `asc age-rating`, `asc encryption`, `asc eula` |
49
+ | Submission readiness + submit | `asc validate`, `asc review`, `asc submit`, `asc publish` |
50
+ | Customer reviews | `asc reviews` |
51
+ | Sales / analytics / finance | `asc analytics`, `asc insights`, `asc finance`, `asc performance` |
52
+ | Signing: certs, profiles, bundle ids | `asc signing`, `asc certificates`, `asc profiles`, `asc bundle-ids` |
53
+ | Team / users / devices | `asc users`, `asc devices`, `asc account` |
54
+ | Xcode Cloud, webhooks, workflows | `asc xcode-cloud`, `asc webhooks`, `asc workflow` |
55
+ </command_map>
56
+
57
+ <common_tasks>
58
+ ```bash
59
+ # What apps do I have / what's an app's id?
60
+ asc apps list --output table
61
+
62
+ # Where is an app in the release pipeline?
63
+ asc status --app <APP_ID> --output table
64
+
65
+ # Latest builds and processing state
66
+ asc builds list --app <APP_ID> --output json
67
+
68
+ # TestFlight: see groups, add a tester, distribute a build
69
+ asc testflight groups list --app <APP_ID>
70
+ asc publish testflight --app <APP_ID> --ipa <path.ipa> --group "<GROUP_ID>" --wait
71
+
72
+ # Is a version ready to submit? (fix every error it reports first)
73
+ asc validate --app <APP_ID> --version <VERSION> --platform IOS --output table
74
+
75
+ # Read customer reviews / respond
76
+ asc reviews list --app <APP_ID> --output table
77
+
78
+ # Sales & analytics
79
+ asc analytics --help # request/download reports
80
+ asc insights --help # weekly/daily insights
81
+ ```
82
+ </common_tasks>
83
+
84
+ <safety>
85
+ - **Confirm before any mutation that is externally visible or hard to reverse:** `asc submit`, `asc publish ... --submit`, `asc review submit`, `asc pricing` changes, `asc iap`/`asc subscriptions` edits, `asc users` invites/removals, certificate/profile deletion. State the app id, version, and exact change, and get explicit user approval.
86
+ - Prefer dry runs / validation first: many commands accept `--dry-run`; always run `asc validate` before submitting.
87
+ - Never delete a signing certificate or provisioning profile without confirmation — it can break other apps signed with it.
88
+ - Never print or commit `.p8` keys, key ids, issuer ids, app-specific passwords, or downloaded financial reports with PII.
89
+ - This skill manages the store side only. Producing the build (.ipa/.aab) and project config belongs to the app's own deploy workflow.
90
+ </safety>
91
+
92
+ <raw_api_fallback>
93
+ For the rare endpoint `asc` doesn't expose, call the App Store Connect API directly with the bundled helper (zero deps, ES256 JWT). Credentials come from env vars — never hardcode them:
94
+
95
+ ```bash
96
+ export ASC_KEY_ID=... # 10-char key id (from the AuthKey_<KEY_ID>.p8 filename)
97
+ export ASC_ISSUER_ID=... # team issuer UUID (App Store Connect > Users and Access > Integrations)
98
+ export ASC_P8_PATH=/path/to/AuthKey_<KEY_ID>.p8
99
+ node "$SKILL_DIR/scripts/asc-api.mjs" GET "/v1/apps?filter[bundleId]=com.example.app"
100
+ node "$SKILL_DIR/scripts/asc-api.mjs" POST /v1/betaGroups body.json
101
+ ```
102
+
103
+ `$SKILL_DIR` is this skill's directory. The helper prints `{"status", "body"}` and exits non-zero on HTTP >= 400.
104
+ </raw_api_fallback>
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Minimal App Store Connect API client. Zero dependencies.
4
+ * Used by the setup-testflight / deploy-ios-app skills to manage certificates,
5
+ * provisioning profiles, beta groups, and testers without the web UI.
6
+ *
7
+ * Credentials come from env vars (never hardcode them):
8
+ * ASC_KEY_ID - 10-char API key ID (from the AuthKey_<KEY_ID>.p8 filename)
9
+ * ASC_ISSUER_ID - team issuer UUID (App Store Connect > Users and Access > Integrations)
10
+ * ASC_P8_PATH - absolute path to the AuthKey_*.p8 private key file
11
+ *
12
+ * Usage:
13
+ * node scripts/asc-api.mjs GET "/v1/apps?filter[bundleId]=com.example.app"
14
+ * node scripts/asc-api.mjs POST /v1/betaGroups body.json
15
+ * node scripts/asc-api.mjs DELETE /v1/profiles/<id>
16
+ *
17
+ * Prints {"status": <http status>, "body": <json|null>} on stdout.
18
+ * Exits non-zero on HTTP >= 400 so shell scripts can chain safely.
19
+ */
20
+ import crypto from "node:crypto";
21
+ import fs from "node:fs";
22
+
23
+ const KEY_ID = process.env.ASC_KEY_ID;
24
+ const ISSUER_ID = process.env.ASC_ISSUER_ID;
25
+ const P8_PATH = process.env.ASC_P8_PATH;
26
+
27
+ if (!KEY_ID || !ISSUER_ID || !P8_PATH) {
28
+ console.error(
29
+ "Missing credentials. Set ASC_KEY_ID, ASC_ISSUER_ID, and ASC_P8_PATH env vars.\n" +
30
+ "Key ID is in the .p8 filename (AuthKey_<KEY_ID>.p8); issuer ID is in\n" +
31
+ "App Store Connect > Users and Access > Integrations > App Store Connect API.",
32
+ );
33
+ process.exit(2);
34
+ }
35
+ if (!fs.existsSync(P8_PATH)) {
36
+ console.error(`ASC_P8_PATH not found: ${P8_PATH}`);
37
+ process.exit(2);
38
+ }
39
+
40
+ const b64url = (buf) =>
41
+ Buffer.from(buf)
42
+ .toString("base64")
43
+ .replace(/=/g, "")
44
+ .replace(/\+/g, "-")
45
+ .replace(/\//g, "_");
46
+
47
+ function makeJwt() {
48
+ const header = { alg: "ES256", kid: KEY_ID, typ: "JWT" };
49
+ const now = Math.floor(Date.now() / 1000);
50
+ const payload = {
51
+ iss: ISSUER_ID,
52
+ iat: now,
53
+ exp: now + 900,
54
+ aud: "appstoreconnect-v1",
55
+ };
56
+ const signingInput = `${b64url(JSON.stringify(header))}.${b64url(JSON.stringify(payload))}`;
57
+ const key = crypto.createPrivateKey(fs.readFileSync(P8_PATH, "utf8"));
58
+ const sig = crypto.sign("sha256", Buffer.from(signingInput), {
59
+ key,
60
+ dsaEncoding: "ieee-p1363",
61
+ });
62
+ return `${signingInput}.${b64url(sig)}`;
63
+ }
64
+
65
+ const [method, apiPath, bodyFile] = process.argv.slice(2);
66
+ if (!method || !apiPath) {
67
+ console.error("usage: asc-api.mjs <GET|POST|PATCH|DELETE> </v1/...> [bodyFile.json]");
68
+ process.exit(2);
69
+ }
70
+
71
+ const res = await fetch(`https://api.appstoreconnect.apple.com${encodeURI(apiPath)}`, {
72
+ method: method.toUpperCase(),
73
+ headers: {
74
+ Authorization: `Bearer ${makeJwt()}`,
75
+ "Content-Type": "application/json",
76
+ },
77
+ body: bodyFile ? fs.readFileSync(bodyFile, "utf8") : undefined,
78
+ });
79
+
80
+ const text = await res.text();
81
+ let body = null;
82
+ try {
83
+ body = text ? JSON.parse(text) : null;
84
+ } catch {
85
+ body = { raw: text.slice(0, 2000) };
86
+ }
87
+ console.log(JSON.stringify({ status: res.status, body }, null, 2));
88
+ if (res.status >= 400) process.exit(1);
@@ -0,0 +1,159 @@
1
+ ---
2
+ name: appstore-connect-setup
3
+ description: Find and configure App Store Connect API credentials for asc auth. Use when asc auth is missing, credentials are unknown, the user says login to App Store Connect, or before TestFlight/App Store release work.
4
+ ---
5
+
6
+ # App Store Connect Setup
7
+
8
+ <objective>
9
+ `asc auth login` needs three things: a **key ID**, an **issuer ID**, and a **.p8 private key file**. Users rarely remember where these are. This skill is a battle-tested workflow for finding all three without asking the user to dig through App Store Connect manually.
10
+
11
+ Key insight from a real session: the `.p8` files and key IDs live on disk, but the **issuer ID is almost never stored locally** — it only exists in the App Store Connect web UI. The trick is to read it from the user's already-signed-in browser session via CDP, since Apple login requires 2FA and cannot be automated.
12
+ </objective>
13
+
14
+ <credentials_anatomy>
15
+ | Credential | What it looks like | Where it lives |
16
+ | --- | --- | --- |
17
+ | Key ID | 10 chars, e.g. `T397KWC8K7` | In the `.p8` filename: `AuthKey_<KEY_ID>.p8` |
18
+ | Issuer ID | UUID, e.g. `35b197bd-...` | App Store Connect → Users and Access → Integrations → App Store Connect API (top of Keys page). Team-level, same for all keys. |
19
+ | Private key | `AuthKey_*.p8` file, ~257 bytes | User's disk — Downloads is the most common spot (Apple only lets you download it once) |
20
+
21
+ Beware look-alikes that are NOT API auth keys:
22
+ - `SubscriptionKey_*.p8` — in-app purchase key, won't work for `asc auth login`.
23
+ - `.p8` files for APNs (push notifications).
24
+ </credentials_anatomy>
25
+
26
+ <step n="1" title="Check if already authenticated">
27
+
28
+ ```bash
29
+ asc auth status --validate
30
+ ```
31
+
32
+ If a credential validates as "works", stop — nothing to do.
33
+ </step>
34
+
35
+ <step n="2" title="Hunt for .p8 files on disk">
36
+
37
+ ```bash
38
+ # Standard locations first
39
+ ls ~/.asc ~/private_keys ~/.appstoreconnect/private_keys 2>/dev/null
40
+
41
+ # Then the places people actually put them (Downloads wins in practice)
42
+ find ~/Downloads ~/Documents ~/Desktop ~/Developer -maxdepth 5 -name "*.p8" 2>/dev/null
43
+ ```
44
+
45
+ Real finding: keys were in `~/Downloads/AuthKey_X.p8` and `~/Downloads/Dev/AuthKey_Y.p8`, downloaded months earlier. The key ID is the filename suffix.
46
+ </step>
47
+
48
+ <step n="3" title="Try to find the issuer ID locally (usually fails)">
49
+
50
+ Worth 30 seconds, but expect nothing:
51
+
52
+ ```bash
53
+ grep -riE "issuer" ~/Developer --include="*.json" --include="*.env*" --include="*.rb" --include="*.yml" -l 2>/dev/null | grep -v node_modules
54
+ grep -iE "issuer" ~/.zsh_history 2>/dev/null
55
+ grep -ri "issuer" ~/.fastlane ~/.expo 2>/dev/null
56
+ ```
57
+
58
+ Real finding: zero hits across the entire `~/Developer` tree, shell history, fastlane and expo config. Docs in repos only contain `ISSUER_ID` placeholders. **Do not burn time here — go to step 4.**
59
+ </step>
60
+
61
+ <step n="4" title="Read the issuer ID from the user's signed-in browser (the key move)">
62
+
63
+ Apple login = password + 2FA, so never try to log in yourself. Instead, attach to the browser where the user is **already signed in** and read the page.
64
+
65
+ **4a. Confirm with the user** which browser is signed in to App Store Connect (Chrome, Helium, etc.).
66
+
67
+ **4b. Check if the browser exposes CDP:**
68
+
69
+ ```bash
70
+ curl -s http://127.0.0.1:9222/json/version # Chrome default
71
+ curl -s http://127.0.0.1:9334/json/version # custom port
72
+ ```
73
+
74
+ **4c. If not (the usual case), quit and relaunch it with a debug port.** Session cookies survive a graceful quit, and `--restore-last-session` brings the tabs back:
75
+
76
+ ```bash
77
+ osascript -e 'quit app "Helium"' # or "Google Chrome"
78
+ sleep 3
79
+ nohup "/Applications/Helium.app/Contents/MacOS/Helium" --remote-debugging-port=9334 --restore-last-session >/dev/null 2>&1 &
80
+ sleep 5
81
+ curl -s http://127.0.0.1:9334/json/version | head -3 # must answer before continuing
82
+ ```
83
+
84
+ **4d. Navigate to the API keys page and extract the issuer ID:**
85
+
86
+ ```bash
87
+ dev-browser --browser helium --connect http://127.0.0.1:9334 --timeout 60 <<'EOF'
88
+ const page = await browser.getPage("asc");
89
+ await page.goto("https://appstoreconnect.apple.com/access/integrations/api", { waitUntil: "domcontentloaded" });
90
+ await page.waitForTimeout(8000);
91
+ const text = await page.evaluate(() => document.body.innerText);
92
+ const m = text.match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i);
93
+ console.log(JSON.stringify({ issuerId: m ? m[1] : null, loggedOut: page.url().includes("/login") }));
94
+ EOF
95
+ ```
96
+
97
+ If `loggedOut` is true, ask the user to sign in in that browser window, then re-run.
98
+
99
+ **4e. Cross-check which keys are actually ACTIVE.** The same page lists active keys with their key IDs. A `.p8` found on disk may belong to a revoked key — match the filename key ID against the active list before using it:
100
+
101
+ ```bash
102
+ dev-browser --browser helium --connect http://127.0.0.1:9334 --timeout 30 <<'EOF'
103
+ const page = await browser.getPage("asc");
104
+ const text = await page.evaluate(() => document.body.innerText);
105
+ console.log(text); // active keys table: NAME / KEY ID / LAST USED / ACCESS
106
+ EOF
107
+ ```
108
+
109
+ Real finding: the first `.p8` we picked (`AuthKey_6QD5RMPU9F.p8`) was NOT in the active list — login would have failed. The second one matched an active Admin key and worked.
110
+ </step>
111
+
112
+ <step n="5" title="Organize keys, then log in">
113
+
114
+ Move keys to the canonical folder so the next agent finds them instantly:
115
+
116
+ ```bash
117
+ mkdir -p ~/Developer/app-store
118
+ mv ~/Downloads/AuthKey_*.p8 ~/Developer/app-store/ 2>/dev/null
119
+ chmod 600 ~/Developer/app-store/*.p8
120
+ ```
121
+
122
+ Then authenticate and verify end-to-end.
123
+
124
+ **Naming the credential:** use a stable, descriptive name tied to the machine + user, not the app — the same ASC API key is team-level and works across every app, so naming it per-app is misleading. Convention: `asc-macos-<user>-key` (e.g. `asc-macos-melvynx-key`). **Prefer a key with Admin access** when several active keys exist (Admin can read/write everything the release flow needs); check the ACCESS column from step 4e and pick the Admin key.
125
+
126
+ ```bash
127
+ asc auth login \
128
+ --name "asc-macos-melvynx-key" \
129
+ --key-id "KEY_ID" \
130
+ --issuer-id "ISSUER_ID" \
131
+ --private-key ~/Developer/app-store/AuthKey_KEY_ID.p8 \
132
+ --network
133
+
134
+ asc auth status --validate # must report "works"
135
+ asc apps list # must list the target app
136
+ ```
137
+ </step>
138
+
139
+ <step n="6" title="Persist the findings">
140
+
141
+ Record in the agent memory / AGENTS.md so this hunt never happens twice:
142
+
143
+ - The keys folder (`~/Developer/app-store/`), each key ID and whether it is active
144
+ - The issuer ID (team-level, stable)
145
+ - The `asc` credential name (convention `asc-macos-<user>-key`), its access level (prefer Admin), and that it is stored in the system keychain
146
+ - The app's numeric App Store Connect ID and bundle ID from `asc apps list`
147
+ </step>
148
+
149
+ <critical_safety>
150
+ - Never commit `.p8` files or paste their contents anywhere. `chmod 600` them.
151
+ - Never attempt the Apple login form yourself — 2FA makes it pointless and looks like account takeover. Always reuse the user's signed-in session, with their explicit OK to attach to/restart their browser.
152
+ - Restarting the browser closes the user's windows; warn them and rely on session restore.
153
+ </critical_safety>
154
+
155
+ <success_criteria>
156
+ - `asc auth status --validate` reports the credential as "works".
157
+ - `asc apps list` returns the expected app(s).
158
+ - Keys live in `~/Developer/app-store/` and the findings are written to memory/AGENTS.md.
159
+ </success_criteria>
@@ -1,6 +1,7 @@
1
1
  ---
2
+ name: create-vitejs-app
2
3
  description: Create a Vite.js app with Tailwind CSS v4 and shadcn/ui in the current directory
3
- argument-hint: [template]
4
+ argument-hint: "[template]"
4
5
  ---
5
6
 
6
7
  <objective>
@@ -235,7 +235,7 @@ python3 -c "import json; json.load(open('.claude/settings.json'))"
235
235
 
236
236
  After the shared scripts are written, for each IDE selected in Step 2, load the matching reference file and apply only its linking config:
237
237
 
238
- - **Claude Code** → [references/claude.md](references/claude.md) - `.claude/settings.json` SessionStart hook + custom slash commands as actions.
238
+ - **Claude Code** → [references/claude.md](references/claude.md) - `.claude/settings.json` worktree hooks + optional project action skills.
239
239
  - **Cursor** → [references/cursor.md](references/cursor.md) - `.cursor/worktrees.json` setup keys.
240
240
  - **Codex** → [references/codex.md](references/codex.md) - `.codex/environments/environment.toml` setup, cleanup, and actions.
241
241
 
@@ -256,11 +256,11 @@ examples/
256
256
  ├── claude/
257
257
  │ ├── .worktreeinclude # native env-file copy list
258
258
  │ ├── settings.json # WorktreeCreate + WorktreeRemove hooks
259
- │ └── commands/ # optional slash-command actions
260
- ├── dev.md
261
- ├── typecheck.md
262
- ├── test.md
263
- └── lint.md
259
+ ├── skills/ # optional project action skills
260
+ ├── dev/SKILL.md
261
+ ├── typecheck/SKILL.md
262
+ ├── test/SKILL.md
263
+ └── lint/SKILL.md
264
264
  ├── cursor/
265
265
  │ └── worktrees.json # setup-worktree-unix -> scripts/worktree-up.sh
266
266
  └── codex/
@@ -1,5 +1,6 @@
1
1
  ---
2
- description: Start the dev server on a free port
2
+ name: dev
3
+ description: Start the dev server on a free port for this project.
3
4
  ---
4
5
 
5
6
  Run `scripts/dev.sh` from the project root. Stream output until the dev server is listening, then return the URL.
@@ -1,5 +1,6 @@
1
1
  ---
2
- description: Run the linter
2
+ name: lint
3
+ description: Run the linter for this project and report violations.
3
4
  ---
4
5
 
5
6
  Run the project's lint command (`pnpm lint:ci`, `bun run lint`, or equivalent). Report any violations.
@@ -1,5 +1,6 @@
1
1
  ---
2
- description: Run unit tests
2
+ name: test
3
+ description: Run unit tests for this project and summarize failures.
3
4
  ---
4
5
 
5
6
  Run the project's unit test command (`pnpm test:ci`, `bun test`, or equivalent). Report failures with file:line references.
@@ -1,5 +1,6 @@
1
1
  ---
2
- description: Typecheck the project
2
+ name: typecheck
3
+ description: Typecheck this project and report errors with file references.
3
4
  ---
4
5
 
5
6
  Run the project's typecheck command (`pnpm ts`, `bun run typecheck`, or equivalent based on the lockfile). Report any errors with file:line references.
@@ -25,12 +25,13 @@ There is no separate `PostWorktreeCreate` hook (feature request #27744 is open).
25
25
  ```text
26
26
  .worktreeinclude # gitignore-syntax list of files to auto-copy
27
27
  .claude/
28
- ├── settings.json # WorktreeCreate + WorktreeRemove hooks
29
- └── commands/ # optional: per-action slash commands
30
- ├── dev.md
31
- ├── typecheck.md
32
- ├── test.md
33
- └── lint.md
28
+ └── settings.json # WorktreeCreate + WorktreeRemove hooks
29
+ .agents/
30
+ └── skills/ # optional: per-action project skills
31
+ ├── dev/SKILL.md
32
+ ├── typecheck/SKILL.md
33
+ ├── test/SKILL.md
34
+ └── lint/SKILL.md
34
35
  scripts/
35
36
  ├── claude-worktree-create.sh # WorktreeCreate hook wrapper
36
37
  ├── claude-worktree-remove.sh # WorktreeRemove hook wrapper
@@ -123,11 +124,14 @@ The `WorktreeCreate` hook **only fires for `claude --worktree` from the CLI**. T
123
124
 
124
125
  Also: **`.claude/settings.json` changes only take effect after restarting Claude.** A running session keeps the old hook config. Tell the user to restart before testing.
125
126
 
126
- ## Custom Slash Commands as Actions (optional)
127
+ ## Project Action Skills (optional)
127
128
 
128
- Claude Code does not have a top-bar action menu. To expose the standard actions, write one file per action under `.claude/commands/`. Each is a tiny prompt that tells Claude to run the matching shared script or package-manager command.
129
+ To expose standard project actions consistently, write one skill per action
130
+ under `.agents/skills/<name>/SKILL.md`. Each skill tells the agent to run the
131
+ matching shared script or package-manager command.
129
132
 
130
- See `examples/claude/commands/` for the four standard ones (`dev.md`, `typecheck.md`, `test.md`, `lint.md`).
133
+ See `examples/skills/` for the four standard ones (`dev`, `typecheck`, `test`,
134
+ `lint`).
131
135
 
132
136
  ## Guardrails
133
137
 
@@ -14,7 +14,7 @@ Three setup keys are supported (Cursor picks the first one that matches the host
14
14
 
15
15
  Cursor does **not** support a cleanup script. Cleanup is timer-based via global settings (`cursor.worktreeCleanupIntervalHours`, `cursor.worktreeMaxCount`). To get a real cleanup hook, expose `scripts/worktree-down.sh` as a project command the user runs manually before `/delete-worktree`.
16
16
 
17
- Built-in worktree slash commands the user already has: `/worktree`, `/best-of-n`, `/apply-worktree`, `/delete-worktree`.
17
+ Cursor includes built-in worktree actions for creating, comparing, applying, and deleting worktrees.
18
18
 
19
19
  ## Environment Variables
20
20
 
@@ -72,7 +72,7 @@ Inline is fine for two-line setups. For anything more, use a script - the worktr
72
72
 
73
73
  - Do not put fragile multi-line setup inline. If it does not fit in two clean array entries, call the script.
74
74
  - Do not put `.cursor/worktrees.json` only in a worktree - it must be on the source checkout / main branch so future worktrees pick it up.
75
- - Do not rely on a cleanup hook - Cursor does not have one. Tell the user to run `scripts/worktree-down.sh` before `/delete-worktree`, or document it in the project README.
75
+ - Do not rely on a cleanup hook - Cursor does not have one. Tell the user to run `scripts/worktree-down.sh` before deleting a worktree, or document it in the project README.
76
76
  - Do not use `$CURSOR_WORKTREE_PATH` - that variable is not documented and not guaranteed. Use `pwd` inside the worktree.
77
77
 
78
78
  ## Verification