taketomarket 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/.claude-plugin/plugin.json +10 -0
  2. package/LICENSE +21 -0
  3. package/README.md +419 -0
  4. package/agents/ttm-producer.md +53 -0
  5. package/bin/lib/campaign.cjs +553 -0
  6. package/bin/lib/commit.cjs +105 -0
  7. package/bin/lib/core.cjs +172 -0
  8. package/bin/lib/deviation.cjs +149 -0
  9. package/bin/lib/drift-log.cjs +219 -0
  10. package/bin/lib/health.cjs +438 -0
  11. package/bin/lib/slug.cjs +59 -0
  12. package/bin/lib/state.cjs +96 -0
  13. package/bin/ttm-tools.cjs +157 -0
  14. package/gates/base-gates.md +266 -0
  15. package/gates/discipline/.gitkeep +0 -0
  16. package/gates/gate-evaluation.md +341 -0
  17. package/gates/meta-gates.md +19 -0
  18. package/install.js +307 -0
  19. package/package.json +53 -0
  20. package/playbooks/.gitkeep +0 -0
  21. package/playbooks/aeo.md +223 -0
  22. package/playbooks/affiliate.md +272 -0
  23. package/playbooks/base.md +110 -0
  24. package/playbooks/email.md +306 -0
  25. package/playbooks/events.md +320 -0
  26. package/playbooks/linkedin.md +263 -0
  27. package/playbooks/paid-ads.md +318 -0
  28. package/playbooks/pr-media.md +296 -0
  29. package/playbooks/seo.md +284 -0
  30. package/playbooks/social.md +305 -0
  31. package/playbooks/youtube.md +325 -0
  32. package/references/context-loading.md +107 -0
  33. package/references/learnings-extraction.md +94 -0
  34. package/references/measurement-template.md +48 -0
  35. package/references/meta-gate-evaluation.md +169 -0
  36. package/references/positioning-check-report.md +197 -0
  37. package/references/review-checklist.md +78 -0
  38. package/references/ship-checklist-items.md +94 -0
  39. package/settings.json +4 -0
  40. package/skills/ttm-aeo-check/SKILL.md +20 -0
  41. package/skills/ttm-affiliate-kit/SKILL.md +19 -0
  42. package/skills/ttm-archive/SKILL.md +13 -0
  43. package/skills/ttm-brand-refresh/SKILL.md +19 -0
  44. package/skills/ttm-brief/SKILL.md +14 -0
  45. package/skills/ttm-competitor-scan/SKILL.md +19 -0
  46. package/skills/ttm-email-preflight/SKILL.md +19 -0
  47. package/skills/ttm-fix/SKILL.md +13 -0
  48. package/skills/ttm-health/SKILL.md +12 -0
  49. package/skills/ttm-icp-refresh/SKILL.md +19 -0
  50. package/skills/ttm-init/SKILL.md +12 -0
  51. package/skills/ttm-keyword-map/SKILL.md +19 -0
  52. package/skills/ttm-learn/SKILL.md +14 -0
  53. package/skills/ttm-measure/SKILL.md +14 -0
  54. package/skills/ttm-new-campaign/SKILL.md +13 -0
  55. package/skills/ttm-next/SKILL.md +12 -0
  56. package/skills/ttm-positioning-check/SKILL.md +19 -0
  57. package/skills/ttm-positioning-shift/SKILL.md +19 -0
  58. package/skills/ttm-produce/SKILL.md +14 -0
  59. package/skills/ttm-repurpose/SKILL.md +20 -0
  60. package/skills/ttm-research/SKILL.md +13 -0
  61. package/skills/ttm-resume/SKILL.md +13 -0
  62. package/skills/ttm-review/SKILL.md +13 -0
  63. package/skills/ttm-seo-audit/SKILL.md +20 -0
  64. package/skills/ttm-ship/SKILL.md +13 -0
  65. package/skills/ttm-state/SKILL.md +13 -0
  66. package/skills/ttm-verify/SKILL.md +14 -0
  67. package/templates/agents-md.md +65 -0
  68. package/templates/campaign-brief.md +74 -0
  69. package/templates/campaign-research.md +39 -0
  70. package/templates/campaign-state.md +40 -0
  71. package/templates/claude-md.md +65 -0
  72. package/templates/deviation-log.md +12 -0
  73. package/templates/drift-log.md +17 -0
  74. package/templates/fix-brief.md +59 -0
  75. package/templates/fix-log.md +22 -0
  76. package/templates/measurement-report.md +75 -0
  77. package/templates/migration-plan.md +24 -0
  78. package/templates/production-manifest.json +20 -0
  79. package/templates/reference-files/brand.md +45 -0
  80. package/templates/reference-files/calendar.md +30 -0
  81. package/templates/reference-files/channels.md +40 -0
  82. package/templates/reference-files/competitors.md +40 -0
  83. package/templates/reference-files/icp.md +50 -0
  84. package/templates/reference-files/learnings.md +40 -0
  85. package/templates/reference-files/metrics.md +42 -0
  86. package/templates/reference-files/positioning.md +38 -0
  87. package/templates/reference-files/state.md +27 -0
  88. package/templates/verification-report.md +59 -0
  89. package/workflows/discipline/.gitkeep +0 -0
  90. package/workflows/discipline/aeo-check.md +180 -0
  91. package/workflows/discipline/affiliate-kit.md +147 -0
  92. package/workflows/discipline/email-preflight.md +150 -0
  93. package/workflows/discipline/keyword-map.md +125 -0
  94. package/workflows/discipline/repurpose.md +329 -0
  95. package/workflows/discipline/seo-audit.md +169 -0
  96. package/workflows/lifecycle/.gitkeep +0 -0
  97. package/workflows/lifecycle/brief-positioning-check.md +90 -0
  98. package/workflows/lifecycle/brief.md +355 -0
  99. package/workflows/lifecycle/fix.md +495 -0
  100. package/workflows/lifecycle/learn.md +405 -0
  101. package/workflows/lifecycle/measure.md +379 -0
  102. package/workflows/lifecycle/produce.md +383 -0
  103. package/workflows/lifecycle/research.md +264 -0
  104. package/workflows/lifecycle/review.md +432 -0
  105. package/workflows/lifecycle/ship.md +521 -0
  106. package/workflows/lifecycle/verify.md +507 -0
  107. package/workflows/reference-mgmt/.gitkeep +0 -0
  108. package/workflows/reference-mgmt/brand-refresh.md +193 -0
  109. package/workflows/reference-mgmt/competitor-scan.md +228 -0
  110. package/workflows/reference-mgmt/icp-refresh.md +200 -0
  111. package/workflows/reference-mgmt/positioning-check.md +339 -0
  112. package/workflows/reference-mgmt/positioning-shift.md +368 -0
  113. package/workflows/setup/.gitkeep +0 -0
  114. package/workflows/setup/init-questions.md +225 -0
  115. package/workflows/setup/init-validation.md +155 -0
  116. package/workflows/setup/init.md +449 -0
  117. package/workflows/setup/new-campaign.md +134 -0
  118. package/workflows/utility/.gitkeep +0 -0
  119. package/workflows/utility/archive.md +334 -0
  120. package/workflows/utility/health.md +166 -0
  121. package/workflows/utility/next.md +187 -0
  122. package/workflows/utility/resume.md +249 -0
  123. package/workflows/utility/state.md +207 -0
@@ -0,0 +1,249 @@
1
+ <purpose>
2
+ Session recovery workflow for /ttm-resume. Loads campaign state, shows context
3
+ summary (last completed phase, what was done, pending work, blockers), and suggests
4
+ the exact next /ttm-* command. Detects interrupted verify/fix loops so the user
5
+ continues from where they left off rather than restarting.
6
+
7
+ State is loaded directly from CAMPAIGNS/<slug>/STATE.md (no separate handoff file).
8
+ </purpose>
9
+
10
+ <required_reading>
11
+ @${CLAUDE_PLUGIN_ROOT}/references/context-loading.md
12
+ </required_reading>
13
+
14
+ <constraints>
15
+ ## POSITIONING.md is READ-ONLY
16
+
17
+ **Do NOT modify `.marketing/POSITIONING.md` during this workflow.**
18
+
19
+ POSITIONING.md is an architectural invariant. If you detect positioning drift:
20
+ - In verify: use the Escalate option to launch /ttm-positioning-shift
21
+ - In other workflows: flag the issue and recommend running /ttm-positioning-check
22
+
23
+ Only /ttm-positioning-shift and /ttm-init may modify POSITIONING.md.
24
+
25
+ ## Read-Only Command
26
+
27
+ This workflow does NOT modify any files. It is purely informational -- it reads
28
+ campaign state and displays a recovery summary. The user runs the suggested next
29
+ command themselves.
30
+ </constraints>
31
+
32
+ <process>
33
+
34
+ ## Step 1: Load Context
35
+
36
+ ```
37
+ takeToMarket > LOADING CONTEXT
38
+ ```
39
+
40
+ Extract SLUG from $ARGUMENTS (strip `--text` flag if present):
41
+ ```bash
42
+ SLUG=$(echo "$ARGUMENTS" | sed 's/--text//g' | xargs)
43
+ ```
44
+
45
+ If SLUG is empty, error:
46
+ "Usage: /ttm-resume [campaign-slug]. Provide a campaign slug."
47
+ Exit.
48
+
49
+ ---
50
+
51
+ ## Step 2: Load Campaign State
52
+
53
+ ```
54
+ takeToMarket > LOADING CAMPAIGN STATE
55
+ ```
56
+
57
+ Run:
58
+ ```bash
59
+ node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign state "${SLUG}" --raw
60
+ ```
61
+
62
+ If `exists: false`: tell user campaign not found. Suggest `/ttm-new-campaign` to
63
+ create a new campaign. Exit.
64
+
65
+ Parse the full JSON output. Extract:
66
+ - `phase` (current campaign phase)
67
+ - `name` (campaign display name)
68
+ - `last_updated` (ISO timestamp of last state change)
69
+ - All `phase.*` timestamps (phase.created, phase.researched, phase.briefed,
70
+ phase.produced, phase.verified, phase.reviewed, phase.fixed, phase.shipped,
71
+ phase.measured, phase.learned)
72
+ - `fix.run_count` (number of fix loop iterations)
73
+ - `review.overall_result` (approved, revise, or null)
74
+ - `verify.overall_result` (pass, fail, or null)
75
+ - `verify.run_count` (number of verification runs)
76
+
77
+ Also read the FULL STATE.md file (not just CLI output) to get body content:
78
+ ```bash
79
+ Read .marketing/CAMPAIGNS/${SLUG}/STATE.md
80
+ ```
81
+
82
+ The body contains "Phase:" and "Next step:" lines plus any additional notes,
83
+ blockers, or context left by previous workflow runs.
84
+
85
+ **Fallback:** If the Read tool returns empty or fails, log "No additional notes
86
+ recorded in STATE.md body" and continue with CLI-parsed state only. Do NOT fail
87
+ the resume workflow due to a missing or empty body section.
88
+
89
+ ---
90
+
91
+ ## Step 3: Build Recovery Context
92
+
93
+ ```
94
+ takeToMarket > RECOVERY CONTEXT
95
+ ```
96
+
97
+ Determine last completed phase by finding the latest non-null `phase.*` timestamp.
98
+ Use this ordering (earlier phases first):
99
+
100
+ 1. created
101
+ 2. researched
102
+ 3. briefed
103
+ 4. produced
104
+ 5. verified
105
+ 6. reviewed
106
+ 7. fixed
107
+ 8. shipped
108
+ 9. measured
109
+ 10. learned
110
+
111
+ For each completed phase, note the timestamp.
112
+
113
+ Calculate time since last activity from `last_updated`:
114
+ - If less than 1 hour: "X minutes ago"
115
+ - If less than 24 hours: "X hours ago"
116
+ - If less than 7 days: "X days ago"
117
+ - Otherwise: "X weeks ago" or exact date
118
+
119
+ ---
120
+
121
+ ## Step 4: Detect Interrupted Loops
122
+
123
+ Check if campaign is mid-fix-loop:
124
+ - `fix.run_count` exists AND is > 0
125
+ - AND `review.overall_result` equals `'revise'`
126
+
127
+ If yes: flag as interrupted fix loop. The user should run `/ttm-fix ${SLUG}` to
128
+ continue the loop (NOT restart from scratch). Note the current attempt number.
129
+
130
+ Check if campaign is mid-verify:
131
+ - `verify.run_count` exists AND is > 0
132
+ - AND `verify.overall_result` is NOT `'pass'`
133
+
134
+ If yes: flag as interrupted verification. Suggest re-running `/ttm-verify ${SLUG}`
135
+ to continue verification from where it left off.
136
+
137
+ ---
138
+
139
+ ## Step 5: Determine Next Command
140
+
141
+ Use the phase-to-command mapping to suggest the exact next command:
142
+
143
+ | Current Phase | Next Command | Notes |
144
+ |---------------|-------------|-------|
145
+ | `created` | `/ttm-research ${SLUG}` | Campaign exists but no research done |
146
+ | `researched` | `/ttm-brief ${SLUG}` | Research complete, needs brief |
147
+ | `briefed` | `/ttm-produce ${SLUG}` | Brief ready, needs production |
148
+ | `produced` | `/ttm-verify ${SLUG}` | Assets produced, needs verification |
149
+ | `verified` | `/ttm-review ${SLUG}` | Verification passed, needs review |
150
+ | `reviewed` | See logic below | Depends on review result |
151
+ | `fixed` | `/ttm-review ${SLUG}` | Fix applied, needs re-review |
152
+ | `shipped` | `/ttm-measure ${SLUG}` | Shipped, awaiting measurement window |
153
+ | `measured` | `/ttm-learn ${SLUG}` | Measured, needs learning extraction |
154
+ | `learned` | `/ttm-archive ${SLUG}` | Learnings extracted, ready to archive |
155
+ | `archived` | None | "Campaign already archived. No further action needed." |
156
+ | `cancelled` | None | "Campaign cancelled. No further action. Create a new campaign with `/ttm-new-campaign`." |
157
+
158
+ **Reviewed phase logic:**
159
+ - If `review.overall_result` equals `'revise'`: suggest `/ttm-fix ${SLUG}`
160
+ - If `review.overall_result` equals `'approved'`: suggest `/ttm-ship ${SLUG}`
161
+ - If `review.overall_result` is null or unclear: suggest `/ttm-review ${SLUG}`
162
+
163
+ **Override with interrupted loop detection (Step 4):**
164
+ - If mid-fix-loop detected: override suggestion to `/ttm-fix ${SLUG}` regardless
165
+ of phase-to-command mapping
166
+ - If mid-verify detected: override suggestion to `/ttm-verify ${SLUG}`
167
+
168
+ ---
169
+
170
+ ## Step 6: Display Recovery Summary
171
+
172
+ ```
173
+ takeToMarket > RESUME SUMMARY
174
+ ```
175
+
176
+ Display formatted summary:
177
+
178
+ ```markdown
179
+ ## Campaign Resume: ${SLUG}
180
+
181
+ **Campaign:** ${name}
182
+ **Current Phase:** ${phase}
183
+ **Last Activity:** ${relative_time} (${last_updated})
184
+
185
+ ### Completed Phases
186
+ | Phase | Completed At |
187
+ |-------|-------------|
188
+ | Created | ${phase.created} |
189
+ | Researched | ${phase.researched} |
190
+ | ... | ... |
191
+
192
+ ### Pending Work
193
+ ${next_step_description -- derived from the phase and any body content in STATE.md}
194
+
195
+ ### Suggested Next Command
196
+ > `/ttm-fix spring-launch`
197
+ > Reason: Fix loop in progress (attempt 2 of 3). Review flagged positioning drift.
198
+ ```
199
+
200
+ If an interrupted loop was detected in Step 4, add a prominent note:
201
+
202
+ ```markdown
203
+ ### Interrupted Loop Detected
204
+
205
+ **Type:** Fix loop (attempt ${fix.run_count} of 3)
206
+ **Reason:** Review result is 'revise' -- fixes needed before re-review.
207
+
208
+ Running `/ttm-fix ${SLUG}` will continue from attempt ${fix.run_count}, not restart.
209
+ Do NOT run `/ttm-produce` -- existing assets need fixing, not reproduction.
210
+ ```
211
+
212
+ If the campaign has blockers noted in STATE.md body, display them:
213
+
214
+ ```markdown
215
+ ### Known Blockers
216
+ ${blockers from STATE.md body if any}
217
+ ```
218
+
219
+ ---
220
+
221
+ ## Additional Context Display
222
+
223
+ If `time_since_last_activity` is greater than 7 days, add a context refresh suggestion:
224
+
225
+ ```markdown
226
+ ### Context Refresh Recommended
227
+
228
+ It has been ${days} days since last activity. Consider:
229
+ - Re-reading POSITIONING.md for any updates
230
+ - Checking CALENDAR.md for scheduling conflicts
231
+ - Running /ttm-health to verify campaign consistency
232
+ ```
233
+
234
+ </process>
235
+
236
+ <success_criteria>
237
+ - [ ] Campaign state loaded from STATE.md (not a separate handoff file)
238
+ - [ ] Recovery context shows last completed phase and full timeline
239
+ - [ ] Interrupted fix loops detected (fix.run_count > 0 AND review.overall_result = revise)
240
+ - [ ] Interrupted verify loops detected (verify.run_count > 0 AND verify.overall_result != pass)
241
+ - [ ] Exact next /ttm-* command suggested based on phase-to-command mapping
242
+ - [ ] Loop detection overrides standard phase mapping when applicable
243
+ - [ ] No files modified (read-only command)
244
+ </success_criteria>
245
+
246
+ <output>
247
+ No files modified. This is a read-only command that displays recovery context
248
+ and suggests the next command for the user to run.
249
+ </output>
@@ -0,0 +1,207 @@
1
+ <purpose>
2
+ State dashboard workflow for /ttm-state. Displays all campaigns (active and
3
+ archived) in a summary table. No-argument mode shows the full campaign dashboard;
4
+ slug argument shows single campaign detail view. Reads from campaign.cjs list
5
+ and enriches with per-campaign STATE.md data.
6
+ </purpose>
7
+
8
+ <required_reading>
9
+ @${CLAUDE_PLUGIN_ROOT}/references/context-loading.md
10
+ </required_reading>
11
+
12
+ <constraints>
13
+ ## POSITIONING.md is READ-ONLY
14
+
15
+ **Do NOT modify `.marketing/POSITIONING.md` during this workflow.**
16
+
17
+ POSITIONING.md is an architectural invariant. If you detect positioning drift:
18
+ - In verify: use the Escalate option to launch /ttm-positioning-shift
19
+ - In other workflows: flag the issue and recommend running /ttm-positioning-check
20
+
21
+ Only /ttm-positioning-shift and /ttm-init may modify POSITIONING.md.
22
+
23
+ ## Read-Only Command
24
+
25
+ This workflow does NOT modify any files. It only reads and displays information.
26
+ </constraints>
27
+
28
+ <process>
29
+
30
+ ## Step 1: Load Context
31
+
32
+ ```
33
+ takeToMarket > LOADING CONTEXT
34
+ ```
35
+
36
+ Extract SLUG from $ARGUMENTS (strip `--text` flag if present):
37
+ ```bash
38
+ SLUG=$(echo "$ARGUMENTS" | sed 's/--text//g' | xargs)
39
+ ```
40
+
41
+ SLUG is optional for this command. If empty, display full dashboard (Step 3).
42
+ If present, display single campaign detail (Step 4).
43
+
44
+ ---
45
+
46
+ ## Step 2: Gather Campaign Data
47
+
48
+ ```
49
+ takeToMarket > GATHERING CAMPAIGN DATA
50
+ ```
51
+
52
+ **Get all campaigns:**
53
+ ```bash
54
+ CAMPAIGNS_JSON=$(node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign list --raw)
55
+ ```
56
+
57
+ Parse JSON output to get all campaigns with their frontmatter fields (slug, phase,
58
+ name, last_updated, etc.).
59
+
60
+ **If SLUG is provided**, also get detailed state:
61
+ ```bash
62
+ DETAIL_JSON=$(node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign state "${SLUG}" --raw)
63
+ ```
64
+
65
+ If `exists: false` in the detail response:
66
+ "Campaign '${SLUG}' not found. Run `/ttm-state` without arguments to see all campaigns."
67
+ Exit.
68
+
69
+ **Check for archived campaigns:**
70
+ ```bash
71
+ ls .marketing/CAMPAIGNS/ARCHIVE/ 2>/dev/null
72
+ ```
73
+
74
+ For each archived directory found, read its STATE.md frontmatter to get archive date
75
+ and outcome information.
76
+
77
+ **Read global state for portfolio context:**
78
+ Read `.marketing/STATE.md` body content (below frontmatter) for portfolio-level
79
+ decisions, blockers, and experiments.
80
+
81
+ ---
82
+
83
+ ## Step 3: Display Dashboard (Full Mode -- No SLUG)
84
+
85
+ ```
86
+ takeToMarket > CAMPAIGN DASHBOARD
87
+ ```
88
+
89
+ Display a summary table with ALL campaigns organized by status.
90
+
91
+ ### Output Format
92
+
93
+ ```
94
+ ## Campaign Dashboard
95
+
96
+ ### Active Campaigns
97
+
98
+ | Campaign | Phase | Last Updated | Status |
99
+ |----------|-------|--------------|--------|
100
+ | <slug> | <phase> | <relative time> | <brief status> |
101
+
102
+ ```
103
+
104
+ For each active campaign, also display a detail section:
105
+
106
+ ```
107
+ ### <slug> Detail
108
+ **Phase:** <phase>
109
+ **Created:** <date> | **Last Updated:** <date>
110
+ **Gate Results:** <summary of pass/fail counts from review.overall_result>
111
+ **Fix Attempts:** <fix.run_count or 0>
112
+ **Decisions in flight:** <from global .marketing/STATE.md body if any>
113
+ **Blockers:** <from global .marketing/STATE.md body if any>
114
+ **Experiments:** <from global .marketing/STATE.md body if any>
115
+ ```
116
+
117
+ If no active campaigns exist, display:
118
+ "No active campaigns. Run `/ttm-new-campaign <slug>` to start one."
119
+
120
+ ### Archived Campaigns
121
+
122
+ If archived campaigns exist, display them in a collapsed section:
123
+
124
+ ```
125
+ ### Archived Campaigns
126
+
127
+ | Campaign | Archived Date | Outcome |
128
+ |----------|--------------|---------|
129
+ | <slug> | <date> | <shipped/cancelled> |
130
+ ```
131
+
132
+ If no archived campaigns exist, omit this section entirely.
133
+
134
+ ### Portfolio Summary
135
+
136
+ At the end, display a brief portfolio summary:
137
+ ```
138
+ ---
139
+ **Portfolio:** <N> active, <M> archived
140
+ **Next recommended action:** Run `/ttm-next` for prioritized guidance
141
+ ```
142
+
143
+ ---
144
+
145
+ ## Step 4: Display Single Campaign (SLUG Provided)
146
+
147
+ ```
148
+ takeToMarket > CAMPAIGN DETAIL: ${SLUG}
149
+ ```
150
+
151
+ Show full detail for the single campaign. Read the full campaign STATE.md file
152
+ (not just frontmatter -- per Pitfall 5) to get all body content.
153
+
154
+ ### Output Format
155
+
156
+ ```
157
+ ## Campaign: ${SLUG}
158
+
159
+ ### Overview
160
+ **Name:** <name>
161
+ **Phase:** <phase>
162
+ **Created:** <created date>
163
+ **Last Updated:** <last_updated date>
164
+
165
+ ### Lifecycle Progress
166
+ <Visual phase indicator showing completed and current phases>
167
+ created -> researched -> briefed -> produced -> verified -> reviewed -> shipped
168
+
169
+ ### State Details
170
+ **Review Result:** <review.overall_result or "not yet reviewed">
171
+ **Fix Attempts:** <fix.run_count or 0>
172
+ **Fix Result:** <fix.overall_result or "N/A">
173
+ **Ship Status:** <ship.status or "not shipped">
174
+
175
+ ### Gate Results
176
+ <Table of all gate/check results if available>
177
+
178
+ | Gate | Result | Date |
179
+ |------|--------|------|
180
+ | verification | <pass/fail> | <date> |
181
+ | review | <approved/revise> | <date> |
182
+
183
+ ### Campaign Notes
184
+ <Full body content from the campaign's STATE.md file>
185
+
186
+ ### Suggested Next Action
187
+ Based on current phase, suggest the next /ttm-* command:
188
+ - "Run `/ttm-<next-command> ${SLUG}` to continue."
189
+ ```
190
+
191
+ If the campaign has no body content in STATE.md, display:
192
+ "No additional notes recorded for this campaign."
193
+
194
+ </process>
195
+
196
+ <success_criteria>
197
+ - [ ] Campaign data retrieved via CLI (`campaign list --raw`)
198
+ - [ ] Dashboard displays active campaigns with detail sections
199
+ - [ ] Archived campaigns shown as collapsed rows
200
+ - [ ] Single campaign mode shows full detail when slug provided
201
+ - [ ] Global .marketing/STATE.md body read for portfolio-level context
202
+ - [ ] No files modified (read-only command)
203
+ </success_criteria>
204
+
205
+ <output>
206
+ No files modified (read-only command).
207
+ </output>