vibebusiness 1.2.80 → 1.2.83
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/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-build-manifest.json +31 -31
- package/.next/standalone/.next/app-path-routes-manifest.json +1 -1
- package/.next/standalone/.next/build-manifest.json +2 -2
- package/.next/standalone/.next/prerender-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
- package/.next/standalone/.next/server/app/api/analyze/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/config/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/epics/[id]/ideas/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/epics/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/epics/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/goals/[id]/kpis/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/goals/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/goals/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/hypotheses/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/hypotheses/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[id]/card/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[id]/comments/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[id]/implement/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[id]/transition/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[id]/transition/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/implementations/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/kpis/refresh/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/social/[id]/publish/route.js +1 -1
- package/.next/standalone/.next/server/app/api/social/[id]/publish/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/social/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/social/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/goals/[id]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/goals/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/goals/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/hypotheses/[id]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/hypotheses/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/hypotheses/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/ideas/[id]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/ideas/[id]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/roadmap/[id]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/roadmap/investors/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/roadmap/investors/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/roadmap/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/roadmap/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/roadmap/public/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/roadmap/public/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/sessions/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings.html +1 -1
- package/.next/standalone/.next/server/app/settings.rsc +1 -1
- package/.next/standalone/.next/server/app/social/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/social.html +1 -1
- package/.next/standalone/.next/server/app/social.rsc +2 -2
- package/.next/standalone/.next/server/app/updates/[id]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/updates/[id]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/updates/new/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/updates/new.html +1 -1
- package/.next/standalone/.next/server/app/updates/new.rsc +2 -2
- package/.next/standalone/.next/server/app/updates/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/updates/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +21 -21
- package/.next/standalone/.next/server/chunks/{3794.js → 7151.js} +27 -27
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/data/business-context.json +1 -1
- package/.next/standalone/data/heartbeat-sessions.json +228 -0
- package/.next/standalone/data/ideas.json +510 -34
- package/.next/standalone/data/implementations.json +129 -0
- package/.next/standalone/data/videos/staging/while-you-slept-demo.json +66 -0
- package/.next/standalone/data/videos/while-you-slept-demo-feed.mp4 +0 -0
- package/.next/standalone/node_modules/.cache/webpack/remotion-production-4.0.428/c99d23d3548030c8ff8de678c71eeb15/0.pack +0 -0
- package/.next/standalone/node_modules/.cache/webpack/remotion-production-4.0.428/c99d23d3548030c8ff8de678c71eeb15/1.pack +0 -0
- package/.next/standalone/node_modules/.cache/webpack/remotion-production-4.0.428/c99d23d3548030c8ff8de678c71eeb15/2.pack +0 -0
- package/.next/standalone/node_modules/.cache/webpack/remotion-production-4.0.428/c99d23d3548030c8ff8de678c71eeb15/index.pack +0 -0
- package/.next/standalone/node_modules/.cache/webpack/remotion-production-4.0.428/c99d23d3548030c8ff8de678c71eeb15/index.pack.old +0 -0
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/scripts/analyze.ts +1 -15
- package/.next/standalone/templates/commands/build-page.md +163 -0
- package/.next/standalone/templates/commands/email-marketing.md +339 -0
- package/.next/standalone/templates/commands/growth-audit.md +85 -0
- package/.next/standalone/templates/commands/launch-campaign.md +84 -0
- package/.next/standalone/templates/commands/manage.md +147 -0
- package/.next/standalone/templates/commands/measure-page.md +89 -0
- package/.next/standalone/templates/commands/positioning.md +128 -0
- package/.next/standalone/templates/commands/pricing-analysis.md +91 -0
- package/.next/standalone/templates/commands/promo-copy.md +186 -0
- package/.next/standalone/templates/commands/promo-video.md +75 -0
- package/.next/standalone/templates/commands/research-competitors.md +124 -0
- package/.next/standalone/templates/commands/setup-payments.md +107 -0
- package/.next/standalone/templates/commands/setup-posthog.md +116 -0
- package/.next/standalone/templates/commands/social-media.md +47 -0
- package/.next/standalone/templates/commands/status-summary.md +103 -0
- package/.next/standalone/templates/commands/validate-idea.md +102 -0
- package/.next/standalone/templates/emails/__tests__/validate-templates.test.ts +147 -0
- package/.next/standalone/templates/emails/day3-activation-feedback.txt +14 -0
- package/.next/standalone/templates/emails/day30-pmf-feedback.txt +19 -0
- package/.next/static/chunks/429-8f4030371ebef5c3.js +1 -0
- package/.next/static/chunks/827-6cf4bfc10d1ff0c7.js +1 -0
- package/.next/static/chunks/app/goals/[id]/page-231bb4daae0f06eb.js +1 -0
- package/.next/static/chunks/app/ideas/[id]/page-b3dfe1e61fc656a4.js +1 -0
- package/.next/static/chunks/app/roadmap/[id]/page-b93a96f017c8d3dd.js +1 -0
- package/.next/static/chunks/app/social/page-5211c78a5f37df65.js +1 -0
- package/.next/static/chunks/app/updates/new/page-dcc67ffca587dcc2.js +1 -0
- package/.next/static/css/654766eb547c6bab.css +3 -0
- package/dist/scripts/analyze.js +1 -14
- package/dist/scripts/heartbeat.js +224 -130
- package/package.json +1 -1
- package/scripts/lib/video/compositions/DemoVideo.tsx +425 -0
- package/scripts/lib/video/compositions/Root.tsx +24 -1
- package/.next/static/chunks/429-c3cc9856a8a9d0d4.js +0 -1
- package/.next/static/chunks/827-d5a9d09b31d7eb1c.js +0 -1
- package/.next/static/chunks/app/goals/[id]/page-7a60dffb8ee860ed.js +0 -1
- package/.next/static/chunks/app/ideas/[id]/page-565f78e223048e74.js +0 -1
- package/.next/static/chunks/app/roadmap/[id]/page-54f51490662106f5.js +0 -1
- package/.next/static/chunks/app/social/page-574752c4e67413de.js +0 -1
- package/.next/static/chunks/app/updates/new/page-c5da11133140a7f4.js +0 -1
- package/.next/static/css/ba6f5fe78931fee2.css +0 -3
- /package/.next/static/{9C8sbF668J83TlKDjSvQm → wJT1h-ifHTtYVlXZG2PFS}/_buildManifest.js +0 -0
- /package/.next/static/{9C8sbF668J83TlKDjSvQm → wJT1h-ifHTtYVlXZG2PFS}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# /setup-payments — Stripe Payment Integration Wizard
|
|
2
|
+
|
|
3
|
+
## Usage
|
|
4
|
+
```
|
|
5
|
+
/setup-payments # Full setup wizard (detect framework → install SDK → validate key → create products → generate code)
|
|
6
|
+
/setup-payments checkout # Generate only checkout session endpoint
|
|
7
|
+
/setup-payments webhook # Generate only webhook handler
|
|
8
|
+
/setup-payments portal # Generate only customer portal redirect
|
|
9
|
+
/setup-payments status # Check integration completeness
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Input
|
|
13
|
+
- `$ARGUMENTS` — optional: one of the modes above (defaults to full setup)
|
|
14
|
+
|
|
15
|
+
## Process
|
|
16
|
+
|
|
17
|
+
Parse `$ARGUMENTS` to determine mode. If empty or "setup", run the full wizard.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
### Mode: Full Setup (default)
|
|
22
|
+
|
|
23
|
+
Runs the complete Stripe integration wizard:
|
|
24
|
+
|
|
25
|
+
1. **Detect Framework**: Reads `package.json` to identify Next.js (App/Pages Router), Express, Fastify, Remix, or generic Node.js. Checks for TypeScript and `src/` directory.
|
|
26
|
+
|
|
27
|
+
2. **Install Stripe SDK**: If `stripe` is not in `node_modules`, runs `npm install stripe`.
|
|
28
|
+
|
|
29
|
+
3. **Validate API Key**: Reads `STRIPE_SECRET_KEY` from `.env` or environment. Calls `stripe.accounts.retrieve()` to validate.
|
|
30
|
+
- If missing: prints instructions to add it and stops.
|
|
31
|
+
- If invalid: prints error and stops.
|
|
32
|
+
|
|
33
|
+
4. **Create Products**: Searches for existing products to avoid duplicates. If none found, creates a default "Pro Plan" ($29/mo).
|
|
34
|
+
|
|
35
|
+
5. **Generate Code**: Creates framework-appropriate files:
|
|
36
|
+
- Checkout session endpoint
|
|
37
|
+
- Webhook handler (with `constructEvent` signature verification)
|
|
38
|
+
- Customer portal redirect
|
|
39
|
+
- Checkout button component (Next.js only)
|
|
40
|
+
- **Never overwrites existing files** — skips with a warning.
|
|
41
|
+
|
|
42
|
+
6. **Update .env**: Appends `STRIPE_SECRET_KEY` and `STRIPE_WEBHOOK_SECRET` if not present. Ensures `.env` is in `.gitignore`.
|
|
43
|
+
|
|
44
|
+
7. **Save State**: Writes integration status to `data/payments.json`.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### Mode: `checkout`
|
|
49
|
+
|
|
50
|
+
Generates only the checkout session creation endpoint for the detected framework.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
### Mode: `webhook`
|
|
55
|
+
|
|
56
|
+
Generates only the webhook handler with Stripe signature verification.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
### Mode: `portal`
|
|
61
|
+
|
|
62
|
+
Generates only the customer portal redirect endpoint.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
### Mode: `status`
|
|
67
|
+
|
|
68
|
+
Audits the current integration:
|
|
69
|
+
- Is Stripe SDK installed?
|
|
70
|
+
- Is the API key valid?
|
|
71
|
+
- Do products exist in Stripe?
|
|
72
|
+
- Are checkout/webhook/portal endpoints generated?
|
|
73
|
+
- Is the webhook secret configured?
|
|
74
|
+
|
|
75
|
+
Reports completeness as a percentage.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## State File
|
|
80
|
+
|
|
81
|
+
`data/payments.json` tracks:
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"last_updated": "2025-01-15T...",
|
|
85
|
+
"integration_status": {
|
|
86
|
+
"sdk_installed": true,
|
|
87
|
+
"api_key_valid": true,
|
|
88
|
+
"products_created": true,
|
|
89
|
+
"checkout_endpoint": true,
|
|
90
|
+
"webhook_endpoint": true,
|
|
91
|
+
"portal_endpoint": false
|
|
92
|
+
},
|
|
93
|
+
"framework": { "framework": "nextjs", "typescript": true, "appRouter": true, "srcDir": true },
|
|
94
|
+
"products": [
|
|
95
|
+
{ "name": "Pro Plan", "stripe_product_id": "prod_...", "stripe_price_id": "price_...", "amount_cents": 2900, "currency": "usd", "interval": "month" }
|
|
96
|
+
],
|
|
97
|
+
"generated_files": ["src/app/api/checkout/route.ts", "src/app/api/webhook/route.ts"]
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Error Handling
|
|
102
|
+
|
|
103
|
+
- Missing `STRIPE_SECRET_KEY` → return instructions to add it to `.env`
|
|
104
|
+
- Invalid key → return `success: false` with "check your key" message
|
|
105
|
+
- Products already exist → skip creation, use existing IDs
|
|
106
|
+
- Target file exists → skip with warning (don't overwrite user code)
|
|
107
|
+
- Framework not detected → fall back to generic Node.js templates
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# /setup-posthog — PostHog Analytics Integration Wizard
|
|
2
|
+
|
|
3
|
+
## Usage
|
|
4
|
+
```
|
|
5
|
+
/setup-posthog # Full setup (detect → install → validate → generate → configure KPI adapter → suggest events)
|
|
6
|
+
/setup-posthog provider # Generate only PostHogProvider + pageview tracker
|
|
7
|
+
/setup-posthog events # Generate only event tracking helper
|
|
8
|
+
/setup-posthog status # Check integration completeness
|
|
9
|
+
/setup-posthog connect-kpis # Scan codebase for events, map them to KPIs
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Input
|
|
13
|
+
- `$ARGUMENTS` — optional: one of the modes above (defaults to full setup)
|
|
14
|
+
|
|
15
|
+
## Process
|
|
16
|
+
|
|
17
|
+
Parse `$ARGUMENTS` to determine mode. If empty or "setup", run the full wizard.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
### Mode: Full Setup (default)
|
|
22
|
+
|
|
23
|
+
Runs the complete PostHog analytics integration wizard:
|
|
24
|
+
|
|
25
|
+
1. **Detect Framework**: Reads `package.json` to identify Next.js (App/Pages Router), Express, Fastify, Remix, or generic Node.js. Checks for TypeScript and `src/` directory.
|
|
26
|
+
|
|
27
|
+
2. **Install SDK**: If `posthog-js` is not in `node_modules`, runs `npm install posthog-js`. For non-Next.js frameworks, also installs `posthog-node`.
|
|
28
|
+
|
|
29
|
+
3. **Validate API Key**: Reads `NEXT_PUBLIC_POSTHOG_KEY` (Next.js) or `POSTHOG_API_KEY` (other) from `.env` or environment. Validates key format (must start with `phc_`).
|
|
30
|
+
- If missing: prints instructions to add it and continues (key can be added later).
|
|
31
|
+
- If invalid format: prints warning.
|
|
32
|
+
- If valid: calls PostHog API to verify the key works.
|
|
33
|
+
|
|
34
|
+
4. **Generate Tracking Code**: Creates framework-appropriate files:
|
|
35
|
+
- **Next.js App Router**: `PostHogProvider.tsx`, `PostHogPageview.tsx`, `posthog-events.ts`
|
|
36
|
+
- **Next.js Pages Router**: `lib/posthog.ts`, `_app.tsx` integration instructions
|
|
37
|
+
- **Generic (Express, etc.)**: `lib/posthog.ts` (posthog-node client)
|
|
38
|
+
- **Never overwrites existing files** — skips with a warning.
|
|
39
|
+
|
|
40
|
+
5. **Update .env**: Appends PostHog key and host variables if not present. Ensures `.env` is in `.gitignore`.
|
|
41
|
+
|
|
42
|
+
6. **Configure KPI Adapter**: Adds a `posthog` adapter entry to `data/business-context.json` so the KPI dashboard can pull metrics from PostHog. Skips if already configured.
|
|
43
|
+
|
|
44
|
+
7. **Suggest Starter Events**: Recommends framework-specific events to track (e.g., `signed_up`, `feature_used`, `upgrade_clicked`, `cta_clicked`). Provides code snippets for adding them.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### Mode: `provider`
|
|
49
|
+
|
|
50
|
+
Generates only the PostHogProvider component and pageview tracker for the detected framework. Useful if you already have the SDK installed and key configured but need the React components.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
### Mode: `events`
|
|
55
|
+
|
|
56
|
+
Generates only the event tracking helper file (`posthog-events.ts` or `lib/posthog.ts`). Useful for adding typed event tracking to an existing PostHog setup.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
### Mode: `status`
|
|
61
|
+
|
|
62
|
+
Audits the current integration:
|
|
63
|
+
- Is PostHog SDK installed?
|
|
64
|
+
- Is the API key configured?
|
|
65
|
+
- Is the key format valid?
|
|
66
|
+
- Are generated files present (Provider, Pageview, events helper)?
|
|
67
|
+
- Is the KPI adapter configured in business-context.json?
|
|
68
|
+
|
|
69
|
+
Reports completeness as a percentage.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
### Mode: `connect-kpis`
|
|
74
|
+
|
|
75
|
+
Scans the user's codebase for PostHog event calls and maps them to KPIs:
|
|
76
|
+
|
|
77
|
+
1. **Find Events**: Searches for `posthog.capture('...')`, `trackEvent('...')`, and `client.capture({ event: '...' })` patterns across `.ts`, `.tsx`, `.js`, `.jsx` files. Ignores `node_modules`, `dist`, and `$`-prefixed internal events.
|
|
78
|
+
|
|
79
|
+
2. **Read Existing KPIs**: Loads KPI definitions from `data/goals.json`.
|
|
80
|
+
|
|
81
|
+
3. **Generate Mappings**: Creates `kpi-{event-name}` → `event_name` field mappings.
|
|
82
|
+
|
|
83
|
+
4. **Update Adapter**: Writes the field mappings to the PostHog adapter in `data/business-context.json`. Creates the adapter if it doesn't exist.
|
|
84
|
+
|
|
85
|
+
5. **Report**: Lists detected events, existing KPIs, and suggested mappings.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## State File
|
|
90
|
+
|
|
91
|
+
`data/posthog.json` tracks:
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"last_updated": "2026-01-15T...",
|
|
95
|
+
"integration_status": {
|
|
96
|
+
"sdk_installed": true,
|
|
97
|
+
"api_key_valid": true,
|
|
98
|
+
"provider_generated": true,
|
|
99
|
+
"pageview_tracker": true,
|
|
100
|
+
"event_helper": false
|
|
101
|
+
},
|
|
102
|
+
"framework": { "framework": "nextjs", "typescript": true, "appRouter": true, "srcDir": true },
|
|
103
|
+
"generated_files": ["src/components/PostHogProvider.tsx", "src/components/PostHogPageview.tsx"]
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Error Handling
|
|
108
|
+
|
|
109
|
+
- Missing `NEXT_PUBLIC_POSTHOG_KEY` → prints instructions to add it to `.env`, continues setup
|
|
110
|
+
- Invalid key format (not `phc_...`) → prints warning, continues
|
|
111
|
+
- API key validation fails → prints error, continues (key can be fixed later)
|
|
112
|
+
- SDK install fails → returns failure with manual install instructions
|
|
113
|
+
- Target file already exists → skips with warning (never overwrites user code)
|
|
114
|
+
- Framework not detected → falls back to generic Node.js templates
|
|
115
|
+
- `business-context.json` missing → skips KPI adapter step with hint to run `vibebusiness init`
|
|
116
|
+
- No PostHog events found in codebase → reports zero and suggests running `posthog-setup` first
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Social Media — Twitter/X Build-in-Public
|
|
2
|
+
|
|
3
|
+
Run social media tasks for your project. This skill manages Twitter/X tweet drafts in a draft-then-confirm workflow.
|
|
4
|
+
|
|
5
|
+
## Available actions: $ARGUMENTS
|
|
6
|
+
|
|
7
|
+
### Setup
|
|
8
|
+
```
|
|
9
|
+
social-setup-x
|
|
10
|
+
```
|
|
11
|
+
Validates X API credentials from .env and saves the connected username.
|
|
12
|
+
|
|
13
|
+
### Generate Drafts
|
|
14
|
+
```
|
|
15
|
+
social-draft-ship # Tweet about the most recently shipped feature
|
|
16
|
+
social-draft-update # Product update from positioning data
|
|
17
|
+
social-draft-milestone # Celebrate a KPI that hit its target
|
|
18
|
+
social-draft-digest # Weekly recap of activity
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Check Status
|
|
22
|
+
```
|
|
23
|
+
social-check-status # Audit credentials, draft count, post streak
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Instructions
|
|
27
|
+
|
|
28
|
+
1. Read `data/social.json` to understand current state
|
|
29
|
+
2. Based on the user's request ($ARGUMENTS), execute the appropriate task by running:
|
|
30
|
+
```
|
|
31
|
+
npx tsx scripts/heartbeat.ts --execute-task <task-id>
|
|
32
|
+
```
|
|
33
|
+
Or if that flag doesn't exist, call the skill directly:
|
|
34
|
+
```typescript
|
|
35
|
+
import { executeSocialTask } from './scripts/skills/social-media';
|
|
36
|
+
const result = await executeSocialTask('<task-id>', '<description>');
|
|
37
|
+
```
|
|
38
|
+
3. Report the result back to the user
|
|
39
|
+
4. If generating drafts, remind the user they can review and publish from the /social dashboard
|
|
40
|
+
|
|
41
|
+
## Environment Variables Required
|
|
42
|
+
- `X_API_KEY` — Consumer API key
|
|
43
|
+
- `X_API_SECRET` — Consumer API secret
|
|
44
|
+
- `X_ACCESS_TOKEN` — User access token
|
|
45
|
+
- `X_ACCESS_SECRET` — User access token secret
|
|
46
|
+
|
|
47
|
+
Get these at https://developer.x.com/en/portal/dashboard
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# /status-summary — State Overview Dashboard
|
|
2
|
+
|
|
3
|
+
## Usage
|
|
4
|
+
```
|
|
5
|
+
/status-summary # Full overview of all data
|
|
6
|
+
/status-summary ideas # Ideas breakdown only
|
|
7
|
+
/status-summary goals # Goals progress only
|
|
8
|
+
/status-summary hypotheses # Hypotheses status only
|
|
9
|
+
/status-summary stale # Only show stale/attention items
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Input
|
|
13
|
+
- `$ARGUMENTS` — optional: specific section to focus on (`ideas`, `goals`, `hypotheses`, `stale`)
|
|
14
|
+
|
|
15
|
+
## Process
|
|
16
|
+
|
|
17
|
+
### Step 1: Load Data
|
|
18
|
+
Read the relevant data files based on `$ARGUMENTS`:
|
|
19
|
+
- If no argument or `stale`: read `data/ideas.json`, `data/goals.json`, `data/hypotheses.json`
|
|
20
|
+
- If `ideas`: read only `data/ideas.json`
|
|
21
|
+
- If `goals`: read only `data/goals.json`
|
|
22
|
+
- If `hypotheses`: read only `data/hypotheses.json`
|
|
23
|
+
|
|
24
|
+
### Step 2: Generate Summary
|
|
25
|
+
|
|
26
|
+
#### Ideas Section
|
|
27
|
+
Count ideas by stage and format as a pipeline:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
📦 Ideas Pipeline (N total)
|
|
31
|
+
───────────────────────────
|
|
32
|
+
inbox: N ██░░░░░░
|
|
33
|
+
under_review: N █░░░░░░░
|
|
34
|
+
approved: N ██░░░░░░
|
|
35
|
+
in_progress: N ███░░░░░
|
|
36
|
+
testing: N █░░░░░░░
|
|
37
|
+
shipped: N █████░░░
|
|
38
|
+
deferred: N
|
|
39
|
+
rejected: N
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Also show:
|
|
43
|
+
- **Critical priority items**: list any ideas with `priority: "critical"`
|
|
44
|
+
- **Stale inbox items**: ideas in `inbox` stage where `created_at` is more than 7 days ago
|
|
45
|
+
- **In-progress without updates**: ideas in `in_progress` where `updated_at` is more than 14 days ago
|
|
46
|
+
|
|
47
|
+
#### Goals Section
|
|
48
|
+
For each goal, show progress:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
🎯 Goals (N total)
|
|
52
|
+
───────────────────
|
|
53
|
+
[status emoji] goal-001: "Lawyer Success"
|
|
54
|
+
Category: activation | Status: behind
|
|
55
|
+
Progress: 0 / 25 (0%)
|
|
56
|
+
KPIs:
|
|
57
|
+
• First Response Rate: 56.9% → target 90% ⚠️
|
|
58
|
+
• Response Time: 64.45h → target 4h ⚠️
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Status emojis: ✅ on_track, ⚠️ at_risk, 🔴 behind, 🏆 achieved
|
|
62
|
+
|
|
63
|
+
#### Hypotheses Section
|
|
64
|
+
Count hypotheses by status:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
🧪 Hypotheses (N total)
|
|
68
|
+
───────────────────────
|
|
69
|
+
stated: N
|
|
70
|
+
testing: N
|
|
71
|
+
validated: N
|
|
72
|
+
invalidated: N
|
|
73
|
+
deferred: N
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
List any hypotheses in `stated` status older than 14 days (not yet tested).
|
|
77
|
+
|
|
78
|
+
#### Stale Data Alerts
|
|
79
|
+
Flag data freshness issues:
|
|
80
|
+
- `data/business-context.json` → check `last_manual_update`, alert if > 30 days ago
|
|
81
|
+
- `data/competitors.json` → check `last_updated`, alert if > 30 days ago
|
|
82
|
+
- `data/sessions.json` → check most recent session date, alert if > 7 days ago
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
⏰ Freshness Alerts
|
|
86
|
+
───────────────────
|
|
87
|
+
⚠️ Business context last updated 45 days ago (2026-01-02)
|
|
88
|
+
✅ Competitors data is fresh (updated 3 days ago)
|
|
89
|
+
⚠️ No analysis sessions in the last 7 days
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Step 3: Output
|
|
93
|
+
Print the full dashboard. This is a **read-only** command — no files are modified.
|
|
94
|
+
|
|
95
|
+
If issues are found, suggest `/manage` commands to fix them:
|
|
96
|
+
```
|
|
97
|
+
💡 Suggested actions:
|
|
98
|
+
/manage move idea-old-001 to deferred (stuck in inbox 30 days)
|
|
99
|
+
/manage update goal-001 status to at_risk
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Output Files
|
|
103
|
+
- None (read-only command)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# /validate-idea — Pre-Build Validation
|
|
2
|
+
|
|
3
|
+
## Usage
|
|
4
|
+
```
|
|
5
|
+
/validate-idea "Add a referral program for existing users"
|
|
6
|
+
/validate-idea "Build an API for third-party integrations"
|
|
7
|
+
/validate-idea "Launch a mobile app"
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Input
|
|
11
|
+
- `$ARGUMENTS` — **required**: the idea to validate
|
|
12
|
+
|
|
13
|
+
## Process
|
|
14
|
+
|
|
15
|
+
### Step 1: Parse Idea
|
|
16
|
+
Extract from `$ARGUMENTS`:
|
|
17
|
+
- Core idea description
|
|
18
|
+
- Implied audience (if mentioned)
|
|
19
|
+
- Implied scope (feature, product, channel)
|
|
20
|
+
|
|
21
|
+
### Step 2: Codebase Check
|
|
22
|
+
Search the codebase to see if this (or something similar) already exists:
|
|
23
|
+
- Use Glob to search for related file names
|
|
24
|
+
- Use Grep to search for related functionality
|
|
25
|
+
- Check `data/ideas.json` for similar existing ideas
|
|
26
|
+
- Check `data/hypotheses.json` for related hypotheses
|
|
27
|
+
|
|
28
|
+
If something similar exists, note it and assess whether the idea is:
|
|
29
|
+
- **Duplicate** — already exists or already proposed
|
|
30
|
+
- **Extension** — builds on existing functionality
|
|
31
|
+
- **New** — genuinely novel
|
|
32
|
+
|
|
33
|
+
### Step 3: Competitor Check
|
|
34
|
+
Load `data/competitors.json` and check:
|
|
35
|
+
- Do competitors offer this? Which ones?
|
|
36
|
+
- How do they implement it?
|
|
37
|
+
- Is it a differentiator or table stakes?
|
|
38
|
+
|
|
39
|
+
If no competitor data, WebSearch:
|
|
40
|
+
- `"[competitor name] [idea keyword]"` for top 3 competitors
|
|
41
|
+
|
|
42
|
+
### Step 4: Market Demand Check
|
|
43
|
+
WebSearch for demand signals:
|
|
44
|
+
- `"[idea keyword] demand"` or `"[idea keyword] need"`
|
|
45
|
+
- `"[product category] users want [idea]"`
|
|
46
|
+
- Check for feature request patterns on review sites, forums
|
|
47
|
+
|
|
48
|
+
### Step 5: Score the Idea
|
|
49
|
+
Score on three dimensions (1-5 each):
|
|
50
|
+
|
|
51
|
+
1. **Desirability** (Do users want it?)
|
|
52
|
+
- Evidence from search results, competitor adoption, user feedback
|
|
53
|
+
- Score 5: strong demand signals
|
|
54
|
+
- Score 1: no evidence of demand
|
|
55
|
+
|
|
56
|
+
2. **Feasibility** (Can we build it?)
|
|
57
|
+
- Technical complexity assessment from codebase check
|
|
58
|
+
- Dependencies and prerequisites
|
|
59
|
+
- Score 5: straightforward with existing tech
|
|
60
|
+
- Score 1: requires major new infrastructure
|
|
61
|
+
|
|
62
|
+
3. **Viability** (Will it make money?)
|
|
63
|
+
- Revenue potential or retention impact
|
|
64
|
+
- Alignment with current business model
|
|
65
|
+
- Score 5: direct revenue impact
|
|
66
|
+
- Score 1: no clear business case
|
|
67
|
+
|
|
68
|
+
### Step 6: Recommendation
|
|
69
|
+
Based on scores, recommend:
|
|
70
|
+
|
|
71
|
+
- **GO** (avg score >= 4): Strong idea, proceed to implementation
|
|
72
|
+
- **INVESTIGATE** (avg score 2.5-3.9): Promising but needs more data
|
|
73
|
+
- **STOP** (avg score < 2.5): Evidence doesn't support this idea
|
|
74
|
+
|
|
75
|
+
### Step 7: Create Artifacts
|
|
76
|
+
If GO or INVESTIGATE:
|
|
77
|
+
- Create a hypothesis in `data/hypotheses.json`:
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"title": "[Idea title]",
|
|
81
|
+
"statement": "If we [build this], then [metric] will [change] because [evidence]",
|
|
82
|
+
"funnel_stage": "[appropriate stage]",
|
|
83
|
+
"priority": "[based on score]",
|
|
84
|
+
"effort_to_test": "[estimate]",
|
|
85
|
+
"tags": ["validation"]
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Step 8: Output
|
|
90
|
+
Print:
|
|
91
|
+
- Idea summary
|
|
92
|
+
- Codebase check results (existing / extension / new)
|
|
93
|
+
- Competitor landscape (who does this, how)
|
|
94
|
+
- Demand evidence
|
|
95
|
+
- Score breakdown (desirability / feasibility / viability)
|
|
96
|
+
- **Recommendation: GO / INVESTIGATE / STOP**
|
|
97
|
+
- Evidence summary
|
|
98
|
+
- Hypothesis created (if applicable)
|
|
99
|
+
- Suggested next steps
|
|
100
|
+
|
|
101
|
+
## Output Files
|
|
102
|
+
- `data/hypotheses.json` — validation hypothesis (if GO or INVESTIGATE)
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
|
|
4
|
+
const TEMPLATES_DIR = path.resolve(__dirname, "..");
|
|
5
|
+
|
|
6
|
+
describe("day3-activation-feedback.txt", () => {
|
|
7
|
+
const filePath = path.join(TEMPLATES_DIR, "day3-activation-feedback.txt");
|
|
8
|
+
let content: string;
|
|
9
|
+
|
|
10
|
+
beforeAll(() => {
|
|
11
|
+
if (!fs.existsSync(filePath)) {
|
|
12
|
+
throw new Error(
|
|
13
|
+
`Template file missing: ${filePath}. Expected file to exist at templates/emails/day3-activation-feedback.txt`
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
content = fs.readFileSync(filePath, "utf-8");
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("has a non-empty Subject line", () => {
|
|
20
|
+
const match = content.match(/^Subject:\s*(.+)$/m);
|
|
21
|
+
expect(match).not.toBeNull();
|
|
22
|
+
const subject = match![1].trim();
|
|
23
|
+
expect(subject.length).toBeGreaterThan(0);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("contains the {{first_name}} placeholder", () => {
|
|
27
|
+
expect(content).toContain("{{first_name}}");
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("has a word count under 150", () => {
|
|
31
|
+
// Strip the Subject line before counting body words
|
|
32
|
+
const body = content.replace(/^Subject:.*$/m, "").trim();
|
|
33
|
+
const wordCount = body.split(/\s+/).filter((w) => w.length > 0).length;
|
|
34
|
+
expect(wordCount).toBeLessThan(150);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
describe("day30-pmf-feedback.txt", () => {
|
|
39
|
+
const filePath = path.join(TEMPLATES_DIR, "day30-pmf-feedback.txt");
|
|
40
|
+
let content: string;
|
|
41
|
+
|
|
42
|
+
beforeAll(() => {
|
|
43
|
+
if (!fs.existsSync(filePath)) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
`Template file missing: ${filePath}. Expected file to exist at templates/emails/day30-pmf-feedback.txt`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
content = fs.readFileSync(filePath, "utf-8");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("has the required Subject line", () => {
|
|
52
|
+
const match = content.match(/^Subject:\s*(.+)$/m);
|
|
53
|
+
if (!match) {
|
|
54
|
+
throw new Error(
|
|
55
|
+
"Missing required element: Subject line not found. Expected a line starting with 'Subject:'"
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
const subject = match[1].trim();
|
|
59
|
+
if (subject.length === 0) {
|
|
60
|
+
throw new Error(
|
|
61
|
+
"Missing required element: Subject line is empty. Expected non-empty subject text"
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
expect(subject.length).toBeGreaterThan(0);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("contains the {{first_name}} placeholder", () => {
|
|
68
|
+
if (!content.includes("{{first_name}}")) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
"Missing required element: {{first_name}} placeholder not found in template"
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
expect(content).toContain("{{first_name}}");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("contains Sean Ellis option a) Very disappointed", () => {
|
|
77
|
+
if (!content.includes("a) Very disappointed")) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
"Missing required element: Sean Ellis answer option 'a) Very disappointed' not found in template"
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
expect(content).toContain("a) Very disappointed");
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("contains Sean Ellis option b) Somewhat disappointed", () => {
|
|
86
|
+
if (!content.includes("b) Somewhat disappointed")) {
|
|
87
|
+
throw new Error(
|
|
88
|
+
"Missing required element: Sean Ellis answer option 'b) Somewhat disappointed' not found in template"
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
expect(content).toContain("b) Somewhat disappointed");
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("contains Sean Ellis option c) Not disappointed", () => {
|
|
95
|
+
if (!content.includes("c) Not disappointed")) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
"Missing required element: Sean Ellis answer option 'c) Not disappointed' not found in template"
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
expect(content).toContain("c) Not disappointed");
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("has a word count under 200", () => {
|
|
104
|
+
const body = content.replace(/^Subject:.*$/m, "").trim();
|
|
105
|
+
const wordCount = body.split(/\s+/).filter((w) => w.length > 0).length;
|
|
106
|
+
if (wordCount >= 200) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
`Missing required element: word count constraint violated. Body has ${wordCount} words but must be under 200`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
expect(wordCount).toBeLessThan(200);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe("feedback-playbook.md", () => {
|
|
116
|
+
const playbookPath = path.resolve(__dirname, "../../../docs/feedback-playbook.md");
|
|
117
|
+
let content: string;
|
|
118
|
+
|
|
119
|
+
const REQUIRED_HEADINGS = [
|
|
120
|
+
"## Purpose",
|
|
121
|
+
"## Templates",
|
|
122
|
+
"## Trigger",
|
|
123
|
+
"## Sending Instructions",
|
|
124
|
+
"## Reading Responses",
|
|
125
|
+
"## Future Automation",
|
|
126
|
+
];
|
|
127
|
+
|
|
128
|
+
beforeAll(() => {
|
|
129
|
+
if (!fs.existsSync(playbookPath)) {
|
|
130
|
+
throw new Error(
|
|
131
|
+
`Playbook file missing: ${playbookPath}. Expected file to exist at docs/feedback-playbook.md`
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
content = fs.readFileSync(playbookPath, "utf-8");
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it("contains all required section headings", () => {
|
|
138
|
+
for (const heading of REQUIRED_HEADINGS) {
|
|
139
|
+
if (!content.includes(heading)) {
|
|
140
|
+
throw new Error(
|
|
141
|
+
`Missing required section heading: "${heading}" not found in docs/feedback-playbook.md`
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
expect(content).toContain(heading);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Subject: Quick question about your first days with VibeBusiness
|
|
2
|
+
|
|
3
|
+
Hi {{first_name}},
|
|
4
|
+
|
|
5
|
+
I'm the founder of VibeBusiness and I wanted to reach out personally.
|
|
6
|
+
|
|
7
|
+
One quick question: what were you originally trying to accomplish when you signed up?
|
|
8
|
+
|
|
9
|
+
Even a one-line answer helps me make VibeBusiness more useful for people like you.
|
|
10
|
+
|
|
11
|
+
Just hit reply — I read every response.
|
|
12
|
+
|
|
13
|
+
— Luis
|
|
14
|
+
Founder, VibeBusiness
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Subject: One question about VibeBusiness
|
|
2
|
+
|
|
3
|
+
Hi {{first_name}},
|
|
4
|
+
|
|
5
|
+
Quick question — it'll take 30 seconds.
|
|
6
|
+
|
|
7
|
+
How would you feel if you could no longer use VibeBusiness?
|
|
8
|
+
|
|
9
|
+
a) Very disappointed
|
|
10
|
+
b) Somewhat disappointed
|
|
11
|
+
c) Not disappointed
|
|
12
|
+
|
|
13
|
+
If VibeBusiness disappeared tomorrow, what would you use instead?
|
|
14
|
+
|
|
15
|
+
Just hit reply with your answer — no forms, no links.
|
|
16
|
+
|
|
17
|
+
Thanks,
|
|
18
|
+
Luís
|
|
19
|
+
Founder, VibeBusiness
|