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.
- package/.claude-plugin/plugin.json +10 -0
- package/LICENSE +21 -0
- package/README.md +419 -0
- package/agents/ttm-producer.md +53 -0
- package/bin/lib/campaign.cjs +553 -0
- package/bin/lib/commit.cjs +105 -0
- package/bin/lib/core.cjs +172 -0
- package/bin/lib/deviation.cjs +149 -0
- package/bin/lib/drift-log.cjs +219 -0
- package/bin/lib/health.cjs +438 -0
- package/bin/lib/slug.cjs +59 -0
- package/bin/lib/state.cjs +96 -0
- package/bin/ttm-tools.cjs +157 -0
- package/gates/base-gates.md +266 -0
- package/gates/discipline/.gitkeep +0 -0
- package/gates/gate-evaluation.md +341 -0
- package/gates/meta-gates.md +19 -0
- package/install.js +307 -0
- package/package.json +53 -0
- package/playbooks/.gitkeep +0 -0
- package/playbooks/aeo.md +223 -0
- package/playbooks/affiliate.md +272 -0
- package/playbooks/base.md +110 -0
- package/playbooks/email.md +306 -0
- package/playbooks/events.md +320 -0
- package/playbooks/linkedin.md +263 -0
- package/playbooks/paid-ads.md +318 -0
- package/playbooks/pr-media.md +296 -0
- package/playbooks/seo.md +284 -0
- package/playbooks/social.md +305 -0
- package/playbooks/youtube.md +325 -0
- package/references/context-loading.md +107 -0
- package/references/learnings-extraction.md +94 -0
- package/references/measurement-template.md +48 -0
- package/references/meta-gate-evaluation.md +169 -0
- package/references/positioning-check-report.md +197 -0
- package/references/review-checklist.md +78 -0
- package/references/ship-checklist-items.md +94 -0
- package/settings.json +4 -0
- package/skills/ttm-aeo-check/SKILL.md +20 -0
- package/skills/ttm-affiliate-kit/SKILL.md +19 -0
- package/skills/ttm-archive/SKILL.md +13 -0
- package/skills/ttm-brand-refresh/SKILL.md +19 -0
- package/skills/ttm-brief/SKILL.md +14 -0
- package/skills/ttm-competitor-scan/SKILL.md +19 -0
- package/skills/ttm-email-preflight/SKILL.md +19 -0
- package/skills/ttm-fix/SKILL.md +13 -0
- package/skills/ttm-health/SKILL.md +12 -0
- package/skills/ttm-icp-refresh/SKILL.md +19 -0
- package/skills/ttm-init/SKILL.md +12 -0
- package/skills/ttm-keyword-map/SKILL.md +19 -0
- package/skills/ttm-learn/SKILL.md +14 -0
- package/skills/ttm-measure/SKILL.md +14 -0
- package/skills/ttm-new-campaign/SKILL.md +13 -0
- package/skills/ttm-next/SKILL.md +12 -0
- package/skills/ttm-positioning-check/SKILL.md +19 -0
- package/skills/ttm-positioning-shift/SKILL.md +19 -0
- package/skills/ttm-produce/SKILL.md +14 -0
- package/skills/ttm-repurpose/SKILL.md +20 -0
- package/skills/ttm-research/SKILL.md +13 -0
- package/skills/ttm-resume/SKILL.md +13 -0
- package/skills/ttm-review/SKILL.md +13 -0
- package/skills/ttm-seo-audit/SKILL.md +20 -0
- package/skills/ttm-ship/SKILL.md +13 -0
- package/skills/ttm-state/SKILL.md +13 -0
- package/skills/ttm-verify/SKILL.md +14 -0
- package/templates/agents-md.md +65 -0
- package/templates/campaign-brief.md +74 -0
- package/templates/campaign-research.md +39 -0
- package/templates/campaign-state.md +40 -0
- package/templates/claude-md.md +65 -0
- package/templates/deviation-log.md +12 -0
- package/templates/drift-log.md +17 -0
- package/templates/fix-brief.md +59 -0
- package/templates/fix-log.md +22 -0
- package/templates/measurement-report.md +75 -0
- package/templates/migration-plan.md +24 -0
- package/templates/production-manifest.json +20 -0
- package/templates/reference-files/brand.md +45 -0
- package/templates/reference-files/calendar.md +30 -0
- package/templates/reference-files/channels.md +40 -0
- package/templates/reference-files/competitors.md +40 -0
- package/templates/reference-files/icp.md +50 -0
- package/templates/reference-files/learnings.md +40 -0
- package/templates/reference-files/metrics.md +42 -0
- package/templates/reference-files/positioning.md +38 -0
- package/templates/reference-files/state.md +27 -0
- package/templates/verification-report.md +59 -0
- package/workflows/discipline/.gitkeep +0 -0
- package/workflows/discipline/aeo-check.md +180 -0
- package/workflows/discipline/affiliate-kit.md +147 -0
- package/workflows/discipline/email-preflight.md +150 -0
- package/workflows/discipline/keyword-map.md +125 -0
- package/workflows/discipline/repurpose.md +329 -0
- package/workflows/discipline/seo-audit.md +169 -0
- package/workflows/lifecycle/.gitkeep +0 -0
- package/workflows/lifecycle/brief-positioning-check.md +90 -0
- package/workflows/lifecycle/brief.md +355 -0
- package/workflows/lifecycle/fix.md +495 -0
- package/workflows/lifecycle/learn.md +405 -0
- package/workflows/lifecycle/measure.md +379 -0
- package/workflows/lifecycle/produce.md +383 -0
- package/workflows/lifecycle/research.md +264 -0
- package/workflows/lifecycle/review.md +432 -0
- package/workflows/lifecycle/ship.md +521 -0
- package/workflows/lifecycle/verify.md +507 -0
- package/workflows/reference-mgmt/.gitkeep +0 -0
- package/workflows/reference-mgmt/brand-refresh.md +193 -0
- package/workflows/reference-mgmt/competitor-scan.md +228 -0
- package/workflows/reference-mgmt/icp-refresh.md +200 -0
- package/workflows/reference-mgmt/positioning-check.md +339 -0
- package/workflows/reference-mgmt/positioning-shift.md +368 -0
- package/workflows/setup/.gitkeep +0 -0
- package/workflows/setup/init-questions.md +225 -0
- package/workflows/setup/init-validation.md +155 -0
- package/workflows/setup/init.md +449 -0
- package/workflows/setup/new-campaign.md +134 -0
- package/workflows/utility/.gitkeep +0 -0
- package/workflows/utility/archive.md +334 -0
- package/workflows/utility/health.md +166 -0
- package/workflows/utility/next.md +187 -0
- package/workflows/utility/resume.md +249 -0
- package/workflows/utility/state.md +207 -0
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
<purpose>
|
|
2
|
+
Ship workflow for /ttm-ship. Generates a dynamic launch checklist per campaign
|
|
3
|
+
based on channel mix and asset types (D-09). AI auto-checks verifiable items,
|
|
4
|
+
presents results with checkboxes for human confirmation (D-10). Per-asset ship
|
|
5
|
+
status allows staggered launches (D-11). Only ship-ready assets can ship.
|
|
6
|
+
</purpose>
|
|
7
|
+
|
|
8
|
+
<required_reading>
|
|
9
|
+
@${CLAUDE_PLUGIN_ROOT}/references/context-loading.md
|
|
10
|
+
@${CLAUDE_PLUGIN_ROOT}/references/ship-checklist-items.md
|
|
11
|
+
</required_reading>
|
|
12
|
+
|
|
13
|
+
<constraints>
|
|
14
|
+
## POSITIONING.md is READ-ONLY
|
|
15
|
+
|
|
16
|
+
**Do NOT modify `.marketing/POSITIONING.md` during this workflow.**
|
|
17
|
+
|
|
18
|
+
POSITIONING.md is an architectural invariant. If you detect positioning drift:
|
|
19
|
+
- In verify: use the Escalate option to launch /ttm-positioning-shift
|
|
20
|
+
- In other workflows: flag the issue and recommend running /ttm-positioning-check
|
|
21
|
+
|
|
22
|
+
Only /ttm-positioning-shift and /ttm-init may modify POSITIONING.md.
|
|
23
|
+
</constraints>
|
|
24
|
+
|
|
25
|
+
<process>
|
|
26
|
+
|
|
27
|
+
## Text-Mode Detection
|
|
28
|
+
|
|
29
|
+
**Text mode (`--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS`
|
|
30
|
+
or if the runtime is not Claude Code. When TEXT_MODE is active, replace every
|
|
31
|
+
`AskUserQuestion` call with a plain-text numbered list.
|
|
32
|
+
|
|
33
|
+
Detection:
|
|
34
|
+
```bash
|
|
35
|
+
if echo "$ARGUMENTS" | grep -q -- '--text'; then TEXT_MODE=true; fi
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
If `AskUserQuestion` tool is not available in the current runtime, set `TEXT_MODE=true`.
|
|
39
|
+
|
|
40
|
+
When TEXT_MODE is active, replace each AskUserQuestion with a plain-text numbered list:
|
|
41
|
+
```
|
|
42
|
+
[HEADER]
|
|
43
|
+
[QUESTION]
|
|
44
|
+
1. [OPTION_1_LABEL] -- [OPTION_1_DESCRIPTION]
|
|
45
|
+
2. [OPTION_2_LABEL] -- [OPTION_2_DESCRIPTION]
|
|
46
|
+
...
|
|
47
|
+
Type the number of your choice:
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Step 1: Load Context
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
takeToMarket > LOADING CONTEXT
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Extract SLUG from $ARGUMENTS (strip `--text` flag if present):
|
|
59
|
+
```bash
|
|
60
|
+
SLUG=$(echo "$ARGUMENTS" | sed 's/--text//g' | xargs)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If SLUG is empty, error: "Usage: /ttm-ship [campaign-slug]. Provide a campaign slug." Exit.
|
|
64
|
+
|
|
65
|
+
**Load Tier 1 summaries** from all 9 reference files (lines 1 to `<!-- END_SUMMARY -->`):
|
|
66
|
+
- `.marketing/POSITIONING.md`
|
|
67
|
+
- `.marketing/BRAND.md`
|
|
68
|
+
- `.marketing/ICP.md`
|
|
69
|
+
- `.marketing/CHANNELS.md`
|
|
70
|
+
- `.marketing/STATE.md` (frontmatter only)
|
|
71
|
+
- `.marketing/CALENDAR.md`
|
|
72
|
+
- `.marketing/COMPETITORS.md`
|
|
73
|
+
- `.marketing/METRICS.md`
|
|
74
|
+
- `.marketing/LEARNINGS.md`
|
|
75
|
+
|
|
76
|
+
**Load Tier 2 (full content)** for ship checklist generation:
|
|
77
|
+
- `.marketing/CHANNELS.md` (needed for UTM schema and channel-specific details)
|
|
78
|
+
|
|
79
|
+
**Load campaign-specific files** (always full-load per context-loading.md rule 4):
|
|
80
|
+
- `.marketing/CAMPAIGNS/${SLUG}/STATE.md`
|
|
81
|
+
- `.marketing/CAMPAIGNS/${SLUG}/BRIEF.md`
|
|
82
|
+
|
|
83
|
+
**Load MANIFEST.json:**
|
|
84
|
+
```bash
|
|
85
|
+
MANIFEST_PATH=".marketing/CAMPAIGNS/${SLUG}/MANIFEST.json"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Read `.marketing/CAMPAIGNS/${SLUG}/MANIFEST.json`. If the file does not exist, error:
|
|
89
|
+
"No production manifest found for campaign '${SLUG}'. Run /ttm-produce first."
|
|
90
|
+
Exit.
|
|
91
|
+
|
|
92
|
+
**Load VERIFICATION.md:**
|
|
93
|
+
Read `.marketing/CAMPAIGNS/${SLUG}/VERIFICATION.md`. If the file does not exist, error:
|
|
94
|
+
"No verification report found for campaign '${SLUG}'. Run /ttm-verify first."
|
|
95
|
+
Exit.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Step 2: Validate Campaign State
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
takeToMarket > VALIDATING CAMPAIGN
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Check campaign exists:
|
|
106
|
+
```bash
|
|
107
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign state "${SLUG}" --raw
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
If result shows `exists: false`: Tell the user the campaign does not exist and suggest
|
|
111
|
+
running `/ttm-new-campaign` first. Exit.
|
|
112
|
+
|
|
113
|
+
**Check review completion:**
|
|
114
|
+
Read `review.overall_result` from campaign state.
|
|
115
|
+
|
|
116
|
+
- If `review.overall_result` is null: "Campaign has not been reviewed. Run /ttm-review first." Exit.
|
|
117
|
+
- If `review.overall_result` is `needs-fix` or `mixed`:
|
|
118
|
+
Read `fix.overall_result` from campaign state.
|
|
119
|
+
If `fix.overall_result` is null:
|
|
120
|
+
Warn: "Some assets need fixing. Run /ttm-fix first, or proceed to ship only approved assets?"
|
|
121
|
+
Using AskUserQuestion (or text-mode numbered list):
|
|
122
|
+
```
|
|
123
|
+
Some assets have not been fixed yet.
|
|
124
|
+
1. Proceed -- ship only approved/ship-ready assets
|
|
125
|
+
2. Fix first -- exit and run /ttm-fix
|
|
126
|
+
```
|
|
127
|
+
If "Fix first": exit workflow.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Step 3: Identify Ship-Ready Assets
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
takeToMarket > CHECKING SHIP READINESS
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Parse MANIFEST.json. Collect hero and all derivative assets. For each asset,
|
|
138
|
+
read its `review_status` and `ship_status` fields. Categorize:
|
|
139
|
+
|
|
140
|
+
- **Ship-ready:** `review_status` is `"approved"` or `"ship-ready"` AND `ship_status` is NOT `"shipped"`
|
|
141
|
+
- **Not ready:** `review_status` is `"needs-fix"` or `"needs-human-fix"` -- display warning
|
|
142
|
+
- **Already shipped:** `ship_status` is `"shipped"` -- skip
|
|
143
|
+
- **Rejected:** `review_status` is `"rejected"` -- excluded, already final
|
|
144
|
+
|
|
145
|
+
If no assets are eligible for shipping:
|
|
146
|
+
"No ship-ready assets found. All assets are either awaiting fix, rejected, or already shipped."
|
|
147
|
+
Exit.
|
|
148
|
+
|
|
149
|
+
Display ship readiness summary:
|
|
150
|
+
```
|
|
151
|
+
takeToMarket > SHIP READINESS
|
|
152
|
+
|
|
153
|
+
Ship-ready assets: ${COUNT}
|
|
154
|
+
${FOR EACH SHIP-READY ASSET:}
|
|
155
|
+
- ${ASSET_NAME} (${ASSET_TYPE}, ${CHANNEL})
|
|
156
|
+
${END FOR}
|
|
157
|
+
|
|
158
|
+
${IF ANY NOT READY:}
|
|
159
|
+
Not ready (excluded from this ship run):
|
|
160
|
+
${FOR EACH NOT-READY ASSET:}
|
|
161
|
+
- ${ASSET_NAME}: ${STATUS} -- ${REASON}
|
|
162
|
+
${END FOR}
|
|
163
|
+
|
|
164
|
+
${IF ANY ALREADY SHIPPED:}
|
|
165
|
+
Already shipped:
|
|
166
|
+
${FOR EACH SHIPPED ASSET:}
|
|
167
|
+
- ${ASSET_NAME} (shipped at ${SHIPPED_AT})
|
|
168
|
+
${END FOR}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Step 4: Generate Dynamic Checklist (D-09)
|
|
174
|
+
|
|
175
|
+
Read `${CLAUDE_PLUGIN_ROOT}/references/ship-checklist-items.md` for the checklist
|
|
176
|
+
item definitions.
|
|
177
|
+
|
|
178
|
+
From BRIEF.md, identify the campaign's channel mix. From the ship-ready asset list,
|
|
179
|
+
identify the unique asset types present (e.g., `blog-post`, `email`, `linkedin-post`,
|
|
180
|
+
`social-post`, `twitter-post`, `landing-page`, `video`, `youtube-video`, `paid-ad`).
|
|
181
|
+
|
|
182
|
+
Build the checklist by combining:
|
|
183
|
+
|
|
184
|
+
1. **Universal section** -- always included for all campaigns. Load items from the
|
|
185
|
+
"Universal (all campaigns)" section of ship-checklist-items.md.
|
|
186
|
+
|
|
187
|
+
2. **Channel-specific sections** -- for each unique asset type in the ship-ready list:
|
|
188
|
+
- `blog-post` -> load "Blog / SEO" section
|
|
189
|
+
- `email` -> load "Email" section
|
|
190
|
+
- `linkedin-post` -> load "LinkedIn" section
|
|
191
|
+
- `social-post` or `twitter-post` -> load "Social / Twitter/X" section
|
|
192
|
+
- `landing-page` -> load "Landing Page" section
|
|
193
|
+
- `video` or `youtube-video` -> load "Video / YouTube" section
|
|
194
|
+
- `paid-ad` -> load "Paid Ads" section
|
|
195
|
+
- Any unmatched type -> load "Default" section
|
|
196
|
+
|
|
197
|
+
Only include sections that match asset types in the ship-ready list. Do NOT include
|
|
198
|
+
sections for asset types that are not present -- the checklist must be relevant, not
|
|
199
|
+
exhaustive (D-09).
|
|
200
|
+
|
|
201
|
+
Store the assembled checklist as a structured list:
|
|
202
|
+
```
|
|
203
|
+
CHECKLIST = [
|
|
204
|
+
{ section: "Universal", items: [
|
|
205
|
+
{ name: "UTM parameters valid...", tag: "AI", result: null },
|
|
206
|
+
{ name: "Tracking/analytics configured...", tag: "HUMAN", result: null },
|
|
207
|
+
...
|
|
208
|
+
]},
|
|
209
|
+
{ section: "Blog / SEO", items: [...] },
|
|
210
|
+
...
|
|
211
|
+
]
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Step 5: Run AI Auto-Checks (D-10)
|
|
217
|
+
|
|
218
|
+
For each `[AI]`-tagged checklist item, attempt automated verification by reading
|
|
219
|
+
the ship-ready asset files and campaign data.
|
|
220
|
+
|
|
221
|
+
### Universal AI Checks
|
|
222
|
+
|
|
223
|
+
**UTM parameter validity:**
|
|
224
|
+
Scan each ship-ready asset file for URLs containing `utm_` parameters.
|
|
225
|
+
- Check format: `utm_source`, `utm_medium`, `utm_campaign` must all be present in each
|
|
226
|
+
tracked URL.
|
|
227
|
+
- Cross-reference against `.marketing/CHANNELS.md` UTM schema if available.
|
|
228
|
+
- Result: PASS (valid UTMs found on all trackable links), WARN (no trackable links found
|
|
229
|
+
in assets -- may be expected for some asset types), FAIL (malformed UTMs -- missing
|
|
230
|
+
required parameters or inconsistent naming).
|
|
231
|
+
|
|
232
|
+
**Draft marker detection:**
|
|
233
|
+
Scan each ship-ready asset file for strings: `TODO`, `PLACEHOLDER`, `TBD`, `DRAFT`,
|
|
234
|
+
`[INSERT`, `XXX`.
|
|
235
|
+
- Result: PASS (none found across all assets), FAIL (markers found -- list file and
|
|
236
|
+
location for each).
|
|
237
|
+
|
|
238
|
+
**Verification status:**
|
|
239
|
+
Read VERIFICATION.md frontmatter `overall_result`.
|
|
240
|
+
- Result: PASS if `pass` or `accepted`, FAIL if `fail` or `warn` without acceptance.
|
|
241
|
+
|
|
242
|
+
**Review status:**
|
|
243
|
+
Check MANIFEST.json -- verify all ship-ready assets have `review_status` of `approved`
|
|
244
|
+
or `ship-ready`.
|
|
245
|
+
- Result: PASS (all ship-ready assets confirmed), FAIL (any asset has unexpected status).
|
|
246
|
+
|
|
247
|
+
### Channel-Specific AI Checks
|
|
248
|
+
|
|
249
|
+
For each channel-specific section in the assembled checklist, run the applicable AI
|
|
250
|
+
checks against the corresponding asset files:
|
|
251
|
+
|
|
252
|
+
**Blog / SEO:**
|
|
253
|
+
- Meta title: Check for first H1 or frontmatter `title` field. PASS if found.
|
|
254
|
+
- Meta description: Check for frontmatter `description` field or first paragraph under
|
|
255
|
+
160 chars. PASS if present, WARN if over 160 chars.
|
|
256
|
+
- H1 with keyword: Check that first H1 contains primary keyword from BRIEF.md or
|
|
257
|
+
positioning anchor from POSITIONING.md summary. PASS/WARN.
|
|
258
|
+
- Orphaned links: Scan for markdown links `[text](url)` -- flag any with empty or
|
|
259
|
+
clearly broken targets. PASS/WARN.
|
|
260
|
+
|
|
261
|
+
**Email:**
|
|
262
|
+
- Subject line length: Read frontmatter `subject` field, check length < 60 chars.
|
|
263
|
+
PASS/FAIL.
|
|
264
|
+
- Preview text length: Read frontmatter `preview` or `preview_text` field, check < 90
|
|
265
|
+
chars. PASS/WARN.
|
|
266
|
+
- Unsubscribe: Scan for string "unsubscribe" (case-insensitive). PASS/FAIL.
|
|
267
|
+
- Physical address: Scan for a postal/mailing address pattern. PASS/WARN.
|
|
268
|
+
- Spam trigger words: Check subject for common spam triggers (FREE, URGENT, ACT NOW,
|
|
269
|
+
LIMITED TIME, GUARANTEED). PASS/WARN.
|
|
270
|
+
|
|
271
|
+
**LinkedIn:**
|
|
272
|
+
- Post length: Count characters. PASS if under 3000, FAIL if over.
|
|
273
|
+
- Opening line: Check if first non-empty line starts with "I". WARN if yes.
|
|
274
|
+
- External URL in first line: Check if first line contains http(s) URL. WARN if yes.
|
|
275
|
+
|
|
276
|
+
**Social / Twitter/X:**
|
|
277
|
+
- Character count: Count total post characters. PASS if under 280 (Twitter/X) or
|
|
278
|
+
platform-appropriate limit, FAIL if over.
|
|
279
|
+
- Rhetorical questions: Scan for question marks in sentences that start with "Why",
|
|
280
|
+
"How", "What if", "Have you". WARN if found.
|
|
281
|
+
- Hashtag count: Count `#` tags. PASS if 0-3, WARN if more.
|
|
282
|
+
|
|
283
|
+
**Landing Page:**
|
|
284
|
+
- CTA presence: Scan for `[CTA]`, button-like markup (`<button`, `[Button]`), or
|
|
285
|
+
strong action verbs (Get, Start, Join, Try, Download, Request, Schedule). PASS/FAIL.
|
|
286
|
+
- Form fields: Check for form-like content matching brief's conversion goal. PASS/WARN.
|
|
287
|
+
- UTM capture: Check for form fields or hidden inputs referencing UTM parameters.
|
|
288
|
+
PASS/WARN.
|
|
289
|
+
|
|
290
|
+
**Video / YouTube:**
|
|
291
|
+
- Title length: Check frontmatter `title` field < 60 chars. PASS/FAIL.
|
|
292
|
+
- Description keyword: Check that description's first 2 lines contain primary keyword.
|
|
293
|
+
PASS/WARN.
|
|
294
|
+
- Timestamps: If content references a video longer than 5 minutes, check for
|
|
295
|
+
timestamp markers. PASS/WARN/N/A.
|
|
296
|
+
|
|
297
|
+
**Paid Ads:**
|
|
298
|
+
- Character limits: Check headline and description against platform limits. PASS/FAIL.
|
|
299
|
+
- Headline and description: Verify both are present. PASS/FAIL.
|
|
300
|
+
- Display URL: Check for a formatted display URL. PASS/WARN.
|
|
301
|
+
|
|
302
|
+
For each AI check, record:
|
|
303
|
+
```
|
|
304
|
+
{ item_name, result: "PASS"|"WARN"|"FAIL", detail: "what was found or why it failed" }
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## Step 6: Present Checklist with Results (D-10)
|
|
310
|
+
|
|
311
|
+
Display the complete checklist organized by section. For each item:
|
|
312
|
+
- `[AI]` items: Show result (PASS/WARN/FAIL) with detail
|
|
313
|
+
- `[HUMAN]` items: Show as unchecked checkbox for user to confirm
|
|
314
|
+
|
|
315
|
+
```
|
|
316
|
+
takeToMarket > LAUNCH CHECKLIST: ${SLUG}
|
|
317
|
+
|
|
318
|
+
## Universal Checks
|
|
319
|
+
- [PASS] UTM parameters valid on all trackable links
|
|
320
|
+
- [PASS] All asset files finalized (no draft markers)
|
|
321
|
+
- [PASS] VERIFICATION.md shows pass/accepted
|
|
322
|
+
- [PASS] All ship-ready assets have approved review status
|
|
323
|
+
- [ ] Tracking/analytics configured for outcome metric -- CONFIRM? (yes/no)
|
|
324
|
+
- [ ] Monitoring and alerts set up -- CONFIRM? (yes/no)
|
|
325
|
+
- [ ] Team notified of launch timeline -- CONFIRM? (yes/no)
|
|
326
|
+
|
|
327
|
+
${IF BLOG/SEO SECTION:}
|
|
328
|
+
## Blog / SEO Checks
|
|
329
|
+
- [PASS] Meta title present
|
|
330
|
+
- [WARN] Meta description: 180 chars (recommend under 160)
|
|
331
|
+
- [ ] Schema markup deployed -- CONFIRM? (yes/no)
|
|
332
|
+
- [ ] Internal links added -- CONFIRM? (yes/no)
|
|
333
|
+
...
|
|
334
|
+
${END IF}
|
|
335
|
+
|
|
336
|
+
${OTHER CHANNEL SECTIONS AS APPLICABLE}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Collect Human Confirmations
|
|
340
|
+
|
|
341
|
+
For each `[HUMAN]` item, use AskUserQuestion (or text-mode) to collect confirmation:
|
|
342
|
+
|
|
343
|
+
```
|
|
344
|
+
Confirm: [CHECKLIST_ITEM]
|
|
345
|
+
1. Yes -- confirmed
|
|
346
|
+
2. No -- not ready yet
|
|
347
|
+
3. N/A -- not applicable to this campaign
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Track which items are confirmed (yes), not ready (no), or not applicable (N/A).
|
|
351
|
+
|
|
352
|
+
**IMPORTANT:** Group human confirmations by section to reduce interaction fatigue.
|
|
353
|
+
Present all [HUMAN] items in a section together:
|
|
354
|
+
|
|
355
|
+
```
|
|
356
|
+
Universal human checks:
|
|
357
|
+
1. Tracking/analytics configured for outcome metric?
|
|
358
|
+
2. Monitoring and alerts set up?
|
|
359
|
+
3. Team notified of launch timeline?
|
|
360
|
+
|
|
361
|
+
For each item above, type: yes / no / n/a
|
|
362
|
+
(Example: yes, yes, n/a)
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## Step 7: Determine Ship Decision
|
|
368
|
+
|
|
369
|
+
After all items processed:
|
|
370
|
+
|
|
371
|
+
**All clear:** If all [AI] checks PASS (or WARN) and all [HUMAN] items confirmed
|
|
372
|
+
(yes or N/A):
|
|
373
|
+
```
|
|
374
|
+
takeToMarket > ALL CLEAR TO SHIP
|
|
375
|
+
|
|
376
|
+
All checklist items passed or confirmed. Ready to proceed with shipping.
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
**Blockers found:** If any [AI] checks FAIL or any [HUMAN] items answered "no":
|
|
380
|
+
```
|
|
381
|
+
Blockers preventing ship:
|
|
382
|
+
${FOR EACH BLOCKER:}
|
|
383
|
+
- ${ITEM_NAME}: ${REASON}
|
|
384
|
+
${END FOR}
|
|
385
|
+
|
|
386
|
+
Resolve these items and re-run /ttm-ship ${SLUG}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
Ask user using AskUserQuestion (or text-mode numbered list):
|
|
390
|
+
```
|
|
391
|
+
Ship decision:
|
|
392
|
+
1. Ship anyway -- proceed with documented exceptions
|
|
393
|
+
2. Resolve first -- exit and fix blockers
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
If "Ship anyway": proceed to Step 8. Record all blockers as exceptions.
|
|
397
|
+
If "Resolve first": exit workflow.
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## Step 8: Update Per-Asset Ship Status (D-11)
|
|
402
|
+
|
|
403
|
+
For each ship-ready asset being shipped:
|
|
404
|
+
|
|
405
|
+
Read MANIFEST.json. Update each shipped asset entry:
|
|
406
|
+
- Set `ship_status: "shipped"`
|
|
407
|
+
- Set `shipped_at: "[ISO_TIMESTAMP]"` (current timestamp)
|
|
408
|
+
|
|
409
|
+
```bash
|
|
410
|
+
TIMESTAMP=$(node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" timestamp --raw)
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Assets NOT being shipped (not ready, user deferred) retain their current status.
|
|
414
|
+
|
|
415
|
+
Write updated MANIFEST.json back to disk.
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## Step 9: Update Campaign State
|
|
420
|
+
|
|
421
|
+
Determine ship status:
|
|
422
|
+
- `shipped` -- all ship-ready assets shipped (none deferred or blocked)
|
|
423
|
+
- `partial` -- some assets shipped, others still pending
|
|
424
|
+
|
|
425
|
+
```bash
|
|
426
|
+
TIMESTAMP=$(node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" timestamp --raw)
|
|
427
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update "${SLUG}" ship.status "[shipped|partial]"
|
|
428
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update "${SLUG}" ship.shipped_at "$TIMESTAMP"
|
|
429
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update "${SLUG}" ship.checklist_result "[all-clear|exceptions]"
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**ship.status logic:**
|
|
433
|
+
- `shipped` -- all ship-ready assets shipped
|
|
434
|
+
- `partial` -- some assets shipped, others deferred or blocked
|
|
435
|
+
|
|
436
|
+
**ship.checklist_result logic:**
|
|
437
|
+
- `all-clear` -- all AI checks passed and all human items confirmed
|
|
438
|
+
- `exceptions` -- shipped with documented blockers/warnings
|
|
439
|
+
|
|
440
|
+
Only update campaign phase to "shipped" if at least one asset was shipped:
|
|
441
|
+
```bash
|
|
442
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update "${SLUG}" phase shipped
|
|
443
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update "${SLUG}" phase.shipped "$TIMESTAMP"
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
## Step 10: Display Completion
|
|
449
|
+
|
|
450
|
+
```
|
|
451
|
+
takeToMarket > SHIP COMPLETE
|
|
452
|
+
|
|
453
|
+
Date: ${ISO_DATE}
|
|
454
|
+
Assets shipped: ${SHIPPED_COUNT}/${TOTAL_SHIP_READY}
|
|
455
|
+
|
|
456
|
+
Shipped:
|
|
457
|
+
${FOR EACH SHIPPED ASSET:}
|
|
458
|
+
- ${ASSET_NAME} (shipped at ${TIMESTAMP})
|
|
459
|
+
${END FOR}
|
|
460
|
+
|
|
461
|
+
${IF PARTIAL:}
|
|
462
|
+
Deferred (not shipped yet):
|
|
463
|
+
${FOR EACH DEFERRED ASSET:}
|
|
464
|
+
- ${ASSET_NAME}: ${REASON}
|
|
465
|
+
${END FOR}
|
|
466
|
+
|
|
467
|
+
${IF EXCEPTIONS:}
|
|
468
|
+
Shipped with exceptions:
|
|
469
|
+
${FOR EACH EXCEPTION:}
|
|
470
|
+
- ${EXCEPTION_ITEM}: ${JUSTIFICATION}
|
|
471
|
+
${END FOR}
|
|
472
|
+
|
|
473
|
+
Checklist result: ${CHECKLIST_RESULT}
|
|
474
|
+
|
|
475
|
+
Next: Run /ttm-measure ${SLUG} when measurement window begins
|
|
476
|
+
(or /ttm-ship ${SLUG} again to ship deferred assets)
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
## Step 11: Positioning Check Auto-Suggest (D-02)
|
|
482
|
+
|
|
483
|
+
Check if a positioning audit is recommended:
|
|
484
|
+
```bash
|
|
485
|
+
SHIPPED_JSON=$(node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign list --shipped-since-last-audit --raw)
|
|
486
|
+
SHIPPED_COUNT=$(echo "$SHIPPED_JSON" | node -e "process.stdin.resume();let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>console.log(JSON.parse(d).count))")
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
If SHIPPED_COUNT >= 3, display:
|
|
490
|
+
|
|
491
|
+
```
|
|
492
|
+
takeToMarket > POSITIONING CHECK SUGGESTED
|
|
493
|
+
|
|
494
|
+
${SHIPPED_COUNT} campaigns have shipped since your last positioning audit.
|
|
495
|
+
Consider running /ttm-positioning-check to verify positioning consistency
|
|
496
|
+
across recent assets.
|
|
497
|
+
|
|
498
|
+
This is a suggestion, not a requirement. Run it when convenient.
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
If SHIPPED_COUNT < 3, do not display anything.
|
|
502
|
+
|
|
503
|
+
</process>
|
|
504
|
+
|
|
505
|
+
<success_criteria>
|
|
506
|
+
- [ ] Campaign state validated (exists, has been reviewed)
|
|
507
|
+
- [ ] Ship-ready assets identified from MANIFEST.json review_status
|
|
508
|
+
- [ ] Dynamic checklist generated from campaign channel mix (D-09)
|
|
509
|
+
- [ ] AI auto-checks run for all [AI]-tagged items (UTM, draft markers, verification, review status)
|
|
510
|
+
- [ ] Channel-specific AI checks run for applicable asset types
|
|
511
|
+
- [ ] Human confirmation collected for all [HUMAN]-tagged items (D-10)
|
|
512
|
+
- [ ] Ship decision made (all clear or ship with exceptions)
|
|
513
|
+
- [ ] Per-asset ship_status and shipped_at updated in MANIFEST.json (D-11)
|
|
514
|
+
- [ ] Campaign state updated: ship.status, ship.shipped_at, ship.checklist_result
|
|
515
|
+
- [ ] Campaign phase advanced to "shipped" (if at least one asset shipped)
|
|
516
|
+
- [ ] User directed to /ttm-measure as next step
|
|
517
|
+
</success_criteria>
|
|
518
|
+
|
|
519
|
+
<output>
|
|
520
|
+
- `.marketing/CAMPAIGNS/${SLUG}/MANIFEST.json` (updated with ship_status and shipped_at per asset)
|
|
521
|
+
</output>
|