vibebusiness 1.2.49 → 1.2.51
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 +17 -17
- 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]/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.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 +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.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 +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 +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/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/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 +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +13 -13
- package/.next/standalone/.next/server/chunks/3794.js +64 -4
- 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 +45 -6
- package/.next/standalone/data/goals.json +50 -10
- package/.next/standalone/data/ideas.json +1278 -597
- package/.next/standalone/data/implementations.json +101 -0
- package/.next/standalone/data/posthog.json +68 -0
- package/.next/standalone/data/sessions.json +5 -4
- package/.next/standalone/data/social.json +2 -2
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/scripts/skills/social-media.ts +172 -2
- package/dist/scripts/heartbeat.js +286 -26
- package/package.json +1 -1
- /package/.next/static/{zIIaTqrawBK1MmHg37JOr → pCt9lOHHLoEA8SuY832zV}/_buildManifest.js +0 -0
- /package/.next/static/{zIIaTqrawBK1MmHg37JOr → pCt9lOHHLoEA8SuY832zV}/_ssgManifest.js +0 -0
|
@@ -1369,6 +1369,107 @@
|
|
|
1369
1369
|
"[2026-02-21T03:14:02.477Z] Create PR only mode — skipping implementation",
|
|
1370
1370
|
"[2026-02-21T03:14:02.490Z] No commits to push, skipping PR creation"
|
|
1371
1371
|
]
|
|
1372
|
+
},
|
|
1373
|
+
{
|
|
1374
|
+
"id": "impl-mly92zre",
|
|
1375
|
+
"idea_id": "idea-073e5d92",
|
|
1376
|
+
"status": "completed",
|
|
1377
|
+
"repo_name": "vibebusiness",
|
|
1378
|
+
"branch_name": "ai/idea-073e5d92-fix-critical-shell-injection-in-implemen",
|
|
1379
|
+
"workspace_path": "/Users/luismey/Code/vibebusiness/workspaces/vibebusiness-worktrees/ai/idea-073e5d92-impl-g0",
|
|
1380
|
+
"logs": [
|
|
1381
|
+
"[2026-02-22T21:19:05.353Z] Implementation started",
|
|
1382
|
+
"[2026-02-22T21:19:05.357Z] Using pre-configured worktree: /Users/luismey/Code/vibebusiness/workspaces/vibebusiness-worktrees/ai/idea-073e5d92-impl-g0",
|
|
1383
|
+
"[2026-02-22T21:19:05.361Z] Running Claude Code to implement changes (timeout: 600s (model: sonnet))...",
|
|
1384
|
+
"[2026-02-22T21:19:05.372Z] Using pre-configured worktree: /Users/luismey/Code/vibebusiness/workspaces/vibebusiness-worktrees/ai/idea-073e5d92-impl-g1",
|
|
1385
|
+
"[2026-02-22T21:19:05.377Z] Running Claude Code to implement changes (timeout: 600s (model: sonnet))...",
|
|
1386
|
+
"[2026-02-22T21:19:05.386Z] Using pre-configured worktree: /Users/luismey/Code/vibebusiness/workspaces/vibebusiness-worktrees/ai/idea-073e5d92-impl-g2",
|
|
1387
|
+
"[2026-02-22T21:19:05.396Z] Using pre-configured worktree: /Users/luismey/Code/vibebusiness/workspaces/vibebusiness-worktrees/ai/idea-073e5d92-impl-g3",
|
|
1388
|
+
"[2026-02-22T21:19:05.403Z] Running Claude Code to implement changes (timeout: 600s (model: sonnet))...",
|
|
1389
|
+
"[2026-02-22T21:19:05.423Z] Using pre-configured worktree: /Users/luismey/Code/vibebusiness/workspaces/vibebusiness-worktrees/ai/idea-073e5d92-impl-g4",
|
|
1390
|
+
"[2026-02-22T21:19:05.455Z] Running Claude Code to implement changes (timeout: 600s (model: sonnet))...",
|
|
1391
|
+
"[2026-02-22T21:19:05.466Z] Using pre-configured worktree: /Users/luismey/Code/vibebusiness/workspaces/vibebusiness-worktrees/ai/idea-073e5d92-impl-g5",
|
|
1392
|
+
"[2026-02-22T21:19:05.477Z] Running Claude Code to implement changes (timeout: 600s (model: sonnet))...",
|
|
1393
|
+
"[2026-02-22T21:19:35.372Z] ...Claude Code working (30s elapsed, 0 chars output, 30s since last output)",
|
|
1394
|
+
"[2026-02-22T21:19:35.380Z] ...Claude Code working (30s elapsed, 0 chars output, 30s since last output)",
|
|
1395
|
+
"[2026-02-22T21:19:35.401Z] ...Claude Code working (30s elapsed, 0 chars output, 30s since last output)",
|
|
1396
|
+
"[2026-02-22T21:19:35.412Z] ...Claude Code working (30s elapsed, 0 chars output, 30s since last output)",
|
|
1397
|
+
"[2026-02-22T21:19:35.466Z] ...Claude Code working (30s elapsed, 0 chars output, 30s since last output)",
|
|
1398
|
+
"[2026-02-22T21:19:35.481Z] ...Claude Code working (30s elapsed, 0 chars output, 30s since last output)",
|
|
1399
|
+
"[2026-02-22T21:19:43.621Z] Claude Code completed successfully in 38s (1000 chars)",
|
|
1400
|
+
"[2026-02-22T21:19:43.657Z] Changes detected, staging and committing...",
|
|
1401
|
+
"[2026-02-22T21:19:43.739Z] Skipping PR creation (--skip-pr)",
|
|
1402
|
+
"[2026-02-22T21:20:04.844Z] Claude Code completed successfully in 59s (1005 chars)",
|
|
1403
|
+
"[2026-02-22T21:20:04.899Z] Changes detected, staging and committing...",
|
|
1404
|
+
"[2026-02-22T21:20:04.975Z] Skipping PR creation (--skip-pr)",
|
|
1405
|
+
"[2026-02-22T21:20:05.021Z] Claude Code completed successfully in 60s (1202 chars)",
|
|
1406
|
+
"[2026-02-22T21:20:05.065Z] Changes detected, staging and committing...",
|
|
1407
|
+
"[2026-02-22T21:20:05.127Z] Skipping PR creation (--skip-pr)",
|
|
1408
|
+
"[2026-02-22T21:20:05.412Z] ...Claude Code working (60s elapsed, 0 chars output, 60s since last output)",
|
|
1409
|
+
"[2026-02-22T21:20:05.467Z] ...Claude Code working (60s elapsed, 0 chars output, 60s since last output)",
|
|
1410
|
+
"[2026-02-22T21:20:05.480Z] ...Claude Code working (60s elapsed, 0 chars output, 60s since last output)",
|
|
1411
|
+
"[2026-02-22T21:20:35.414Z] ...Claude Code working (90s elapsed, 0 chars output, 90s since last output)",
|
|
1412
|
+
"[2026-02-22T21:20:35.468Z] ...Claude Code working (90s elapsed, 0 chars output, 90s since last output)",
|
|
1413
|
+
"[2026-02-22T21:20:35.483Z] ...Claude Code working (90s elapsed, 0 chars output, 90s since last output)",
|
|
1414
|
+
"[2026-02-22T21:20:42.632Z] Claude Code completed successfully in 97s (1206 chars)",
|
|
1415
|
+
"[2026-02-22T21:20:42.685Z] Changes detected, staging and committing...",
|
|
1416
|
+
"[2026-02-22T21:20:42.735Z] Skipping PR creation (--skip-pr)",
|
|
1417
|
+
"[2026-02-22T21:21:05.414Z] ...Claude Code working (120s elapsed, 0 chars output, 120s since last output)",
|
|
1418
|
+
"[2026-02-22T21:21:05.481Z] ...Claude Code working (120s elapsed, 0 chars output, 120s since last output)",
|
|
1419
|
+
"[2026-02-22T21:21:35.414Z] ...Claude Code working (150s elapsed, 0 chars output, 150s since last output)",
|
|
1420
|
+
"[2026-02-22T21:21:35.483Z] ...Claude Code working (150s elapsed, 0 chars output, 150s since last output)",
|
|
1421
|
+
"[2026-02-22T21:22:05.416Z] ...Claude Code working (180s elapsed, 0 chars output, 180s since last output)",
|
|
1422
|
+
"[2026-02-22T21:22:05.483Z] ...Claude Code working (180s elapsed, 0 chars output, 180s since last output)",
|
|
1423
|
+
"[2026-02-22T21:22:35.417Z] ...Claude Code working (210s elapsed, 0 chars output, 210s since last output)",
|
|
1424
|
+
"[2026-02-22T21:22:35.484Z] ...Claude Code working (210s elapsed, 0 chars output, 210s since last output)",
|
|
1425
|
+
"[2026-02-22T21:23:05.416Z] ...Claude Code working (240s elapsed, 0 chars output, 240s since last output)",
|
|
1426
|
+
"[2026-02-22T21:23:05.483Z] ...Claude Code working (240s elapsed, 0 chars output, 240s since last output)",
|
|
1427
|
+
"[2026-02-22T21:23:17.057Z] Claude Code completed successfully in 252s (2194 chars)",
|
|
1428
|
+
"[2026-02-22T21:23:17.098Z] Changes detected, staging and committing...",
|
|
1429
|
+
"[2026-02-22T21:23:17.156Z] Skipping PR creation (--skip-pr)",
|
|
1430
|
+
"[2026-02-22T21:23:35.417Z] ...Claude Code working (270s elapsed, 0 chars output, 270s since last output)",
|
|
1431
|
+
"[2026-02-22T21:24:04.053Z] Claude Code completed successfully in 299s (2310 chars)",
|
|
1432
|
+
"[2026-02-22T21:24:04.121Z] Changes detected, staging and committing...",
|
|
1433
|
+
"[2026-02-22T21:24:04.199Z] Skipping PR creation (--skip-pr)"
|
|
1434
|
+
]
|
|
1435
|
+
},
|
|
1436
|
+
{
|
|
1437
|
+
"id": "impl-mly949xm",
|
|
1438
|
+
"idea_id": "idea-073e5d92",
|
|
1439
|
+
"status": "completed",
|
|
1440
|
+
"repo_name": "vibebusiness",
|
|
1441
|
+
"branch_name": "ai/idea-073e5d92-fix-critical-shell-injection-in-implemen",
|
|
1442
|
+
"workspace_path": "/Users/luismey/Code/vibebusiness/workspaces/vibebusiness-worktrees/ai/idea-073e5d92-impl-g0",
|
|
1443
|
+
"logs": [
|
|
1444
|
+
"[2026-02-22T21:20:05.193Z] Implementation started",
|
|
1445
|
+
"[2026-02-22T21:20:05.195Z] Using pre-configured worktree: /Users/luismey/Code/vibebusiness/workspaces/vibebusiness-worktrees/ai/idea-073e5d92-impl-g0",
|
|
1446
|
+
"[2026-02-22T21:20:05.196Z] Running Claude Code to implement changes (timeout: 600s (model: sonnet))...",
|
|
1447
|
+
"[2026-02-22T21:20:35.199Z] ...Claude Code working (30s elapsed, 0 chars output, 30s since last output)",
|
|
1448
|
+
"[2026-02-22T21:21:05.200Z] ...Claude Code working (60s elapsed, 0 chars output, 60s since last output)",
|
|
1449
|
+
"[2026-02-22T21:21:30.701Z] Claude Code completed successfully in 86s (1241 chars)",
|
|
1450
|
+
"[2026-02-22T21:21:30.721Z] Changes detected, staging and committing...",
|
|
1451
|
+
"[2026-02-22T21:21:30.799Z] Skipping PR creation (--skip-pr)"
|
|
1452
|
+
]
|
|
1453
|
+
},
|
|
1454
|
+
{
|
|
1455
|
+
"id": "impl-mly9641i",
|
|
1456
|
+
"idea_id": "idea-073e5d92",
|
|
1457
|
+
"status": "completed",
|
|
1458
|
+
"repo_name": "vibebusiness",
|
|
1459
|
+
"branch_name": "ai/idea-073e5d92-fix-critical-shell-injection-in-implemen",
|
|
1460
|
+
"workspace_path": "/Users/luismey/Code/vibebusiness/workspaces/vibebusiness-worktrees/ai/idea-073e5d92-impl-g0",
|
|
1461
|
+
"logs": [
|
|
1462
|
+
"[2026-02-22T21:21:30.870Z] Implementation started",
|
|
1463
|
+
"[2026-02-22T21:21:30.871Z] Using pre-configured worktree: /Users/luismey/Code/vibebusiness/workspaces/vibebusiness-worktrees/ai/idea-073e5d92-impl-g0",
|
|
1464
|
+
"[2026-02-22T21:21:30.872Z] Running Claude Code to implement changes (timeout: 600s (model: sonnet))...",
|
|
1465
|
+
"[2026-02-22T21:22:00.877Z] ...Claude Code working (30s elapsed, 0 chars output, 30s since last output)",
|
|
1466
|
+
"[2026-02-22T21:22:30.876Z] ...Claude Code working (60s elapsed, 0 chars output, 60s since last output)",
|
|
1467
|
+
"[2026-02-22T21:23:00.877Z] ...Claude Code working (90s elapsed, 0 chars output, 90s since last output)",
|
|
1468
|
+
"[2026-02-22T21:23:30.878Z] ...Claude Code working (120s elapsed, 0 chars output, 120s since last output)",
|
|
1469
|
+
"[2026-02-22T21:23:36.366Z] Claude Code completed successfully in 125s (1664 chars)",
|
|
1470
|
+
"[2026-02-22T21:23:36.408Z] Changes detected, staging and committing...",
|
|
1471
|
+
"[2026-02-22T21:23:36.507Z] Skipping PR creation (--skip-pr)"
|
|
1472
|
+
]
|
|
1372
1473
|
}
|
|
1373
1474
|
]
|
|
1374
1475
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"last_updated": "2026-02-22T21:45:00.000Z",
|
|
3
|
+
"integration_status": {
|
|
4
|
+
"sdk_installed": true,
|
|
5
|
+
"api_key_valid": true,
|
|
6
|
+
"provider_generated": true,
|
|
7
|
+
"pageview_tracker": true,
|
|
8
|
+
"event_helper": true,
|
|
9
|
+
"kpi_adapter": true
|
|
10
|
+
},
|
|
11
|
+
"framework": {
|
|
12
|
+
"framework": "nextjs",
|
|
13
|
+
"typescript": true,
|
|
14
|
+
"appRouter": true,
|
|
15
|
+
"srcDir": true
|
|
16
|
+
},
|
|
17
|
+
"generated_files": [
|
|
18
|
+
"website/src/components/PostHogProvider.tsx",
|
|
19
|
+
"website/src/components/PostHogPageview.tsx",
|
|
20
|
+
"website/src/lib/posthog.ts"
|
|
21
|
+
],
|
|
22
|
+
"detected_events": [
|
|
23
|
+
{
|
|
24
|
+
"event": "waitlist_signup_success",
|
|
25
|
+
"location": "website/src/app/page.tsx",
|
|
26
|
+
"type": "website"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"event": "waitlist_signup_error",
|
|
30
|
+
"location": "website/src/app/page.tsx",
|
|
31
|
+
"type": "website"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"event": "checkout_completed",
|
|
35
|
+
"location": "website/src/components/TrackCheckoutComplete.tsx",
|
|
36
|
+
"type": "website"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"event": "command_run",
|
|
40
|
+
"location": "bin/ai-analyst.ts",
|
|
41
|
+
"type": "cli",
|
|
42
|
+
"properties": ["command", "dryRun", "session", "task", "type", "deep", "minimal"]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"event": "heartbeat_task",
|
|
46
|
+
"location": "scripts/heartbeat.ts",
|
|
47
|
+
"type": "backend",
|
|
48
|
+
"properties": ["taskType", "success", "errorType"]
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"kpi_mappings": {
|
|
52
|
+
"kpi-beta-signups": "waitlist_signup_success",
|
|
53
|
+
"kpi-paying-users": "checkout_completed",
|
|
54
|
+
"kpi-cli-init-count": "command_run[command=init]",
|
|
55
|
+
"kpi-cli-vibe-count": "command_run[command=vibe]",
|
|
56
|
+
"kpi-cli-scan-count": "command_run[command=scan]"
|
|
57
|
+
},
|
|
58
|
+
"unmapped_events": [
|
|
59
|
+
{
|
|
60
|
+
"event": "waitlist_signup_error",
|
|
61
|
+
"reason": "No matching KPI — useful for error monitoring in PostHog dashboards"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"event": "heartbeat_task",
|
|
65
|
+
"reason": "Operational metric — useful in PostHog dashboards but no business KPI match"
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
}
|
|
@@ -341,18 +341,19 @@
|
|
|
341
341
|
{
|
|
342
342
|
"id": "session-4a6293fb",
|
|
343
343
|
"created_at": "2026-02-19T20:11:45.297Z",
|
|
344
|
-
"completed_at":
|
|
344
|
+
"completed_at": "2026-02-22T00:00:00.000Z",
|
|
345
345
|
"type": "quick",
|
|
346
|
-
"status": "
|
|
346
|
+
"status": "failed",
|
|
347
347
|
"repos_analyzed": [
|
|
348
348
|
"vibebusiness"
|
|
349
349
|
],
|
|
350
350
|
"ideas_generated": [],
|
|
351
|
-
"error_message":
|
|
351
|
+
"error_message": "Session timed out — marked failed by dedup-triage-and-approve-inbox meta-task on 2026-02-22. Was stuck in 'running' with 0 ideas generated since 2026-02-19T20:11:45.",
|
|
352
352
|
"logs": [
|
|
353
353
|
"[2026-02-19T20:11:45.297Z] Session started",
|
|
354
354
|
"[2026-02-19T20:11:45.301Z] Generated quick analysis prompt",
|
|
355
|
-
"[2026-02-19T20:11:45.301Z] Running Claude Code analysis..."
|
|
355
|
+
"[2026-02-19T20:11:45.301Z] Running Claude Code analysis...",
|
|
356
|
+
"[2026-02-22T00:00:00.000Z] Session marked failed by meta-task cleanup (zombie session — no ideas generated, stuck in running state)"
|
|
356
357
|
]
|
|
357
358
|
}
|
|
358
359
|
]
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
-
"last_updated": "2026-02-
|
|
2
|
+
"last_updated": "2026-02-22T20:39:11.478Z",
|
|
3
3
|
"platform": "x",
|
|
4
4
|
"username": "@luisgmey",
|
|
5
5
|
"credentials_valid": true,
|
|
6
6
|
"drafts": [],
|
|
7
7
|
"metrics": {
|
|
8
|
-
"followers_count":
|
|
8
|
+
"followers_count": 335,
|
|
9
9
|
"post_streak_days": 0,
|
|
10
10
|
"total_posts": 0,
|
|
11
11
|
"last_post_date": null
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Task prefixes handled:
|
|
10
10
|
* social-setup-x → Validate X credentials, save username
|
|
11
|
+
* social-plan-week → Generate a 7-day content calendar with AI-optimized drafts
|
|
11
12
|
* social-draft-ship → Draft a "just shipped" tweet from latest shipped idea
|
|
12
13
|
* social-draft-ship-visual → Draft ship tweet with card/video media
|
|
13
14
|
* social-draft-update → Draft a product update from positioning data
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
import * as fs from 'fs';
|
|
25
26
|
import * as path from 'path';
|
|
26
27
|
import { v4 as uuidv4 } from 'uuid';
|
|
27
|
-
import { SOCIAL_FILE, GOALS_FILE, DATA_DIR } from '../lib/paths';
|
|
28
|
+
import { SOCIAL_FILE, GOALS_FILE, IDEAS_FILE, POSITIONING_FILE, DATA_DIR } from '../lib/paths';
|
|
28
29
|
import {
|
|
29
30
|
loadCredentials,
|
|
30
31
|
createXClient,
|
|
@@ -45,10 +46,11 @@ import {
|
|
|
45
46
|
import {
|
|
46
47
|
generateViralTweet,
|
|
47
48
|
generateViralThread,
|
|
49
|
+
generateWeekPlan,
|
|
48
50
|
scoreDraft,
|
|
49
51
|
type TweetTopic,
|
|
50
52
|
} from '../lib/social/ai-content-generator';
|
|
51
|
-
import type { SocialConfig, SocialDraft, SocialDraftSource, TweetEngagement, BusinessGoal } from '../../src/lib/types';
|
|
53
|
+
import type { SocialConfig, SocialDraft, SocialDraftSource, TweetEngagement, BusinessGoal, PositioningData } from '../../src/lib/types';
|
|
52
54
|
|
|
53
55
|
// ─── State ───────────────────────────────────────────────────────────────────
|
|
54
56
|
|
|
@@ -159,6 +161,7 @@ function createDraft(
|
|
|
159
161
|
|
|
160
162
|
const SOCIAL_PREFIXES = [
|
|
161
163
|
'social-setup-x',
|
|
164
|
+
'social-plan-week',
|
|
162
165
|
'social-draft-ship-visual',
|
|
163
166
|
'social-draft-ship',
|
|
164
167
|
'social-draft-update',
|
|
@@ -191,6 +194,9 @@ export async function executeSocialTask(
|
|
|
191
194
|
if (taskId === 'social-setup-x') {
|
|
192
195
|
return await executeSetupX();
|
|
193
196
|
}
|
|
197
|
+
if (taskId === 'social-plan-week') {
|
|
198
|
+
return await executePlanWeek();
|
|
199
|
+
}
|
|
194
200
|
if (taskId === 'social-draft-ship-visual') {
|
|
195
201
|
return executeDraftShipVisual();
|
|
196
202
|
}
|
|
@@ -251,6 +257,7 @@ export function readSocialFreshness(): {
|
|
|
251
257
|
best_tweet_id: string | null;
|
|
252
258
|
best_engagement_rate: number | null;
|
|
253
259
|
thread_count: number;
|
|
260
|
+
scheduled_draft_count: number;
|
|
254
261
|
} {
|
|
255
262
|
const state = loadState();
|
|
256
263
|
const pendingDrafts = state.drafts.filter((d) => d.status === 'draft').length;
|
|
@@ -278,6 +285,12 @@ export function readSocialFreshness(): {
|
|
|
278
285
|
|
|
279
286
|
const threadCount = state.drafts.filter((d) => d.is_thread && d.status === 'published').length;
|
|
280
287
|
|
|
288
|
+
// Count drafts with future scheduled dates
|
|
289
|
+
const today = new Date().toISOString().split('T')[0];
|
|
290
|
+
const scheduledDraftCount = state.drafts.filter(
|
|
291
|
+
(d) => d.status === 'draft' && d.scheduled_date && d.scheduled_date >= today
|
|
292
|
+
).length;
|
|
293
|
+
|
|
281
294
|
return {
|
|
282
295
|
configured: state.credentials_valid,
|
|
283
296
|
credentials_valid: state.credentials_valid,
|
|
@@ -290,6 +303,7 @@ export function readSocialFreshness(): {
|
|
|
290
303
|
best_tweet_id: bestTweetId,
|
|
291
304
|
best_engagement_rate: bestEngagementRate,
|
|
292
305
|
thread_count: threadCount,
|
|
306
|
+
scheduled_draft_count: scheduledDraftCount,
|
|
293
307
|
};
|
|
294
308
|
}
|
|
295
309
|
|
|
@@ -616,6 +630,161 @@ async function executeDraftThread(
|
|
|
616
630
|
};
|
|
617
631
|
}
|
|
618
632
|
|
|
633
|
+
// ─── Weekly Content Plan ─────────────────────────────────────────────────
|
|
634
|
+
|
|
635
|
+
async function executePlanWeek(): Promise<{ success: boolean; output: string }> {
|
|
636
|
+
const state = loadState();
|
|
637
|
+
|
|
638
|
+
// Gather context for the AI planner
|
|
639
|
+
const pastPerformance = collectEngagementHistory(state);
|
|
640
|
+
|
|
641
|
+
// Read positioning data
|
|
642
|
+
let positioning: PositioningData | null = null;
|
|
643
|
+
try {
|
|
644
|
+
if (fs.existsSync(POSITIONING_FILE)) {
|
|
645
|
+
positioning = JSON.parse(fs.readFileSync(POSITIONING_FILE, 'utf-8'));
|
|
646
|
+
}
|
|
647
|
+
} catch { /* ignore */ }
|
|
648
|
+
|
|
649
|
+
// Read goals for behind-schedule context
|
|
650
|
+
let goalsContext = '';
|
|
651
|
+
try {
|
|
652
|
+
if (fs.existsSync(GOALS_FILE)) {
|
|
653
|
+
const { goals } = JSON.parse(fs.readFileSync(GOALS_FILE, 'utf-8')) as { goals: BusinessGoal[] };
|
|
654
|
+
const relevant = goals
|
|
655
|
+
.filter((g) => g.status === 'on_track' || g.status === 'at_risk' || g.status === 'behind')
|
|
656
|
+
.map((g) => {
|
|
657
|
+
const progress = g.current_value != null && g.target_value
|
|
658
|
+
? `${Math.round((g.current_value / g.target_value) * 100)}%`
|
|
659
|
+
: 'unknown';
|
|
660
|
+
return `- ${g.title} (${g.status}, ${progress} complete, deadline: ${g.deadline})`;
|
|
661
|
+
});
|
|
662
|
+
goalsContext = relevant.length > 0 ? relevant.join('\n') : 'No active goals.';
|
|
663
|
+
}
|
|
664
|
+
} catch { /* ignore */ }
|
|
665
|
+
|
|
666
|
+
// Read recently shipped ideas (last 14 days)
|
|
667
|
+
let recentShips = '';
|
|
668
|
+
try {
|
|
669
|
+
if (fs.existsSync(IDEAS_FILE)) {
|
|
670
|
+
const { ideas } = JSON.parse(fs.readFileSync(IDEAS_FILE, 'utf-8')) as {
|
|
671
|
+
ideas: Array<{ id: string; title: string; stage: string; updated_at: string }>;
|
|
672
|
+
};
|
|
673
|
+
const twoWeeksAgo = new Date(Date.now() - 14 * 24 * 60 * 60 * 1000).toISOString();
|
|
674
|
+
const shipped = ideas
|
|
675
|
+
.filter((i) => i.stage === 'shipped' && i.updated_at > twoWeeksAgo)
|
|
676
|
+
.map((i) => `- ${i.title} (shipped ${i.updated_at.split('T')[0]})`);
|
|
677
|
+
recentShips = shipped.length > 0 ? shipped.join('\n') : 'No recent ships.';
|
|
678
|
+
}
|
|
679
|
+
} catch { /* ignore */ }
|
|
680
|
+
|
|
681
|
+
// KPI highlights
|
|
682
|
+
let kpiHighlights = '';
|
|
683
|
+
try {
|
|
684
|
+
if (fs.existsSync(GOALS_FILE)) {
|
|
685
|
+
const { goals } = JSON.parse(fs.readFileSync(GOALS_FILE, 'utf-8')) as { goals: BusinessGoal[] };
|
|
686
|
+
const highlights: string[] = [];
|
|
687
|
+
for (const goal of goals) {
|
|
688
|
+
for (const kpi of goal.kpis) {
|
|
689
|
+
if (kpi.current_value != null && kpi.target_value != null) {
|
|
690
|
+
const pct = Math.round((kpi.current_value / kpi.target_value) * 100);
|
|
691
|
+
highlights.push(`- ${kpi.name}: ${kpi.current_value}/${kpi.target_value} ${kpi.unit} (${pct}%)`);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
kpiHighlights = highlights.length > 0 ? highlights.join('\n') : 'No KPI data.';
|
|
696
|
+
}
|
|
697
|
+
} catch { /* ignore */ }
|
|
698
|
+
|
|
699
|
+
const plan = await generateWeekPlan({
|
|
700
|
+
positioning,
|
|
701
|
+
pastPerformance,
|
|
702
|
+
goalsContext,
|
|
703
|
+
recentShips,
|
|
704
|
+
kpiHighlights,
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
if (plan.days.length === 0) {
|
|
708
|
+
return { success: false, output: 'AI failed to generate a weekly content plan.' };
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// Create drafts for each non-rest day
|
|
712
|
+
const createdDrafts: Array<{ day: string; date: string; type: string; id: string }> = [];
|
|
713
|
+
|
|
714
|
+
for (const day of plan.days) {
|
|
715
|
+
if (day.type === 'rest' || !day.content) continue;
|
|
716
|
+
|
|
717
|
+
if (day.type === 'thread' && day.thread_tweets && day.thread_tweets.length > 0) {
|
|
718
|
+
// Thread draft
|
|
719
|
+
const draft: SocialDraft = {
|
|
720
|
+
id: `draft-${uuidv4().slice(0, 8)}`,
|
|
721
|
+
text: day.thread_tweets[0],
|
|
722
|
+
source: 'thread',
|
|
723
|
+
source_ref: null,
|
|
724
|
+
status: 'draft',
|
|
725
|
+
created_at: new Date().toISOString(),
|
|
726
|
+
published_at: null,
|
|
727
|
+
tweet_id: null,
|
|
728
|
+
tweet_url: null,
|
|
729
|
+
is_thread: true,
|
|
730
|
+
thread_tweets: day.thread_tweets,
|
|
731
|
+
scheduled_date: day.date,
|
|
732
|
+
};
|
|
733
|
+
state.drafts.push(draft);
|
|
734
|
+
createdDrafts.push({ day: day.day, date: day.date, type: 'thread', id: draft.id });
|
|
735
|
+
} else {
|
|
736
|
+
// Single tweet draft
|
|
737
|
+
const source: SocialDraftSource = (['ship', 'milestone', 'update', 'digest', 'insight'].includes(day.topic as string)
|
|
738
|
+
? day.topic
|
|
739
|
+
: 'insight') as SocialDraftSource;
|
|
740
|
+
const draft = createDraft(state, day.content, source, null);
|
|
741
|
+
draft.scheduled_date = day.date;
|
|
742
|
+
createdDrafts.push({ day: day.day, date: day.date, type: day.type, id: draft.id });
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
saveState(state);
|
|
747
|
+
|
|
748
|
+
// Format calendar output
|
|
749
|
+
const monday = plan.days.find((d) => d.day === 'monday')?.date ?? '';
|
|
750
|
+
const sunday = plan.days.find((d) => d.day === 'sunday')?.date ?? '';
|
|
751
|
+
const dateRange = monday && sunday
|
|
752
|
+
? `${formatDateShort(monday)} - ${formatDateShort(sunday)}`
|
|
753
|
+
: 'This Week';
|
|
754
|
+
|
|
755
|
+
const lines: string[] = [`Weekly Content Plan (${dateRange})`, ''];
|
|
756
|
+
|
|
757
|
+
for (const day of plan.days) {
|
|
758
|
+
const dayLabel = day.day.charAt(0).toUpperCase() + day.day.slice(1, 3);
|
|
759
|
+
if (day.type === 'rest') {
|
|
760
|
+
lines.push(`${dayLabel} -- Rest`);
|
|
761
|
+
} else {
|
|
762
|
+
const threadInfo = day.type === 'thread' && day.thread_tweets
|
|
763
|
+
? ` (${day.thread_tweets.length} tweets)`
|
|
764
|
+
: '';
|
|
765
|
+
const preview = day.content.length > 60
|
|
766
|
+
? `"${day.content.slice(0, 57)}..."`
|
|
767
|
+
: `"${day.content}"`;
|
|
768
|
+
lines.push(`${dayLabel} [${day.type}] ${preview}${threadInfo}`);
|
|
769
|
+
lines.push(` Hook: ${day.hook_type} | ${day.rationale}`);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
lines.push('');
|
|
774
|
+
lines.push(`${createdDrafts.length} drafts created. Review and edit at: vibebusiness start -> /social`);
|
|
775
|
+
|
|
776
|
+
return { success: true, output: lines.join('\n') };
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
/**
|
|
780
|
+
* Format YYYY-MM-DD to "Mon DD" short form.
|
|
781
|
+
*/
|
|
782
|
+
function formatDateShort(isoDate: string): string {
|
|
783
|
+
const d = new Date(isoDate + 'T00:00:00');
|
|
784
|
+
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
785
|
+
return `${months[d.getMonth()]} ${d.getDate()}`;
|
|
786
|
+
}
|
|
787
|
+
|
|
619
788
|
// ─── Engagement Tracking ──────────────────────────────────────────────────
|
|
620
789
|
|
|
621
790
|
async function executeTrackMetrics(): Promise<{ success: boolean; output: string }> {
|
|
@@ -777,6 +946,7 @@ async function executeCheckStatus(): Promise<{ success: boolean; output: string
|
|
|
777
946
|
}
|
|
778
947
|
|
|
779
948
|
lines.push(` Pending drafts: ${freshness.draft_count}`);
|
|
949
|
+
lines.push(` Scheduled drafts: ${freshness.scheduled_draft_count}`);
|
|
780
950
|
lines.push(` Post streak: ${freshness.post_streak_days} day(s)`);
|
|
781
951
|
lines.push(` Total posts: ${freshness.total_posts}`);
|
|
782
952
|
lines.push(` Threads published: ${freshness.thread_count}`);
|