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,150 @@
1
+ <purpose>
2
+ Pre-send deliverability, dark-mode compatibility, and spam-trigger scan for email content.
3
+ Evaluates against email playbook gate definitions and generates a go/no-go recommendation.
4
+ Single-pass analysis workflow per D-07.
5
+ </purpose>
6
+
7
+ <required_reading>
8
+ @${CLAUDE_PLUGIN_ROOT}/references/context-loading.md
9
+ @${CLAUDE_PLUGIN_ROOT}/playbooks/email.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
+ - Flag the issue and recommend running /ttm-positioning-check
19
+
20
+ Only /ttm-positioning-shift and /ttm-init may modify POSITIONING.md.
21
+ </constraints>
22
+
23
+ <process>
24
+
25
+ ## Text-Mode Detection
26
+
27
+ **Text mode (`--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS`
28
+ or if the runtime is not Claude Code. When TEXT_MODE is active, replace every
29
+ `AskUserQuestion` call with a plain-text numbered list.
30
+
31
+ Detection:
32
+ ```bash
33
+ if echo "$ARGUMENTS" | grep -q -- '--text'; then TEXT_MODE=true; fi
34
+ ```
35
+
36
+ If `AskUserQuestion` tool is not available in the current runtime, set `TEXT_MODE=true`.
37
+
38
+ ---
39
+
40
+ ## Step 1: Load Context
41
+
42
+ ```
43
+ takeToMarket > LOADING CONTEXT FOR EMAIL PREFLIGHT
44
+ ```
45
+
46
+ **Tier 1 summaries** (lines 1 to `<!-- END_SUMMARY -->`) from all 9 `.marketing/` reference files.
47
+ **Tier 2 (full):** `.marketing/BRAND.md` (voice/banned words check).
48
+ **Playbook gates:** @${CLAUDE_PLUGIN_ROOT}/playbooks/email.md
49
+
50
+ If `.marketing/POSITIONING.md` does not exist: Error and exit.
51
+
52
+ ---
53
+
54
+ ## Step 2: Get Email Content
55
+
56
+ Ask: "Paste your email content (subject line, preview text, and body). Include HTML if available."
57
+
58
+ Parse into: subject line, preview text, body content, and HTML structure (if provided).
59
+ If user provides a file path, read the file. If subject/preview are not clearly marked,
60
+ ask for clarification.
61
+
62
+ ---
63
+
64
+ ## Step 3: Run Email Preflight Checks
65
+
66
+ ```
67
+ takeToMarket > RUNNING EMAIL PREFLIGHT CHECKS
68
+ ```
69
+
70
+ Evaluate against 7 email discipline gates:
71
+
72
+ **1. Subject Line Spam Triggers (DISC-EMAIL-01)**
73
+ Check for: ALL CAPS words, excessive punctuation (!!!, ???), spam trigger phrases
74
+ (FREE, ACT NOW, LIMITED TIME, GUARANTEED, etc.), multiple formatting red flags.
75
+ - PASS: No spam triggers; clean formatting
76
+ - WARN: 1 borderline trigger with mitigating context
77
+ - FAIL: 2+ spam triggers, ALL CAPS subject, or excessive punctuation
78
+
79
+ **2. Preview Text Optimization (DISC-EMAIL-05)**
80
+ Preview text present, distinct from subject, 40-130 chars, compelling.
81
+ - PASS: Present, 40-130 chars, distinct from subject
82
+ - WARN: Present but too short/long or repeats subject
83
+ - FAIL: No preview text specified
84
+
85
+ **3. Dark Mode Compatibility (DISC-EMAIL-02)**
86
+ If HTML: check for dark-mode-safe colors, no hardcoded white backgrounds, image alt-text.
87
+ - PASS: No hard-coded light backgrounds; all images have alt text
88
+ - WARN: Background colors may render poorly in dark mode
89
+ - FAIL: White backgrounds without alternatives; image-dependent content
90
+
91
+ **4. Unsubscribe/Address (DISC-EMAIL-03)**
92
+ CAN-SPAM compliance: unsubscribe link and physical address present.
93
+ - PASS: Both unsubscribe link and physical address clearly present
94
+ - WARN: Present but buried or incomplete
95
+ - FAIL: Missing unsubscribe or physical address
96
+
97
+ **5. Content-to-Image Ratio (DISC-EMAIL-04)**
98
+ Text-to-image ratio at least 60:40, alt text on all images.
99
+ - PASS: Text dominant; fully readable without images
100
+ - WARN: Roughly equal text/image; core message survives without images
101
+ - FAIL: Image-heavy; image-only sections or missing alt text
102
+
103
+ **6. Deliverability Signals (DISC-EMAIL-07)**
104
+ Link count (<10 recommended), no URL shorteners, SPF/DKIM/DMARC reminder.
105
+ - PASS: <10 links, no shorteners, proper sending domain
106
+ - WARN: 10-15 links or minor deliverability concerns
107
+ - FAIL: Excessive links, URL shorteners, or unconfigured domain
108
+
109
+ **7. Brand Voice**
110
+ Check against BRAND.md tone guidelines and banned words list.
111
+ - PASS: Tone matches brand voice; no banned words
112
+ - WARN: Minor tone deviation but no banned words
113
+ - FAIL: Banned words present or tone contradicts brand
114
+
115
+ Per check: assign PASS / WARN / FAIL with evidence.
116
+
117
+ ---
118
+
119
+ ## Step 4: Generate Report
120
+
121
+ Determine verdict: **GO** (0 FAIL, <=2 WARN) | **CAUTION** (>2 WARN) | **NO-GO** (any FAIL)
122
+
123
+ ```
124
+ ========================================
125
+ takeToMarket > EMAIL PREFLIGHT REPORT
126
+ ========================================
127
+ Subject: [subject line]
128
+ Date: [current date]
129
+ Overall: [GO / CAUTION / NO-GO]
130
+
131
+ | # | Check | Result | Detail |
132
+ |---|------------------------|--------|-----------------------|
133
+ | 1 | Spam Triggers | [P/W/F] | [detail] |
134
+ | 2 | Preview Text | [P/W/F] | [detail] |
135
+ | 3 | Dark Mode | [P/W/F] | [detail] |
136
+ | 4 | Unsubscribe/Address | [P/W/F] | [detail] |
137
+ | 5 | Content-to-Image Ratio | [P/W/F] | [detail] |
138
+ | 6 | Deliverability Signals | [P/W/F] | [detail] |
139
+ | 7 | Brand Voice | [P/W/F] | [detail] |
140
+
141
+ ISSUES (WARN/FAIL fixes):
142
+ - [Check]: [Specific fix recommendation]
143
+
144
+ VERDICT: [GO / CAUTION / NO-GO]
145
+ - GO: 0 FAIL + <=2 WARN -- safe to send
146
+ - CAUTION: >2 WARN -- review recommended before sending
147
+ - NO-GO: any FAIL -- must fix before sending
148
+ ```
149
+
150
+ </process>
@@ -0,0 +1,125 @@
1
+ <purpose>
2
+ Generate a keyword cluster map with intent tags for content planning. Groups keywords
3
+ by topic cluster, assigns search intent (informational/transactional/navigational/
4
+ commercial), and maps to content types and funnel stages.
5
+ Single-pass analysis workflow per D-07.
6
+ </purpose>
7
+
8
+ <required_reading>
9
+ @${CLAUDE_PLUGIN_ROOT}/references/context-loading.md
10
+ @${CLAUDE_PLUGIN_ROOT}/playbooks/seo.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
+ - Flag the issue and recommend running /ttm-positioning-check
20
+
21
+ Only /ttm-positioning-shift and /ttm-init may modify POSITIONING.md.
22
+ </constraints>
23
+
24
+ <process>
25
+
26
+ ## Text-Mode Detection
27
+
28
+ **Text mode (`--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS`
29
+ or if the runtime is not Claude Code. When TEXT_MODE is active, replace every
30
+ `AskUserQuestion` call with a plain-text numbered list.
31
+
32
+ Detection:
33
+ ```bash
34
+ if echo "$ARGUMENTS" | grep -q -- '--text'; then TEXT_MODE=true; fi
35
+ ```
36
+
37
+ If `AskUserQuestion` tool is not available in the current runtime, set `TEXT_MODE=true`.
38
+
39
+ ---
40
+
41
+ ## Step 1: Load Context
42
+
43
+ ```
44
+ takeToMarket > LOADING CONTEXT FOR KEYWORD MAP
45
+ ```
46
+
47
+ **Tier 1 summaries** (lines 1 to `<!-- END_SUMMARY -->`) from all 9 `.marketing/` reference files.
48
+ **Tier 2 (full):** `.marketing/POSITIONING.md`, `.marketing/CHANNELS.md`, `.marketing/COMPETITORS.md`
49
+
50
+ If `.marketing/POSITIONING.md` does not exist: Error and exit.
51
+
52
+ ---
53
+
54
+ ## Step 2: Gather Seed Keywords
55
+
56
+ Ask the user:
57
+ 1. "What are your primary seed keywords or topics? (comma-separated)"
58
+ 2. "Any specific competitors to include in keyword gap analysis? (or 'use COMPETITORS.md')"
59
+ 3. "Target geography/language? (default: English, global)"
60
+
61
+ If user says "use COMPETITORS.md", extract competitor names from the loaded file.
62
+
63
+ MCP Detection: Attempt WebSearch for seed keyword variations.
64
+ - **SEARCH_MODE=web:** Use WebSearch to expand seed keywords with related terms, "people also ask" patterns, and competitor keyword gaps.
65
+ - **SEARCH_MODE=manual:** Work with user-provided seeds + positioning + ICP context to generate clusters from domain knowledge.
66
+
67
+ ---
68
+
69
+ ## Step 3: Generate Keyword Clusters
70
+
71
+ For each seed keyword, generate clusters:
72
+ - **Head terms** (1-2 words, high volume)
73
+ - **Body terms** (2-3 words, medium volume)
74
+ - **Long-tail terms** (4+ words, specific intent)
75
+
76
+ Assign to each keyword:
77
+ - **Intent tag:** informational / transactional / navigational / commercial-investigation
78
+ - **Funnel stage:** awareness / consideration / decision / retention
79
+ - **Content type:** blog / landing page / comparison / how-to / case study / tool
80
+ - **Priority:** H (high) / M (medium) / L (low) based on intent alignment with ICP
81
+
82
+ Group into topic clusters with pillar-cluster relationships.
83
+
84
+ ---
85
+
86
+ ## Step 4: Output Keyword Map
87
+
88
+ Write to `.marketing/KEYWORD-MAP.md`:
89
+
90
+ ```markdown
91
+ # Keyword Map
92
+ Generated: [date]
93
+ Seeds: [list]
94
+ Geography: [target]
95
+
96
+ ## Cluster: [Topic 1]
97
+ Pillar: [pillar keyword]
98
+
99
+ | Keyword | Intent | Funnel | Content Type | Priority |
100
+ |---------|--------|--------|--------------|----------|
101
+ | [term] | [info/trans/nav/comm] | [stage] | [type] | [H/M/L] |
102
+
103
+ ## Cluster: [Topic 2]
104
+ ...
105
+
106
+ ## Gap Analysis
107
+ Keywords competitors rank for that are not covered:
108
+ | Keyword | Competitor | Intent | Opportunity |
109
+ |---------|-----------|--------|-------------|
110
+ ```
111
+
112
+ ---
113
+
114
+ ## Step 5: Completion
115
+
116
+ ```
117
+ ========================================
118
+ takeToMarket > KEYWORD MAP COMPLETE
119
+ ========================================
120
+ Clusters: [N] | Keywords: [total] | File: .marketing/KEYWORD-MAP.md
121
+ ```
122
+
123
+ Display a summary table of clusters with keyword counts per cluster.
124
+
125
+ </process>
@@ -0,0 +1,329 @@
1
+ <purpose>
2
+ Fan out a long-form source asset into derivative assets across channels. Executes full
3
+ brief-produce-verify per derivative with hero-first Task() orchestration. Each derivative
4
+ gets a channel-adapted brief, fresh production context, and independent verification.
5
+ This is NOT a lightweight command -- it runs the full production lifecycle per derivative.
6
+ </purpose>
7
+
8
+ <required_reading>
9
+ @${CLAUDE_PLUGIN_ROOT}/references/context-loading.md
10
+ @${CLAUDE_PLUGIN_ROOT}/agents/ttm-producer.md
11
+ @${CLAUDE_PLUGIN_ROOT}/workflows/lifecycle/brief.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
+ ## Campaign Context Required
26
+
27
+ This workflow MUST be run within an existing campaign context. The source asset must
28
+ exist in a campaign's ASSETS/ directory with a campaign that is in phase: produced,
29
+ verified, reviewed, fixed, or shipped.
30
+ </constraints>
31
+
32
+ <process>
33
+
34
+ ## Text-Mode Detection
35
+
36
+ **Text mode (`--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS`
37
+ or if the runtime is not Claude Code. When TEXT_MODE is active, replace every
38
+ `AskUserQuestion` call with a plain-text numbered list.
39
+
40
+ Detection:
41
+ ```bash
42
+ if echo "$ARGUMENTS" | grep -q -- '--text'; then TEXT_MODE=true; fi
43
+ ```
44
+
45
+ If `AskUserQuestion` tool is not available in the current runtime, set `TEXT_MODE=true`.
46
+
47
+ When TEXT_MODE is active, replace each AskUserQuestion with a plain-text numbered list:
48
+ ```
49
+ [HEADER]
50
+ [QUESTION]
51
+ 1. [OPTION_1_LABEL] -- [OPTION_1_DESCRIPTION]
52
+ 2. [OPTION_2_LABEL] -- [OPTION_2_DESCRIPTION]
53
+ ...
54
+ Type the number of your choice:
55
+ ```
56
+
57
+ ---
58
+
59
+ ## Step 1: Load Context
60
+
61
+ ```
62
+ takeToMarket > LOADING REPURPOSE CONTEXT
63
+ ```
64
+
65
+ Extract SOURCE_ASSET_PATH from $ARGUMENTS (strip `--text` flag if present):
66
+ ```bash
67
+ SOURCE_ASSET_PATH=$(echo "$ARGUMENTS" | sed 's/--text//g' | xargs)
68
+ ```
69
+
70
+ Read Tier 1 summaries from all 9 reference files (lines 1 to `<!-- END_SUMMARY -->`):
71
+ - `.marketing/POSITIONING.md`
72
+ - `.marketing/BRAND.md`
73
+ - `.marketing/ICP.md`
74
+ - `.marketing/CHANNELS.md`
75
+ - `.marketing/STATE.md` (frontmatter only)
76
+ - `.marketing/CALENDAR.md`
77
+ - `.marketing/COMPETITORS.md`
78
+ - `.marketing/METRICS.md`
79
+ - `.marketing/LEARNINGS.md`
80
+
81
+ Read Tier 2 (full content) for production context:
82
+ - `.marketing/POSITIONING.md`
83
+ - `.marketing/CHANNELS.md`
84
+ - `.marketing/BRAND.md`
85
+ - `.marketing/ICP.md`
86
+
87
+ ---
88
+
89
+ ## Step 2: Identify Source Asset
90
+
91
+ Parse SOURCE_ASSET_PATH from $ARGUMENTS.
92
+
93
+ ### Validate Path (T-10-11 mitigation)
94
+
95
+ Use path.resolve() equivalent to canonicalize the path, then verify:
96
+
97
+ 1. **File exists** at the specified path
98
+ 2. **Path is within `.marketing/CAMPAIGNS/`** directory -- reject any path that does not
99
+ resolve to a location under `.marketing/CAMPAIGNS/[slug]/ASSETS/`
100
+ 3. **Campaign is in appropriate phase** -- read the campaign's STATE.md and confirm phase
101
+ is one of: produced, verified, reviewed, fixed, or shipped
102
+
103
+ Extract from the validated path and campaign data:
104
+ - `CAMPAIGN_SLUG` -- extracted from the path (the directory name under CAMPAIGNS/)
105
+ - `SOURCE_ASSET_ID` -- look up the source file in MANIFEST.json by matching the filename
106
+ against hero.file and derivatives[].file entries. Extract the matching asset_id.
107
+ - `SOURCE_CHANNEL` -- from the matching MANIFEST.json asset entry's channel field
108
+ - `SOURCE_CONTENT` -- read the full file content
109
+
110
+ If validation fails at any step, display a specific error:
111
+ - Path not found: "Source asset not found at [path]. Check the file path and try again."
112
+ - Not in CAMPAIGNS: "Source asset must be within a .marketing/CAMPAIGNS/[slug]/ASSETS/ directory."
113
+ - Wrong phase: "Campaign [slug] is in phase [phase]. Repurpose requires produced, verified, reviewed, fixed, or shipped."
114
+ - Not in MANIFEST: "Source asset not found in MANIFEST.json. Was this asset produced by /ttm-produce?"
115
+
116
+ ---
117
+
118
+ ## Step 3: Select Target Channels
119
+
120
+ Read `.marketing/CHANNELS.md` active channels list.
121
+
122
+ Parse all active channels from CHANNELS.md. Remove SOURCE_CHANNEL from the list
123
+ (do not repurpose to the same channel the source was produced for).
124
+
125
+ Default selection: all remaining active channels.
126
+
127
+ Ask user for channel selection (per D-12):
128
+
129
+ ```
130
+ AskUserQuestion:
131
+ title: "Repurpose Target Channels"
132
+ question: "Repurpose to which channels? Default: all active channels minus source."
133
+ options:
134
+ - label: "All channels"
135
+ description: "[list all remaining channels]"
136
+ - label: "[channel 1]"
137
+ description: "Repurpose to [channel 1] only"
138
+ - label: "[channel 2]"
139
+ description: "Repurpose to [channel 2] only"
140
+ - label: "Custom selection"
141
+ description: "Enter comma-separated channel numbers"
142
+ ```
143
+
144
+ If user selects "All channels" or accepts the default: use all remaining active channels.
145
+ If user selects a specific channel: use only that channel.
146
+ If user selects "Custom selection": collect comma-separated numbers and resolve to channels.
147
+
148
+ ### Identify Hero Channel (per D-13)
149
+
150
+ From the selected target channels, identify the HERO_CHANNEL -- the channel with the
151
+ highest reach baseline from CHANNELS.md metrics/baselines section.
152
+
153
+ If baselines are not available or tied: use the first channel in the selected list.
154
+
155
+ Store `HERO_CHANNEL` and `HERO_CHANNEL_SLUG` (URL-safe version of channel name).
156
+ Store remaining channels as `REMAINING_CHANNELS`.
157
+
158
+ ---
159
+
160
+ ## Step 4: Generate Derivative Briefs
161
+
162
+ ```
163
+ takeToMarket > GENERATING DERIVATIVE BRIEFS ([N] channels)
164
+ ```
165
+
166
+ For each target channel, generate a channel-adapted derivative brief (per D-11).
167
+
168
+ Read the source asset content and extract the core message/thesis.
169
+ Cross-reference `.marketing/CHANNELS.md` for each target channel's configuration:
170
+ - Format requirements (content type, structure)
171
+ - Typical length/word count for the channel
172
+ - Audience overlap with source channel
173
+
174
+ Cross-reference `.marketing/BRAND.md` for tone-per-context adjustments if defined
175
+ for the target channel.
176
+
177
+ Write each brief with these sections:
178
+ - **Header:** Derivative Brief title, source filename, campaign slug, source asset ID
179
+ - **Adaptation Requirements:** Channel name, format (from CHANNELS.md), length, tone adjustment (from BRAND.md or "match source")
180
+ - **Core Message:** Extract primary thesis, key claims, and CTA from source (must be preserved)
181
+ - **Channel-Specific Adaptations:** Hook/opening, structure, length limits, CTA format, playbook rules
182
+ - **Positioning Anchor:** Primary differentiator and proof points from POSITIONING.md (direct quote)
183
+ - **Outcome Metric:** Inherit from campaign BRIEF.md, or channel-default from CHANNELS.md baselines
184
+
185
+ Write each brief to: `.marketing/CAMPAIGNS/${CAMPAIGN_SLUG}/REPURPOSE-BRIEF-${CHANNEL_SLUG}.md`
186
+
187
+ ---
188
+
189
+ ## Step 5: Produce Hero Derivative
190
+
191
+ ```
192
+ takeToMarket > REPURPOSING: HERO DERIVATIVE ([HERO_CHANNEL])
193
+ ```
194
+
195
+ Read the agent prompt template from `${CLAUDE_PLUGIN_ROOT}/agents/ttm-producer.md`.
196
+
197
+ Fill placeholders:
198
+ - `[BRIEF_PATH]` --> `.marketing/CAMPAIGNS/${CAMPAIGN_SLUG}/REPURPOSE-BRIEF-${HERO_CHANNEL_SLUG}.md`
199
+ - `[POSITIONING_PATH]` --> `.marketing/POSITIONING.md`
200
+ - `[BRAND_PATH]` --> `.marketing/BRAND.md`
201
+ - `[ICP_PATH]` --> `.marketing/ICP.md`
202
+ - `[PLAYBOOK_PATH]` --> resolved playbook for HERO_CHANNEL (from `${CLAUDE_PLUGIN_ROOT}/playbooks/${CHANNEL_TYPE}.md`), or `"none"` if not found
203
+ - `[OUTPUT_PATH]` --> `.marketing/CAMPAIGNS/${CAMPAIGN_SLUG}/ASSETS/R-01-${HERO_CHANNEL_SLUG}.md`
204
+ - `[ASSET_TYPE]` --> derivative content type for this channel
205
+ - `[CHANNEL]` --> HERO_CHANNEL name
206
+ - `[HERO_PATH]` --> SOURCE_ASSET_PATH (the original source serves as the "hero" reference)
207
+
208
+ Also inject a "Source Asset Reference" section into the prompt with SOURCE_CHANNEL
209
+ and SOURCE_ASSET_PATH so the producer can reference the original content.
210
+
211
+ Call Task() with the populated prompt.
212
+ **WAIT** for Task() to complete before proceeding.
213
+
214
+ After Task() returns, verify the hero derivative file exists and has content:
215
+ ```bash
216
+ test -s ".marketing/CAMPAIGNS/${CAMPAIGN_SLUG}/ASSETS/R-01-${HERO_CHANNEL_SLUG}.md"
217
+ ```
218
+
219
+ If the file is empty or missing:
220
+ Error: "Hero derivative production failed -- file not written by subagent."
221
+ Exit.
222
+
223
+ ---
224
+
225
+ ## Step 6: Produce Remaining Derivatives (Wave-Parallel)
226
+
227
+ If only 1 target channel was selected (hero only): skip this step.
228
+
229
+ ```
230
+ takeToMarket > REPURPOSING: DERIVATIVES ([N] channels, wave-parallel)
231
+ ```
232
+
233
+ For each channel in REMAINING_CHANNELS:
234
+
235
+ 1. Read agent prompt template from `${CLAUDE_PLUGIN_ROOT}/agents/ttm-producer.md`
236
+
237
+ 2. Assign sequential filename: `R-[NN]-${CHANNEL_SLUG}.md` where NN starts at 02
238
+
239
+ 3. Fill all placeholders (same pattern as Step 5, with channel-specific values and
240
+ `[HERO_PATH]` pointing to the hero derivative `R-01-${HERO_CHANNEL_SLUG}.md`)
241
+ 4. Inject Source Asset Reference (same as Step 5)
242
+ 5. Call Task() with the populated prompt
243
+
244
+ All derivative Task() calls run in parallel (per D-13 wave-parallel pattern).
245
+
246
+ After ALL Task() calls complete, verify each output file exists and has content (> 50 chars):
247
+ ```bash
248
+ test -s ".marketing/CAMPAIGNS/${CAMPAIGN_SLUG}/ASSETS/R-${NN}-${CHANNEL_SLUG}.md"
249
+ ```
250
+
251
+ For any derivative that failed (file empty or missing):
252
+ - Log warning: `takeToMarket > WARNING: Derivative R-${NN}-${CHANNEL_SLUG}.md failed`
253
+ - Continue with remaining assets. Do NOT abort the repurpose run.
254
+
255
+ Track successful and failed derivatives for the manifest and completion banner.
256
+
257
+ ---
258
+
259
+ ## Step 7: Verify Derivatives
260
+
261
+ ```
262
+ takeToMarket > VERIFYING DERIVATIVES
263
+ ```
264
+
265
+ For each successfully produced derivative, run simplified inline gate checks:
266
+
267
+ Run 3 simplified gates per derivative (PASS / WARN / FAIL each):
268
+
269
+ 1. **Positioning Drift** -- maintains primary differentiator, claims trace to proof points, no must-not-say terms
270
+ 2. **Format Correctness** -- meets channel length constraints, has required structural elements (hook, CTA), follows channel conventions
271
+ 3. **Voice Drift** -- matches BRAND.md voice archetype, no banned words, tone consistent with source
272
+
273
+ Record results as `VERIFY_RESULTS` array with per-derivative gate outcomes.
274
+
275
+ If any FAIL: flag for user attention but do NOT auto-fix. Recommend `/ttm-fix` or `/ttm-verify`.
276
+
277
+ ---
278
+
279
+ ## Step 8: Update MANIFEST.json
280
+
281
+ ```
282
+ takeToMarket > UPDATING MANIFEST
283
+ ```
284
+
285
+ Read existing MANIFEST.json to determine the next available asset_id.
286
+ Find the maximum asset_id across hero.asset_id and all derivatives[].asset_id.
287
+ Set NEXT_ID = max_id + 1.
288
+
289
+ Build `DERIVATIVES_JSON` array -- one entry per successfully produced derivative, each with
290
+ `asset_id` (sequential from NEXT_ID), `name`, `type: "derivative"`, `channel`, and `file`.
291
+
292
+ Run the campaign.cjs CLI to update MANIFEST.json:
293
+ ```bash
294
+ node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign repurpose-manifest "${CAMPAIGN_SLUG}" ${SOURCE_ASSET_ID} '${DERIVATIVES_JSON}'
295
+ ```
296
+
297
+ Verify the command succeeded (exit code 0 and output contains "derivatives_added").
298
+
299
+ ---
300
+
301
+ ## Step 9: Completion Banner
302
+
303
+ Display a banner with:
304
+ - Source asset name and channel
305
+ - Campaign slug
306
+ - Derivative count (successful / attempted)
307
+ - Per-derivative table: #, Channel, File, Positioning result, Format result, Voice result
308
+ - Warnings for any failed productions or FAIL gate results
309
+ - Manifest and brief file paths
310
+ - Next steps: `/ttm-verify`, `/ttm-review`, `/ttm-fix`
311
+
312
+ </process>
313
+
314
+ <success_criteria>
315
+ - [ ] Source asset validated (exists, in campaign, campaign in correct phase)
316
+ - [ ] Channel selection defaults to all active minus source, with user override
317
+ - [ ] Hero derivative produced first (blocking) in highest-reach channel
318
+ - [ ] Remaining derivatives produced in wave-parallel via Task()
319
+ - [ ] Each derivative gets a channel-adapted brief cross-referencing CHANNELS.md
320
+ - [ ] Simplified verification (positioning drift, format, voice) runs per derivative
321
+ - [ ] All derivatives tracked in MANIFEST.json with source_asset_id
322
+ - [ ] Completion banner with per-derivative verification results
323
+ </success_criteria>
324
+
325
+ <output>
326
+ - `.marketing/CAMPAIGNS/${SLUG}/REPURPOSE-BRIEF-*.md` (per-channel derivative briefs)
327
+ - `.marketing/CAMPAIGNS/${SLUG}/ASSETS/R-*.md` (produced derivative assets)
328
+ - `.marketing/CAMPAIGNS/${SLUG}/MANIFEST.json` (updated with derivative entries)
329
+ </output>