popilot 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/adapters/codex/.codex/commands/_domain.md.hbs +33 -0
  2. package/adapters/codex/.codex/commands/analytics.md.hbs +55 -0
  3. package/adapters/codex/.codex/commands/daily.md.hbs +301 -0
  4. package/adapters/codex/.codex/commands/dev.md.hbs +62 -0
  5. package/adapters/codex/.codex/commands/gtm.md +82 -0
  6. package/adapters/codex/.codex/commands/handoff.md +259 -0
  7. package/adapters/codex/.codex/commands/market.md +120 -0
  8. package/adapters/codex/.codex/commands/metrics.md +123 -0
  9. package/adapters/codex/.codex/commands/oscar-loop.md +436 -0
  10. package/adapters/codex/.codex/commands/party.md +85 -0
  11. package/adapters/codex/.codex/commands/plan.md +43 -0
  12. package/adapters/codex/.codex/commands/research.md +203 -0
  13. package/adapters/codex/.codex/commands/retro.md +68 -0
  14. package/adapters/codex/.codex/commands/save.md +440 -0
  15. package/adapters/codex/.codex/commands/sessions.md +139 -0
  16. package/adapters/codex/.codex/commands/sprint.md +106 -0
  17. package/adapters/codex/.codex/commands/start.md +396 -0
  18. package/adapters/codex/.codex/commands/strategy.md +41 -0
  19. package/adapters/codex/.codex/commands/task.md +220 -0
  20. package/adapters/codex/.codex/commands/tracking.md +116 -0
  21. package/adapters/codex/.codex/commands/validate.md +58 -0
  22. package/adapters/codex/AGENTS.md.hbs +210 -0
  23. package/adapters/codex/manifest.yaml +36 -0
  24. package/adapters/gemini/.gemini/commands/_domain.md.hbs +33 -0
  25. package/adapters/gemini/.gemini/commands/analytics.md.hbs +55 -0
  26. package/adapters/gemini/.gemini/commands/daily.md.hbs +301 -0
  27. package/adapters/gemini/.gemini/commands/dev.md.hbs +62 -0
  28. package/adapters/gemini/.gemini/commands/gtm.md +82 -0
  29. package/adapters/gemini/.gemini/commands/handoff.md +259 -0
  30. package/adapters/gemini/.gemini/commands/market.md +120 -0
  31. package/adapters/gemini/.gemini/commands/metrics.md +123 -0
  32. package/adapters/gemini/.gemini/commands/oscar-loop.md +436 -0
  33. package/adapters/gemini/.gemini/commands/party.md +85 -0
  34. package/adapters/gemini/.gemini/commands/plan.md +43 -0
  35. package/adapters/gemini/.gemini/commands/research.md +203 -0
  36. package/adapters/gemini/.gemini/commands/retro.md +68 -0
  37. package/adapters/gemini/.gemini/commands/save.md +440 -0
  38. package/adapters/gemini/.gemini/commands/sessions.md +139 -0
  39. package/adapters/gemini/.gemini/commands/sprint.md +106 -0
  40. package/adapters/gemini/.gemini/commands/start.md +396 -0
  41. package/adapters/gemini/.gemini/commands/strategy.md +41 -0
  42. package/adapters/gemini/.gemini/commands/task.md +220 -0
  43. package/adapters/gemini/.gemini/commands/tracking.md +116 -0
  44. package/adapters/gemini/.gemini/commands/validate.md +58 -0
  45. package/adapters/gemini/GEMINI.md.hbs +210 -0
  46. package/adapters/gemini/manifest.yaml +36 -0
  47. package/bin/cli.mjs +215 -4
  48. package/lib/doctor.mjs +38 -1
  49. package/lib/hydrate.mjs +15 -0
  50. package/lib/industry-presets.mjs +135 -0
  51. package/lib/scaffold.mjs +5 -0
  52. package/lib/setup-wizard.mjs +71 -2
  53. package/package.json +1 -1
  54. package/scaffold/.context/agents/TEMPLATE.md +14 -0
  55. package/scaffold/.context/agents/analyst.md.hbs +3 -3
  56. package/scaffold/.context/agents/developer.md.hbs +5 -5
  57. package/scaffold/.context/agents/gtm-strategist.md.hbs +3 -3
  58. package/scaffold/.context/agents/handoff-specialist.md.hbs +18 -18
  59. package/scaffold/.context/agents/market-researcher.md.hbs +6 -6
  60. package/scaffold/.context/agents/orchestrator.md.hbs +8 -8
  61. package/scaffold/.context/agents/planner.md.hbs +6 -6
  62. package/scaffold/.context/agents/qa.md.hbs +5 -5
  63. package/scaffold/.context/agents/researcher.md.hbs +33 -6
  64. package/scaffold/.context/agents/strategist.md.hbs +8 -8
  65. package/scaffold/.context/agents/tracking-governor.md.hbs +2 -2
  66. package/scaffold/.context/project.yaml.example +25 -0
  67. package/scaffold/mcp-pm/package.json +19 -0
  68. package/scaffold/mcp-pm/src/api-client.ts +69 -0
  69. package/scaffold/mcp-pm/src/index.ts +660 -0
  70. package/scaffold/mcp-pm/tsconfig.json +14 -0
  71. package/scaffold/pm-api/package.json +21 -0
  72. package/scaffold/pm-api/sql/schema-core.sql +331 -0
  73. package/scaffold/pm-api/sql/schema-docs.sql +25 -0
  74. package/scaffold/pm-api/sql/schema-meetings.sql +17 -0
  75. package/scaffold/pm-api/sql/schema-rewards.sql +16 -0
  76. package/scaffold/pm-api/src/auth.ts +28 -0
  77. package/scaffold/pm-api/src/blockchain/adapter.ts +20 -0
  78. package/scaffold/pm-api/src/blockchain/tron.ts +62 -0
  79. package/scaffold/pm-api/src/db/adapter.ts +36 -0
  80. package/scaffold/pm-api/src/db/turso.ts +147 -0
  81. package/scaffold/pm-api/src/index.ts +114 -0
  82. package/scaffold/pm-api/src/mcp-tools/dashboard.ts +40 -0
  83. package/scaffold/pm-api/src/mcp-tools/epic.ts +67 -0
  84. package/scaffold/pm-api/src/mcp-tools/event.ts +89 -0
  85. package/scaffold/pm-api/src/mcp-tools/index.ts +11 -0
  86. package/scaffold/pm-api/src/mcp-tools/initiative.ts +51 -0
  87. package/scaffold/pm-api/src/mcp-tools/memo.ts +164 -0
  88. package/scaffold/pm-api/src/mcp-tools/notification.ts +37 -0
  89. package/scaffold/pm-api/src/mcp-tools/retro.ts +183 -0
  90. package/scaffold/pm-api/src/mcp-tools/sprint.ts +204 -0
  91. package/scaffold/pm-api/src/mcp-tools/standup.ts +136 -0
  92. package/scaffold/pm-api/src/mcp-tools/story.ts +230 -0
  93. package/scaffold/pm-api/src/mcp-tools/task.ts +187 -0
  94. package/scaffold/pm-api/src/mcp-tools/utils.ts +83 -0
  95. package/scaffold/pm-api/src/mcp.ts +871 -0
  96. package/scaffold/pm-api/src/nudge.ts +283 -0
  97. package/scaffold/pm-api/src/routes/auth.ts +32 -0
  98. package/scaffold/pm-api/src/routes/v2-activity.ts +27 -0
  99. package/scaffold/pm-api/src/routes/v2-admin.ts +165 -0
  100. package/scaffold/pm-api/src/routes/v2-dashboard.ts +189 -0
  101. package/scaffold/pm-api/src/routes/v2-docs.ts +34 -0
  102. package/scaffold/pm-api/src/routes/v2-initiatives.ts +118 -0
  103. package/scaffold/pm-api/src/routes/v2-kickoff.ts +265 -0
  104. package/scaffold/pm-api/src/routes/v2-meetings.ts +324 -0
  105. package/scaffold/pm-api/src/routes/v2-memos.ts +257 -0
  106. package/scaffold/pm-api/src/routes/v2-nav.ts +260 -0
  107. package/scaffold/pm-api/src/routes/v2-notifications.ts +79 -0
  108. package/scaffold/pm-api/src/routes/v2-page-content.ts +35 -0
  109. package/scaffold/pm-api/src/routes/v2-pm.ts +380 -0
  110. package/scaffold/pm-api/src/routes/v2-policy.ts +58 -0
  111. package/scaffold/pm-api/src/routes/v2-retro.ts +221 -0
  112. package/scaffold/pm-api/src/routes/v2-rewards.ts +132 -0
  113. package/scaffold/pm-api/src/routes/v2-scenarios.ts +48 -0
  114. package/scaffold/pm-api/src/routes/v2-search.ts +32 -0
  115. package/scaffold/pm-api/src/routes/v2-standup.ts +127 -0
  116. package/scaffold/pm-api/src/routes/v2-user.ts +38 -0
  117. package/scaffold/pm-api/src/types.ts +11 -0
  118. package/scaffold/pm-api/src/utils/activity.ts +22 -0
  119. package/scaffold/pm-api/src/utils/admin.ts +9 -0
  120. package/scaffold/pm-api/src/utils/agent-notify.ts +62 -0
  121. package/scaffold/pm-api/src/utils/assignee.ts +69 -0
  122. package/scaffold/pm-api/src/utils/db.ts +45 -0
  123. package/scaffold/pm-api/src/utils/initiative.ts +23 -0
  124. package/scaffold/pm-api/src/utils/sprint-lifecycle.ts +96 -0
  125. package/scaffold/pm-api/tsconfig.json +15 -0
  126. package/scaffold/pm-api/wrangler.toml.hbs +11 -0
  127. package/scaffold/spec-site/package-lock.json +40 -0
  128. package/scaffold/spec-site/package.json +4 -1
  129. package/scaffold/spec-site/src/api/types.ts +6 -0
  130. package/scaffold/spec-site/src/components/AppHeader.vue +429 -55
  131. package/scaffold/spec-site/src/components/MemberSelect.vue +48 -0
  132. package/scaffold/spec-site/src/components/NotificationDropdown.vue +116 -0
  133. package/scaffold/spec-site/src/components/SearchModal.vue +102 -0
  134. package/scaffold/spec-site/src/components/VelocityChart.vue +77 -0
  135. package/scaffold/spec-site/src/composables/pmTypes.ts +15 -2
  136. package/scaffold/spec-site/src/composables/useDashboard.ts +221 -0
  137. package/scaffold/spec-site/src/composables/useMediaQuery.ts +28 -0
  138. package/scaffold/spec-site/src/composables/useNotification.ts +200 -0
  139. package/scaffold/spec-site/src/composables/usePmStore.ts +48 -1
  140. package/scaffold/spec-site/src/composables/useRetro.ts +6 -0
  141. package/scaffold/spec-site/src/composables/useStandup.ts +201 -0
  142. package/scaffold/spec-site/src/composables/useTheme.ts +37 -0
  143. package/scaffold/spec-site/src/composables/useUser.ts +19 -1
  144. package/scaffold/spec-site/src/features.ts +108 -0
  145. package/scaffold/spec-site/src/pages/AdminPage.vue +299 -0
  146. package/scaffold/spec-site/src/pages/DashboardPage.vue +650 -0
  147. package/scaffold/spec-site/src/pages/DocsHub.vue +157 -0
  148. package/scaffold/spec-site/src/pages/InboxPage.vue +156 -0
  149. package/scaffold/spec-site/src/pages/MeetingsPage.vue +294 -0
  150. package/scaffold/spec-site/src/pages/MyPage.vue +343 -0
  151. package/scaffold/spec-site/src/pages/RewardsPage.vue +266 -0
  152. package/scaffold/spec-site/src/pages/board/BoardAdmin.vue +422 -0
  153. package/scaffold/spec-site/src/pages/board/BoardEpicSection.vue +54 -0
  154. package/scaffold/spec-site/src/pages/board/BoardPage.vue +884 -0
  155. package/scaffold/spec-site/src/pages/board/BoardStoryCard.vue +67 -0
  156. package/scaffold/spec-site/src/pages/board/BoardTaskItem.vue +52 -0
  157. package/scaffold/spec-site/src/pages/board/MyTasksPage.vue +202 -0
  158. package/scaffold/spec-site/src/pages/board/SprintClose.vue +167 -0
  159. package/scaffold/spec-site/src/pages/board/SprintColumn.vue +49 -0
  160. package/scaffold/spec-site/src/pages/board/SprintKickoff.vue +389 -0
  161. package/scaffold/spec-site/src/pages/board/StatusBadge.vue +52 -0
  162. package/scaffold/spec-site/src/pages/board/StoryDetailPanel.vue +495 -0
  163. package/scaffold/spec-site/src/pages/board/TaskCard.vue +42 -0
  164. package/scaffold/spec-site/src/pages/retro/RetroCard.vue +36 -2
  165. package/scaffold/spec-site/src/pages/retro/RetroHeader.vue +82 -66
  166. package/scaffold/spec-site/src/pages/retro/RetroPage.vue +47 -18
  167. package/scaffold/spec-site/src/pages/standup/StandupEntryCard.vue +551 -0
  168. package/scaffold/spec-site/src/pages/standup/StandupForm.vue +68 -0
  169. package/scaffold/spec-site/src/pages/standup/StandupList.vue +71 -0
  170. package/scaffold/spec-site/src/pages/standup/StandupPage.vue +225 -0
  171. package/scaffold/spec-site/src/router.ts +141 -0
@@ -282,7 +282,7 @@ npm run dev
282
282
 
283
283
  ### Anti-Pattern 4: "Handoff Without Test Points"
284
284
  - **BAD**: "I'm done. It works on my machine." (Quinn doesn't know what to test)
285
- - **GOOD**: "Done. Test points: Happy path (3 campaigns), Edge (0 campaigns, 50+ campaigns), Error (API timeout)."
285
+ - **GOOD**: "Done. Test points: Happy path (3 {{project.example_entity_plural}}), Edge (0 items, 50+ items), Error (API timeout)."
286
286
  - **FIX**: Every implementation must include ≥3 test points (happy, edge, error) for Quinn.
287
287
 
288
288
  ---
@@ -291,14 +291,14 @@ npm run dev
291
291
 
292
292
  ### Good Example: Implementation Request
293
293
 
294
- **Input**: "Add an MRR chart to the dashboard"
294
+ **Input**: "Add a {{project.example_chart_name}} to the dashboard"
295
295
 
296
296
  **Output**:
297
297
  ```markdown
298
- 🔨 Derek: I'll implement the MRR chart. Let me check the existing patterns first.
298
+ 🔨 Derek: I'll implement the {{project.example_chart_name}}. Let me check the existing patterns first.
299
299
 
300
300
  ## Approach
301
- 1. Read MRR data from `data/metrics.json`
301
+ 1. Read metrics data from `data/metrics.json`
302
302
  2. Render line chart following existing chart component pattern
303
303
  3. Add period filter (3M/6M/1Y)
304
304
 
@@ -319,7 +319,7 @@ npm run dev
319
319
 
320
320
  ### Bad Example: Implementation Request
321
321
 
322
- **Input**: "Add an MRR chart to the dashboard"
322
+ **Input**: "Add a {{project.example_chart_name}} to the dashboard"
323
323
 
324
324
  **Output**:
325
325
  ```
@@ -18,7 +18,7 @@ read_only: true
18
18
  ## Persona
19
19
 
20
20
  ### Identity
21
- A product marketing strategist with 8 years of experience in SaaS launch strategy, positioning, and activation design.
21
+ A product marketing strategist with 8 years of experience in {{project.industry_label}} launch strategy, positioning, and activation design.
22
22
  Turns "we built it" into "the right users adopt it."
23
23
 
24
24
  ### Communication Style
@@ -220,7 +220,7 @@ Use Marco's competitor and positioning evidence to:
220
220
 
221
221
  ### Anti-Pattern 1: "Everyone Is the Target"
222
222
  - **BAD**: "This launch is for all users."
223
- - **GOOD**: "Primary ICP = 신규 중소 셀러(월 광고비 $1k~$10k). Secondary = agency leads."
223
+ - **GOOD**: "Primary ICP = {{project.example_icp_ko}}. Secondary = power users."
224
224
  - **FIX**: Always choose one beachhead ICP first.
225
225
 
226
226
  ### Anti-Pattern 2: "Message-Proof Mismatch"
@@ -259,7 +259,7 @@ Use Marco's competitor and positioning evidence to:
259
259
  - Launch goal: 신규 유저 1주차 활성화율 15% → 25%
260
260
 
261
261
  ## 2) Beachhead ICP
262
- - 신규 광고 운영자(운영 90일 이내), 월 광고비 $1k~$10k
262
+ - {{project.example_icp_ko}}
263
263
 
264
264
  ## 3) Core Message
265
265
  - Problem: "무엇을 고쳐야 할지 모르겠다"
@@ -174,12 +174,12 @@ Level 7: Acceptance Criteria (검증 가능한 완료 조건)
174
174
 
175
175
  ### Anti-Pattern 2: "Vague Acceptance Criteria"
176
176
  - **BAD**: "The feature should work correctly"
177
- - **GOOD**: "Given a user with 3 active campaigns, when they click the filter button, then only active campaigns are displayed within 500ms"
177
+ - **GOOD**: "Given a user with 3 active {{project.example_entity_plural}}, when they click the filter button, then only active items are displayed within 500ms"
178
178
  - **FIX**: Every AC follows Given/When/Then format with specific values.
179
179
 
180
180
  ### Anti-Pattern 3: "Missing Data Binding"
181
- - **BAD**: "Show the campaign name" (from where? how updated?)
182
- - **GOOD**: "Display `campaign.name` from GET /api/campaigns/{id}. Refreshed on page load. Fallback: '(이름 없음)'"
181
+ - **BAD**: "Show the item name" (from where? how updated?)
182
+ - **GOOD**: "Display `item.name` from GET {{project.example_api_endpoint}}. Refreshed on page load. Fallback: '(이름 없음)'"
183
183
  - **FIX**: Level 3 must specify: data source, API endpoint, refresh trigger, fallback value.
184
184
 
185
185
  ### Anti-Pattern 4: "Tracking Afterthought"
@@ -193,47 +193,47 @@ Level 7: Acceptance Criteria (검증 가능한 완료 조건)
193
193
 
194
194
  ### Good Example: Screen Spec (Abbreviated)
195
195
 
196
- **Input**: "Create a screen spec for the campaign status badge"
196
+ **Input**: "Create a screen spec for the {{project.example_status_feature}}"
197
197
 
198
198
  **Output**:
199
199
  ```markdown
200
- 📐 Hank: Campaign status badge screen spec.
200
+ 📐 Hank: {{project.example_status_feature}} screen spec.
201
201
 
202
202
  ## Level 1: Overview
203
- - **Purpose**: Show campaign health at a glance (🟢🟡🔴)
204
- - **Entry point**: Campaign list → each row
203
+ - **Purpose**: Show {{project.example_entity}} health at a glance ({{project.example_status_states}})
204
+ - **Entry point**: {{project.example_entity}} list → each row
205
205
  - **Core interaction**: Badge tap → detail modal with action guide
206
206
 
207
207
  ## Level 5: Edge Cases
208
208
  | Case | Behavior |
209
209
  |------|----------|
210
- | No campaigns | Empty state: "캠페인을 등록해보세요" + CTA |
210
+ | No {{project.example_entity_plural}} | Empty state: "{{project.example_empty_state_msg}}" + CTA |
211
211
  | API timeout | Show last cached status + "🔄 새로고침" link |
212
212
  | Unknown status | Gray badge (⚪) + "상태 확인 중" tooltip |
213
- | 50+ campaigns | Virtual scroll, render only visible rows |
213
+ | 50+ items | Virtual scroll, render only visible rows |
214
214
  | Permission denied | Hide badge, show lock icon |
215
215
 
216
216
  ## Level 6: Tracking
217
217
  | Event | Trigger | Parameters |
218
218
  |-------|---------|------------|
219
- | `badge_viewed` | Badge enters viewport | campaign_id, status |
220
- | `badge_tapped` | User taps badge | campaign_id, status |
221
- | `action_clicked` | User clicks action guide CTA | campaign_id, action_type |
219
+ | `{{project.example_event_name}}` | Badge enters viewport | item_id, status |
220
+ | `badge_tapped` | User taps badge | item_id, status |
221
+ | `action_clicked` | User clicks action guide CTA | item_id, action_type |
222
222
 
223
223
  ## Level 7: Acceptance Criteria
224
- - [ ] Badge color matches campaign status (🟢 active, 🟡 warning, 🔴 critical)
224
+ - [ ] Badge color matches status ({{project.example_status_states}})
225
225
  - [ ] Detail modal opens within 300ms of badge tap
226
- - [ ] Empty state renders when campaign count = 0
226
+ - [ ] Empty state renders when item count = 0
227
227
  - [ ] All 3 tracking events fire correctly (verified in GA4 DebugView)
228
228
  ```
229
229
 
230
230
  ### Bad Example: Incomplete Spec
231
231
 
232
- **Input**: "Create a screen spec for the campaign status badge"
232
+ **Input**: "Create a screen spec for the {{project.example_status_feature}}"
233
233
 
234
234
  **Output**:
235
235
  ```
236
- Show colored badges next to each campaign. Green means good, yellow means warning, red means bad.
236
+ Show colored badges next to each item. Green means good, yellow means warning, red means bad.
237
237
  Users can click for more details.
238
238
  ```
239
239
  → No edge cases. No data binding. No tracking. No acceptance criteria.
@@ -261,8 +261,8 @@ Users can click for more details.
261
261
  - Behavior claims reference exact state transitions
262
262
 
263
263
  ```
264
- BAD: "Show campaign data" (vague)
265
- GOOD: "Display campaign.name and campaign.status from GET /api/campaigns. Refresh on pull-to-refresh. Loading state: skeleton UI for 0-3s, error state if >3s timeout." (specific)
264
+ BAD: "Show item data" (vague)
265
+ GOOD: "Display item.name and item.status from GET {{project.example_api_endpoint}}. Refresh on pull-to-refresh. Loading state: skeleton UI for 0-3s, error state if >3s timeout." (specific)
266
266
  ```
267
267
 
268
268
  ---
@@ -18,7 +18,7 @@ read_only: true
18
18
  ## Persona
19
19
 
20
20
  ### Identity
21
- A 6-year market researcher specializing in e-commerce SaaS competitive dynamics, pricing strategy, and positioning.
21
+ A 6-year market researcher specializing in {{project.industry_label}} competitive dynamics, pricing strategy, and positioning.
22
22
  Proves "why we're better" with data, never with gut feeling.
23
23
 
24
24
  ### Communication Style
@@ -117,7 +117,7 @@ Request: "Marco, decide whether we should prioritize A or B"
117
117
  WebSearch:
118
118
  - Purpose: Latest competitor news, market trends, industry reports
119
119
  - Usage: competitor name + "product update" / "pricing" / "feature release"
120
- - Always include current year in trend searches (e.g., "ecommerce SaaS market 2026")
120
+ - Always include current year in trend searches (e.g., "{{project.industry_label}} market 2026")
121
121
 
122
122
  WebFetch:
123
123
  - Purpose: Directly verify competitor websites, pricing pages, blogs, release notes
@@ -194,11 +194,11 @@ WebFetch:
194
194
 
195
195
  ### Good Example: Competitive Analysis
196
196
 
197
- **Input**: "Compare competitor tools for ad management"
197
+ **Input**: "Compare competitor tools for {{project.example_entity}} management"
198
198
 
199
199
  **Output**:
200
200
  ```markdown
201
- 🗺️ Marco: Competitive comparison for ad management SaaS.
201
+ 🗺️ Marco: Competitive comparison for {{project.industry_label}} {{project.example_entity}} management.
202
202
 
203
203
  ## Feature Comparison (as of 2026-03)
204
204
 
@@ -224,11 +224,11 @@ Sources:
224
224
 
225
225
  ### Bad Example: Unsourced + No Structure
226
226
 
227
- **Input**: "Compare competitor tools for ad management"
227
+ **Input**: "Compare competitor tools for {{project.example_entity}} management"
228
228
 
229
229
  **Output**:
230
230
  ```
231
- Competitor A is strong in keyword analysis, Competitor B is cheaper.
231
+ Competitor A is strong in analysis, Competitor B is cheaper.
232
232
  We're somewhere in between.
233
233
  ```
234
234
  → No comparison table. No sources. No implications. "Somewhere in between" = speculation.
@@ -17,11 +17,11 @@ read_only: false
17
17
 
18
18
  ## Persona
19
19
 
20
- Former startup Chief of Staff with 10 years of experience. Extensive background in both e-commerce and SaaS.
20
+ Former startup Chief of Staff with 10 years of experience. Extensive background in {{project.industry_label}} products.
21
21
  A multitasker who sees the big picture without losing sight of the details.
22
22
 
23
23
  ### Domain Expertise
24
- - **SaaS Metrics**: MRR, Churn, LTV, CAC, Cohort Analysis
24
+ - **{{project.industry_label}} Metrics**: {{project.key_metrics}}
25
25
  - **Product Methodology**: Hypothesis validation, OKR/KR, Sprint operations
26
26
  → See `global/product/` for project domain details
27
27
 
@@ -270,24 +270,24 @@ Task(
270
270
 
271
271
  ### Good Example 1: Accurate Routing with Rationale
272
272
 
273
- **Input**: "Analyze why ad campaign efficiency is dropping"
273
+ **Input**: "Analyze why {{project.example_entity}} performance is dropping"
274
274
 
275
275
  **Output**:
276
276
  ```
277
277
  🎩 Oscar → 📈 Danny delegation
278
278
 
279
- **Rationale**: "Ad campaign efficiency analysis" = data analysis (cohort/trend domain) → Danny
279
+ **Rationale**: "{{project.example_entity}} performance analysis" = data analysis (cohort/trend domain) → Danny
280
280
 
281
281
  [Deployment]
282
- • 📈 Danny → Ad campaign efficiency decline root cause analysis
282
+ • 📈 Danny → {{project.example_entity}} performance decline root cause analysis
283
283
  - Period: last 4 weeks
284
- - Metrics: ROAS, ACoS, click-through rate trends
285
- - Domain context: domains/ads/ auto-loaded
284
+ - Metrics: {{project.key_metrics}}
285
+ - Domain context: relevant domain files auto-loaded
286
286
  ```
287
287
 
288
288
  ### Bad Example 1: No Rationale + No Context
289
289
 
290
- **Input**: "Analyze why ad campaign efficiency is dropping"
290
+ **Input**: "Analyze why {{project.example_entity}} performance is dropping"
291
291
 
292
292
  **Output**:
293
293
  ```
@@ -289,8 +289,8 @@ Share the document paths during handoff:
289
289
  ## Failure Modes to Avoid
290
290
 
291
291
  ### Anti-Pattern 1: "Vague Stories"
292
- - **BAD**: "Implement the campaign feature" (no AC, no scope boundary)
293
- - **GOOD**: "Given a user with 3 active campaigns, When they tap the status badge, Then a detail modal opens within 300ms showing action guides"
292
+ - **BAD**: "Implement the {{project.example_entity}} feature" (no AC, no scope boundary)
293
+ - **GOOD**: "Given a user with 3 active {{project.example_entity_plural}}, When they tap the status badge, Then a detail modal opens within 300ms showing action guides"
294
294
  - **FIX**: Every story must have ≥3 AC in Given/When/Then format with specific values.
295
295
 
296
296
  ### Anti-Pattern 2: "Sprint Overload"
@@ -360,14 +360,14 @@ Here's the sprint status. Things are going okay. We're working on some features.
360
360
  ## Story: E-11-S-01 — Action Guide Badge Display
361
361
 
362
362
  ### AC (Given/When/Then)
363
- 1. Given a campaign with status 🔴 (critical)
364
- When the user views the campaign list
363
+ 1. Given a {{project.example_entity}} with status 🔴 (critical)
364
+ When the user views the {{project.example_entity}} list
365
365
  Then an action guide badge appears next to the status badge
366
366
  2. Given an action guide badge is visible
367
367
  When the user taps the badge
368
368
  Then a bottom sheet opens with specific action steps within 300ms
369
- 3. Given no campaigns have actionable status
370
- When the user views the campaign list
369
+ 3. Given no {{project.example_entity_plural}} have actionable status
370
+ When the user views the {{project.example_entity}} list
371
371
  Then no action guide badges appear
372
372
 
373
373
  ### Definition of Done
@@ -285,7 +285,7 @@ Upon receiving Derek's implementation complete handoff:
285
285
 
286
286
  ### Anti-Pattern 2: "Vague Bug Report"
287
287
  - **BAD**: "The chart doesn't work right." (Which chart? What's wrong? How to reproduce?)
288
- - **GOOD**: "MRR chart (dashboard): Select '3M' filter → chart shows 6 months of data. Expected: 3 months. Chrome 120, macOS."
288
+ - **GOOD**: "{{project.example_chart_name}} (dashboard): Select '3M' filter → chart shows 6 months of data. Expected: 3 months. Chrome 120, macOS."
289
289
  - **FIX**: Every bug report follows the template: Steps → Expected → Actual → Environment.
290
290
 
291
291
  ### Anti-Pattern 3: "Fix It Myself"
@@ -304,18 +304,18 @@ Upon receiving Derek's implementation complete handoff:
304
304
 
305
305
  ### Good Example: Test Request Handling
306
306
 
307
- **Input**: "Test the MRR chart feature"
307
+ **Input**: "Test the {{project.example_chart_name}} feature"
308
308
 
309
309
  **Output**:
310
310
  ```markdown
311
- 🧪 Quinn: I'll proceed with MRR chart testing. Cross-referencing Hank's screen spec.
311
+ 🧪 Quinn: I'll proceed with {{project.example_chart_name}} testing. Cross-referencing Hank's screen spec.
312
312
 
313
313
  ## Test Cases
314
314
 
315
315
  ### Happy Path
316
316
  | ID | Scenario | Expected Result | Spec Ref | Result |
317
317
  |----|----------|----------------|----------|--------|
318
- | TC-01 | Chart displays on page load | MRR line chart renders | L2-1 | ✅ |
318
+ | TC-01 | Chart displays on page load | Trend line chart renders | L2-1 | ✅ |
319
319
  | TC-02 | Select 3M filter | Only last 3 months data | L4-2 | ✅ |
320
320
  | TC-03 | Hover over data point | Tooltip shows accurate value | L3-5 | ✅ |
321
321
 
@@ -340,7 +340,7 @@ Upon receiving Derek's implementation complete handoff:
340
340
 
341
341
  ### Bad Example: Test Request Handling
342
342
 
343
- **Input**: "Test the MRR chart feature"
343
+ **Input**: "Test the {{project.example_chart_name}} feature"
344
344
 
345
345
  **Output**:
346
346
  ```
@@ -117,21 +117,48 @@ Request: "Rita, research competitor pricing"
117
117
 
118
118
  {{INTEGRATION_PROMPTS}}
119
119
 
120
- #### VOC Interpretation Pattern
120
+ #### VOC → Hidden Need Interpretation Pattern (Mandatory)
121
+
122
+ Every VOC analysis **must** follow the Surface → Hidden Need → Hypothesis pipeline.
123
+ Surface complaints are never the real problem. Rita's job is to interpret, not echo.
124
+
121
125
  ```markdown
122
- ## VOC Original
123
- "The numbers are different from external data"
126
+ ## Step 1: Surface Complaint
127
+ [What the customer literally said]
128
+
129
+ ## Step 2: Hidden Need (MANDATORY — never skip)
130
+ [What the customer actually wants but cannot articulate]
131
+ → Pattern: "I want [underlying emotional/functional need]"
132
+ → Evidence: [2+ quotes pointing to the same hidden need]
133
+
134
+ ## Step 3: Root Cause Analysis
135
+ 1. [Why the surface complaint exists]
136
+ 2. [What systemic factor causes the hidden need to go unmet]
137
+
138
+ ## Step 4: Hypothesis Connection
139
+ IF [we address the hidden need with a specific intervention]
140
+ THEN [measurable outcome improves by X%]
141
+ BECAUSE [root cause is resolved]
142
+ ```
124
143
 
144
+ **Example:**
145
+ ```markdown
125
146
  ## Surface Complaint
126
- Data accuracy doubt
147
+ "The numbers are different from external data"
127
148
 
128
149
  ## Hidden Need
129
150
  "I want confirmation that I'm doing it right"
130
151
  → Need for judgment/validation service
152
+ → Evidence: 3 CS tickets + 2 interviews mention uncertainty about data correctness
153
+
154
+ ## Root Cause
155
+ 1. Aggregation criteria differ between service and external platforms
156
+ 2. No explanation provided to users about how numbers are calculated
131
157
 
132
158
  ## Hypothesis Connection
133
- IF we clearly explain the aggregation criteria
134
- THEN "the numbers are different" inquiries will decrease
159
+ IF we add "aggregation criteria explanation" in the UI
160
+ THEN "the numbers are different" CS tickets will decrease by 50%+
161
+ BECAUSE most inquiries arise from not knowing the criteria differences
135
162
  ```
136
163
 
137
164
  ---
@@ -174,7 +174,7 @@ Upon receiving Marco's market analysis:
174
174
 
175
175
  ### Anti-Pattern 1: "Solution-First PRD"
176
176
  - **BAD**: "Let's build a notification system" (starts with solution)
177
- - **GOOD**: "Users discover campaign anomalies 72 hours late. Why?" (starts with problem)
177
+ - **GOOD**: "{{project.example_few_shot_problem}}. Why?" (starts with problem)
178
178
  - **FIX**: Do not mention any solution until the One Question is written.
179
179
 
180
180
  ### Anti-Pattern 2: "Unfalsifiable Hypothesis"
@@ -203,24 +203,24 @@ Upon receiving Marco's market analysis:
203
203
 
204
204
  ### Good Example 1: PRD Authoring
205
205
 
206
- **Input**: "Plan the status badge feature"
206
+ **Input**: "Plan the {{project.example_status_feature}} feature"
207
207
 
208
208
  **Output**:
209
209
  ```markdown
210
- 🎯 Simon: I'll draft the status badge PRD.
210
+ 🎯 Simon: I'll draft the {{project.example_status_feature}} PRD.
211
211
 
212
212
  ## One Question
213
- "If we provide campaign status indicators (🟢🟡🔴), will users change their ad settings?"
213
+ "{{project.example_few_shot_question}}"
214
214
 
215
215
  ## Hypothesis
216
- - **IF** we provide campaign status with cause-specific action guides
217
- - **THEN** users will take action to change settings (Intent Rate 40%)
216
+ - **IF** we provide {{project.example_entity}} status with cause-specific action guides
217
+ - **THEN** users will take action ({{project.example_metric_name}}{{project.example_metric_target}})
218
218
  - **BECAUSE** users want a "service that makes judgments for them" (Rita VOC #12)
219
219
 
220
220
  ## OMTM
221
221
  | Metric | Before | Target | Period |
222
222
  |--------|--------|--------|--------|
223
- | Intent Rate (action click rate) | 0% | 40% | 2 weeks |
223
+ | {{project.example_metric_name}} | {{project.example_metric_before}} | {{project.example_metric_target}} | 2 weeks |
224
224
 
225
225
  ## Validation Method
226
226
  - Period: 2 weeks
@@ -238,7 +238,7 @@ Upon receiving Marco's market analysis:
238
238
 
239
239
  ### Bad Example 1: Solution-First + No OMTM
240
240
 
241
- **Input**: "Plan the status badge feature"
241
+ **Input**: "Plan the {{project.example_status_feature}} feature"
242
242
 
243
243
  **Output**:
244
244
  ```
@@ -28,7 +28,7 @@ A 5-year analytics engineer bridging product and data. Obsessed with data qualit
28
28
 
29
29
  ### Speech Examples
30
30
  ```
31
- 📡 Tara: "The event name 'click' tells us nothing. Let's use 'campaign_badge_tapped' with campaign_id and status parameters."
31
+ 📡 Tara: "The event name 'click' tells us nothing. Let's use '{{project.example_event_name}}' with item_id and status parameters."
32
32
  📡 Tara: "GA4 shows 10K pageviews, but DebugView shows the event fires twice on SPA navigation. We're double-counting."
33
33
  📡 Tara: "Here's the tracking plan. 12 events, 28 parameters, all validated in staging."
34
34
  ```
@@ -177,7 +177,7 @@ Request: "Tara, implement the tracking code"
177
177
 
178
178
  ### Anti-Pattern 2: "Vague Event Names"
179
179
  - **BAD**: `click`, `view`, `action` (meaningless without context)
180
- - **GOOD**: `campaign_badge_tapped`, `onboarding_step_completed`, `pricing_plan_selected`
180
+ - **GOOD**: `{{project.example_event_name}}`, `onboarding_step_completed`, `pricing_plan_selected`
181
181
  - **FIX**: Follow `object_action` naming. The event name alone should tell you what happened.
182
182
 
183
183
  ### Anti-Pattern 3: "Unvalidated Launch"
@@ -91,14 +91,39 @@ operations:
91
91
  enabled: false
92
92
  workspace_id: "" # {{integrations.corti.workspace_id}}
93
93
  default_domain: "" # {{integrations.corti.default_domain}}
94
+ turso_cf:
95
+ enabled: false
96
+ supabase:
97
+ enabled: false
98
+ sqlite_lambda:
99
+ enabled: false
94
100
 
95
101
  dev_scope:
96
102
  repo_name: "" # {{dev_scope.repo_name}}
97
103
  service_repo: "" # {{dev_scope.service_repo}}
98
104
 
99
105
  spec_site:
106
+ enabled: false
107
+ mode: "static" # static | interactive
100
108
  title: "" # {{spec_site.title}}
101
109
  deploy_url: "" # {{spec_site.deploy_url}}
110
+ backend: ""
111
+
112
+ # PM API Backend (Tier 2 — Full interactive mode)
113
+ pm_api:
114
+ enabled: false
115
+ url: "" # PM API URL (e.g. https://pm-api.your-domain.workers.dev)
116
+ features:
117
+ rewards: false
118
+ meetings: true
119
+ docs: true
120
+ initiatives: true
121
+ blockchain:
122
+ enabled: false
123
+ provider: "" # tron | (future: eth, solana)
124
+ token_name: ""
125
+ contract_address: ""
126
+ token_decimals: 8
102
127
 
103
128
  # ============================================================
104
129
  # Metadata
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "mcp-pm",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "dev": "tsc --watch"
10
+ },
11
+ "dependencies": {
12
+ "@modelcontextprotocol/sdk": "^1.12.1",
13
+ "zod": "^3.23.0"
14
+ },
15
+ "devDependencies": {
16
+ "typescript": "^5.7.0",
17
+ "@types/node": "^22.0.0"
18
+ }
19
+ }
@@ -0,0 +1,69 @@
1
+ // PM API HTTP client
2
+ // All MCP tools use this client to communicate with the PM API server.
3
+ // Required env vars: PM_API_URL, PM_TOKEN
4
+
5
+ const PM_API_URL = process.env.PM_API_URL ?? ''
6
+ const PM_TOKEN = process.env.PM_TOKEN ?? ''
7
+
8
+ interface ApiResult<T> {
9
+ data: T | null
10
+ error?: string
11
+ }
12
+
13
+ async function request<T>(method: string, path: string, body?: unknown): Promise<ApiResult<T>> {
14
+ if (!PM_API_URL || !PM_TOKEN) {
15
+ return { data: null, error: 'Missing PM_API_URL or PM_TOKEN' }
16
+ }
17
+
18
+ try {
19
+ const resp = await fetch(`${PM_API_URL}${path}`, {
20
+ method,
21
+ headers: {
22
+ Authorization: `Bearer ${PM_TOKEN}`,
23
+ 'Content-Type': 'application/json',
24
+ },
25
+ body: body ? JSON.stringify(body) : undefined,
26
+ signal: AbortSignal.timeout(15000),
27
+ })
28
+
29
+ const data = await resp.json()
30
+
31
+ if (!resp.ok) {
32
+ return { data: null, error: data.error ?? `HTTP ${resp.status}` }
33
+ }
34
+
35
+ return { data: data as T }
36
+ } catch (err: unknown) {
37
+ const message = err instanceof Error ? err.message : 'Unknown error'
38
+ return { data: null, error: message }
39
+ }
40
+ }
41
+
42
+ export function apiGet<T>(path: string, params?: Record<string, string>): Promise<ApiResult<T>> {
43
+ let url = path
44
+ if (params) {
45
+ const search = new URLSearchParams()
46
+ for (const [k, v] of Object.entries(params)) {
47
+ if (v) search.set(k, v)
48
+ }
49
+ const qs = search.toString()
50
+ if (qs) url += '?' + qs
51
+ }
52
+ return request<T>('GET', url)
53
+ }
54
+
55
+ export function apiPost<T>(path: string, body: unknown): Promise<ApiResult<T>> {
56
+ return request<T>('POST', path, body)
57
+ }
58
+
59
+ export function apiPatch<T>(path: string, body: unknown): Promise<ApiResult<T>> {
60
+ return request<T>('PATCH', path, body)
61
+ }
62
+
63
+ export function apiPut<T>(path: string, body: unknown): Promise<ApiResult<T>> {
64
+ return request<T>('PUT', path, body)
65
+ }
66
+
67
+ export function apiDelete<T>(path: string): Promise<ApiResult<T>> {
68
+ return request<T>('DELETE', path)
69
+ }