taketomarket 2.2.0 → 2.3.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/marketplace.json +4 -4
- package/.claude-plugin/plugin.json +2 -2
- package/README.md +34 -11
- package/bin/lib/campaign.cjs +12 -8
- package/bin/lib/codebase-scan.cjs +86 -0
- package/bin/lib/config.cjs +129 -0
- package/bin/lib/deploy.cjs +36 -0
- package/bin/lib/deviation.cjs +1 -1
- package/bin/lib/drift-log.cjs +4 -4
- package/bin/lib/health.cjs +32 -31
- package/bin/lib/install-detect.cjs +62 -0
- package/bin/lib/legacy-folder.cjs +100 -0
- package/bin/lib/playwright-check.cjs +26 -0
- package/bin/lib/site-location.cjs +22 -0
- package/bin/lib/state.cjs +3 -3
- package/bin/lib/svg-render.cjs +42 -0
- package/bin/ttm-tools.cjs +136 -4
- package/gates/base-gates.md +8 -8
- package/gates/gate-evaluation.md +8 -8
- package/install.js +37 -3
- package/package.json +10 -6
- package/playbooks/aeo.md +218 -114
- package/playbooks/affiliate.md +225 -160
- package/playbooks/email.md +236 -174
- package/playbooks/events.md +303 -213
- package/playbooks/landing-pages.md +305 -0
- package/playbooks/linkedin.md +264 -142
- package/playbooks/manifesto.md +322 -0
- package/playbooks/paid-ads.md +240 -189
- package/playbooks/positioning.md +340 -0
- package/playbooks/pr-media.md +308 -168
- package/playbooks/pseo.md +426 -0
- package/playbooks/seo.md +251 -158
- package/playbooks/social.md +253 -182
- package/playbooks/youtube.md +286 -181
- package/references/brand-color-theory.md +48 -0
- package/references/codex-image-gen-research.md +58 -0
- package/references/context-loading.md +6 -6
- package/references/humanizer-patterns.md +433 -0
- package/references/inline-education-blurbs.md +461 -0
- package/references/landing-page-anatomy.md +64 -0
- package/references/linkedin-post-patterns.md +174 -0
- package/references/logo-design-principles.md +55 -0
- package/references/meta-gate-evaluation.md +3 -3
- package/references/obra-superpowers-conventions.md +170 -0
- package/references/playbook-leaders.md +472 -0
- package/references/playwright-mcp-setup.md +164 -0
- package/references/positioning-check-report.md +2 -2
- package/references/pseo-page-anatomy.md +56 -0
- package/references/pseo-templates/alternative-anatomy.md +31 -0
- package/references/pseo-templates/alternative-content-playbook.md +32 -0
- package/references/pseo-templates/blog-anatomy.md +28 -0
- package/references/pseo-templates/blog-content-playbook.md +36 -0
- package/references/pseo-templates/comparison-anatomy.md +29 -0
- package/references/pseo-templates/comparison-content-playbook.md +35 -0
- package/references/pseo-templates/use-case-anatomy.md +28 -0
- package/references/pseo-templates/use-case-content-playbook.md +30 -0
- package/skills/ttm-101/SKILL.md +25 -0
- package/skills/ttm-aeo-check/SKILL.md +17 -12
- package/skills/ttm-affiliate-kit/SKILL.md +5 -0
- package/skills/ttm-archive/SKILL.md +5 -0
- package/skills/ttm-brand-refresh/SKILL.md +5 -0
- package/skills/ttm-brief/SKILL.md +5 -0
- package/skills/ttm-competitor-scan/SKILL.md +5 -0
- package/skills/ttm-deploy/SKILL.md +22 -0
- package/skills/ttm-discover/SKILL.md +17 -0
- package/skills/ttm-email-check/SKILL.md +17 -0
- package/skills/ttm-email-preflight/SKILL.md +17 -11
- package/skills/ttm-fix/SKILL.md +5 -0
- package/skills/ttm-health/SKILL.md +6 -1
- package/skills/ttm-humanize/SKILL.md +33 -0
- package/skills/ttm-icp-refresh/SKILL.md +5 -0
- package/skills/ttm-improve-skill/SKILL.md +18 -0
- package/skills/ttm-init/SKILL.md +10 -3
- package/skills/ttm-keyword-map/SKILL.md +17 -11
- package/skills/ttm-landing/SKILL.md +19 -0
- package/skills/ttm-learn/SKILL.md +5 -0
- package/skills/ttm-linkedin-post/SKILL.md +26 -0
- package/skills/ttm-measure/SKILL.md +5 -0
- package/skills/ttm-new-campaign/SKILL.md +5 -0
- package/skills/ttm-next/SKILL.md +5 -0
- package/skills/ttm-playwright-setup/SKILL.md +18 -0
- package/skills/ttm-positioning-check/SKILL.md +5 -0
- package/skills/ttm-positioning-shift/SKILL.md +5 -0
- package/skills/ttm-produce/SKILL.md +5 -0
- package/skills/ttm-pseo/SKILL.md +26 -0
- package/skills/ttm-repurpose/SKILL.md +5 -0
- package/skills/ttm-request-skill/SKILL.md +18 -0
- package/skills/ttm-research/SKILL.md +18 -6
- package/skills/ttm-resume/SKILL.md +5 -0
- package/skills/ttm-review/SKILL.md +5 -0
- package/skills/ttm-seo/SKILL.md +64 -0
- package/skills/ttm-seo-audit/SKILL.md +17 -12
- package/skills/ttm-ship/SKILL.md +5 -0
- package/skills/ttm-state/SKILL.md +5 -0
- package/skills/ttm-update/SKILL.md +152 -4
- package/skills/ttm-verify/SKILL.md +5 -0
- package/templates/agents-md.md +14 -4
- package/templates/campaign-research.md +6 -6
- package/templates/campaign-state.md +1 -1
- package/templates/claude-md.md +14 -4
- package/templates/linkedin-base-template.md +48 -0
- package/templates/next-step-footer.md +13 -0
- package/templates/production-manifest.json +4 -4
- package/templates/pseo/alternative-cms-schema.json +65 -0
- package/templates/pseo/blog-cms-schema.json +55 -0
- package/templates/pseo/comparison-cms-schema.json +56 -0
- package/templates/pseo/use-case-cms-schema.json +62 -0
- package/templates/reference-files/brand.md +51 -0
- package/templates/reference-files/product-dna.md +73 -0
- package/templates/site-scaffold/app/globals.css +2 -0
- package/templates/site-scaffold/app/layout.tsx +17 -0
- package/templates/site-scaffold/app/page.tsx +33 -0
- package/templates/site-scaffold/app/robots.ts +8 -0
- package/templates/site-scaffold/app/sitemap.ts +10 -0
- package/templates/site-scaffold/app/tokens.css +21 -0
- package/templates/site-scaffold/components/Comparison.tsx +14 -0
- package/templates/site-scaffold/components/Faq.tsx +14 -0
- package/templates/site-scaffold/components/Features.tsx +14 -0
- package/templates/site-scaffold/components/FinalCta.tsx +17 -0
- package/templates/site-scaffold/components/Footer.tsx +12 -0
- package/templates/site-scaffold/components/Hero.tsx +22 -0
- package/templates/site-scaffold/components/HowItWorks.tsx +14 -0
- package/templates/site-scaffold/components/PricingTeaser.tsx +14 -0
- package/templates/site-scaffold/components/Problem.tsx +14 -0
- package/templates/site-scaffold/components/SocialProof.tsx +14 -0
- package/templates/site-scaffold/components/Solution.tsx +14 -0
- package/templates/site-scaffold/components/Testimonials.tsx +14 -0
- package/templates/site-scaffold/components/UseCases.tsx +14 -0
- package/templates/site-scaffold/content/.gitkeep +0 -0
- package/templates/site-scaffold/lib/.gitkeep +0 -0
- package/templates/site-scaffold/next.config.mjs +10 -0
- package/templates/site-scaffold/package.json +25 -0
- package/templates/site-scaffold/postcss.config.mjs +3 -0
- package/templates/site-scaffold/public/llms.txt +9 -0
- package/templates/site-scaffold/tsconfig.json +21 -0
- package/templates/verification-report.md +1 -1
- package/workflows/channel/linkedin-post.md +178 -0
- package/workflows/discipline/affiliate-kit.md +65 -6
- package/workflows/discipline/{email-preflight.md → email-check.md} +39 -4
- package/workflows/discipline/repurpose.md +82 -31
- package/workflows/discipline/{aeo-check.md → seo/aeo.md} +13 -6
- package/workflows/discipline/{seo-audit.md → seo/audit.md} +13 -6
- package/workflows/discipline/{keyword-map.md → seo/keyword-map.md} +13 -6
- package/workflows/education/ttm-101.md +114 -0
- package/workflows/lifecycle/brief-positioning-check.md +1 -1
- package/workflows/lifecycle/brief.md +64 -28
- package/workflows/lifecycle/{research.md → discover.md} +61 -19
- package/workflows/lifecycle/fix.md +72 -37
- package/workflows/lifecycle/humanize.md +280 -0
- package/workflows/lifecycle/learn.md +72 -35
- package/workflows/lifecycle/measure.md +54 -18
- package/workflows/lifecycle/produce.md +88 -37
- package/workflows/lifecycle/review.md +71 -25
- package/workflows/lifecycle/ship.md +62 -18
- package/workflows/lifecycle/verify.md +72 -26
- package/workflows/reference-mgmt/brand-refresh.md +50 -13
- package/workflows/reference-mgmt/competitor-scan.md +51 -15
- package/workflows/reference-mgmt/icp-refresh.md +48 -12
- package/workflows/reference-mgmt/positioning-check.md +55 -20
- package/workflows/reference-mgmt/positioning-shift.md +53 -17
- package/workflows/setup/init-brand-colors.md +75 -0
- package/workflows/setup/init-logo.md +113 -0
- package/workflows/setup/init-product-dna.md +83 -0
- package/workflows/setup/init-questions.md +166 -30
- package/workflows/setup/init-validation.md +22 -0
- package/workflows/setup/init.md +144 -39
- package/workflows/setup/new-campaign.md +48 -12
- package/workflows/site/deploy.md +98 -0
- package/workflows/site/landing.md +156 -0
- package/workflows/site/pseo.md +96 -0
- package/workflows/site/quality-gates.md +88 -0
- package/workflows/utility/archive.md +45 -9
- package/workflows/utility/health.md +77 -3
- package/workflows/utility/improve-skill.md +233 -0
- package/workflows/utility/next.md +38 -2
- package/workflows/utility/playwright-setup.md +128 -0
- package/workflows/utility/request-skill.md +218 -0
- package/workflows/utility/resume.md +40 -3
- package/workflows/utility/state.md +42 -7
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
<!-- _SUMMARY: Tier 1 context (loaded universally, <200 words) -->
|
|
2
|
+
## Summary
|
|
3
|
+
**Stage:** [GENERATED BY /ttm-init]
|
|
4
|
+
**Primary JTBD:** [GENERATED BY /ttm-init]
|
|
5
|
+
**Top belief (1-line):** [GENERATED BY /ttm-init]
|
|
6
|
+
**Worldview elevator pitch (2 sentences):** [GENERATED BY /ttm-init]
|
|
7
|
+
<!-- END_SUMMARY -->
|
|
8
|
+
|
|
9
|
+
# Product DNA
|
|
10
|
+
|
|
11
|
+
**Generated by `/ttm-init` on YYYY-MM-DD. Update by re-running `/ttm-init --update product-dna`.**
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## WHAT - Product Spec (code-scan-derived)
|
|
16
|
+
|
|
17
|
+
### Tech stack
|
|
18
|
+
[Auto-populated from codebase scan: languages, frameworks, key libraries.]
|
|
19
|
+
|
|
20
|
+
### Feature areas
|
|
21
|
+
[Auto-populated from directory structure + entry points. User confirms.]
|
|
22
|
+
|
|
23
|
+
### Capability map
|
|
24
|
+
[What this product can do, in capability-bullet form. User edits.]
|
|
25
|
+
|
|
26
|
+
### JTBD (Jobs To Be Done)
|
|
27
|
+
**Primary JTBD:** [The single most important job your customer hires this product to do.]
|
|
28
|
+
|
|
29
|
+
**Secondary JTBDs:**
|
|
30
|
+
- [JTBD 2]
|
|
31
|
+
- [JTBD 3]
|
|
32
|
+
|
|
33
|
+
### Stage
|
|
34
|
+
[Pre-MVP / MVP / Beta / GA / Mature]
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## WHY - Manifesto (user interview)
|
|
39
|
+
|
|
40
|
+
### Beliefs
|
|
41
|
+
Three to five things you believe that most people in your space don't.
|
|
42
|
+
|
|
43
|
+
1. [Belief 1]
|
|
44
|
+
2. [Belief 2]
|
|
45
|
+
3. [Belief 3]
|
|
46
|
+
|
|
47
|
+
### Anti-status-quo positions
|
|
48
|
+
What are you AGAINST? What conventional wisdom are you rejecting?
|
|
49
|
+
|
|
50
|
+
1. [Position 1]
|
|
51
|
+
2. [Position 2]
|
|
52
|
+
|
|
53
|
+
### Worldview
|
|
54
|
+
The 2-3 paragraph story of why this product exists. Not the marketing tagline - the actual motivation. Read like a founder's letter.
|
|
55
|
+
|
|
56
|
+
[Worldview prose.]
|
|
57
|
+
|
|
58
|
+
### Founding-team voice
|
|
59
|
+
Optional. If a co-founder or you personally have an authorial voice that shows up in content, capture it here in 2-3 example sentences.
|
|
60
|
+
|
|
61
|
+
[Voice samples.]
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## How this file is used
|
|
66
|
+
|
|
67
|
+
- `/ttm-produce` loads PRODUCT-DNA along with POSITIONING, BRAND, ICP into every production wave.
|
|
68
|
+
- `/ttm-positioning-check` references the manifesto's anti-status-quo positions as drift anchors.
|
|
69
|
+
- `/ttm-landing` and `/ttm-pseo` use beliefs + worldview as the source for hero copy and About pages.
|
|
70
|
+
|
|
71
|
+
## Update history
|
|
72
|
+
|
|
73
|
+
[Auto-appended each time /ttm-init --update is run.]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Metadata } from 'next';
|
|
2
|
+
import './globals.css';
|
|
3
|
+
|
|
4
|
+
export const metadata: Metadata = {
|
|
5
|
+
title: '{{SITE_TITLE}}',
|
|
6
|
+
description: '{{SITE_DESCRIPTION}}',
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
10
|
+
return (
|
|
11
|
+
<html lang="en">
|
|
12
|
+
<body className="bg-neutral-50 text-neutral-900 antialiased">
|
|
13
|
+
{children}
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Hero } from '@/components/Hero';
|
|
2
|
+
import { SocialProof } from '@/components/SocialProof';
|
|
3
|
+
import { Problem } from '@/components/Problem';
|
|
4
|
+
import { Solution } from '@/components/Solution';
|
|
5
|
+
import { HowItWorks } from '@/components/HowItWorks';
|
|
6
|
+
import { Features } from '@/components/Features';
|
|
7
|
+
import { UseCases } from '@/components/UseCases';
|
|
8
|
+
import { Comparison } from '@/components/Comparison';
|
|
9
|
+
import { Testimonials } from '@/components/Testimonials';
|
|
10
|
+
import { PricingTeaser } from '@/components/PricingTeaser';
|
|
11
|
+
import { Faq } from '@/components/Faq';
|
|
12
|
+
import { FinalCta } from '@/components/FinalCta';
|
|
13
|
+
import { Footer } from '@/components/Footer';
|
|
14
|
+
|
|
15
|
+
export default function Home() {
|
|
16
|
+
return (
|
|
17
|
+
<main>
|
|
18
|
+
<Hero />
|
|
19
|
+
<SocialProof />
|
|
20
|
+
<Problem />
|
|
21
|
+
<Solution />
|
|
22
|
+
<HowItWorks />
|
|
23
|
+
<Features />
|
|
24
|
+
<UseCases />
|
|
25
|
+
<Comparison />
|
|
26
|
+
<Testimonials />
|
|
27
|
+
<PricingTeaser />
|
|
28
|
+
<Faq />
|
|
29
|
+
<FinalCta />
|
|
30
|
+
<Footer />
|
|
31
|
+
</main>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { MetadataRoute } from 'next';
|
|
2
|
+
|
|
3
|
+
export default function sitemap(): MetadataRoute.Sitemap {
|
|
4
|
+
return [
|
|
5
|
+
{ url: '{{BASE_URL}}', lastModified: new Date() },
|
|
6
|
+
{ url: '{{BASE_URL}}/product', lastModified: new Date() },
|
|
7
|
+
{ url: '{{BASE_URL}}/pricing', lastModified: new Date() },
|
|
8
|
+
{ url: '{{BASE_URL}}/about', lastModified: new Date() },
|
|
9
|
+
];
|
|
10
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
@theme {
|
|
2
|
+
--color-primary: {{COLOR_PRIMARY}};
|
|
3
|
+
--color-primary-hover: {{COLOR_PRIMARY_HOVER}};
|
|
4
|
+
--color-primary-active: {{COLOR_PRIMARY_ACTIVE}};
|
|
5
|
+
--color-secondary: {{COLOR_SECONDARY}};
|
|
6
|
+
--color-accent: {{COLOR_ACCENT}};
|
|
7
|
+
--color-success: {{COLOR_SUCCESS}};
|
|
8
|
+
--color-warning: {{COLOR_WARNING}};
|
|
9
|
+
--color-error: {{COLOR_ERROR}};
|
|
10
|
+
--color-info: {{COLOR_INFO}};
|
|
11
|
+
--color-neutral-50: {{COLOR_NEUTRAL_50}};
|
|
12
|
+
--color-neutral-100: {{COLOR_NEUTRAL_100}};
|
|
13
|
+
--color-neutral-200: {{COLOR_NEUTRAL_200}};
|
|
14
|
+
--color-neutral-300: {{COLOR_NEUTRAL_300}};
|
|
15
|
+
--color-neutral-400: {{COLOR_NEUTRAL_400}};
|
|
16
|
+
--color-neutral-500: {{COLOR_NEUTRAL_500}};
|
|
17
|
+
--color-neutral-600: {{COLOR_NEUTRAL_600}};
|
|
18
|
+
--color-neutral-700: {{COLOR_NEUTRAL_700}};
|
|
19
|
+
--color-neutral-800: {{COLOR_NEUTRAL_800}};
|
|
20
|
+
--color-neutral-900: {{COLOR_NEUTRAL_900}};
|
|
21
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function Comparison() {
|
|
2
|
+
return (
|
|
3
|
+
<section className="px-6 py-20 bg-neutral-100">
|
|
4
|
+
<div className="mx-auto max-w-4xl">
|
|
5
|
+
<h2 className="text-3xl font-bold tracking-tight text-center">
|
|
6
|
+
{/* {{COMPARISON_HEADLINE}} */}
|
|
7
|
+
</h2>
|
|
8
|
+
<div className="mt-12">
|
|
9
|
+
{/* {{COMPARISON_TABLE}} */}
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
</section>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function Faq() {
|
|
2
|
+
return (
|
|
3
|
+
<section className="px-6 py-20">
|
|
4
|
+
<div className="mx-auto max-w-3xl">
|
|
5
|
+
<h2 className="text-3xl font-bold tracking-tight text-center">
|
|
6
|
+
{/* {{FAQ_HEADLINE}} */}
|
|
7
|
+
</h2>
|
|
8
|
+
<dl className="mt-12 space-y-6">
|
|
9
|
+
{/* {{FAQ_ITEMS}} */}
|
|
10
|
+
</dl>
|
|
11
|
+
</div>
|
|
12
|
+
</section>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function Features() {
|
|
2
|
+
return (
|
|
3
|
+
<section className="px-6 py-20 bg-neutral-100">
|
|
4
|
+
<div className="mx-auto max-w-5xl">
|
|
5
|
+
<h2 className="text-3xl font-bold tracking-tight">
|
|
6
|
+
{/* {{FEATURES_HEADLINE}} */}
|
|
7
|
+
</h2>
|
|
8
|
+
<div className="mt-12 space-y-16">
|
|
9
|
+
{/* {{FEATURES_BLOCKS}} */}
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
</section>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function FinalCta() {
|
|
2
|
+
return (
|
|
3
|
+
<section className="px-6 py-24 bg-[var(--color-primary)] text-white text-center">
|
|
4
|
+
<div className="mx-auto max-w-3xl">
|
|
5
|
+
<h2 className="text-4xl font-bold tracking-tight">
|
|
6
|
+
{/* {{FINAL_CTA_HEADLINE}} */}
|
|
7
|
+
</h2>
|
|
8
|
+
<p className="mt-4 text-lg opacity-90">
|
|
9
|
+
{/* {{FINAL_CTA_SUBHEAD}} */}
|
|
10
|
+
</p>
|
|
11
|
+
<a href="{{FINAL_CTA_HREF}}" className="mt-8 inline-block rounded-md bg-white px-5 py-3 text-neutral-900">
|
|
12
|
+
{/* {{FINAL_CTA_LABEL}} */}
|
|
13
|
+
</a>
|
|
14
|
+
</div>
|
|
15
|
+
</section>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function Footer() {
|
|
2
|
+
return (
|
|
3
|
+
<footer className="px-6 py-12 border-t border-neutral-200">
|
|
4
|
+
<div className="mx-auto max-w-5xl grid gap-8 md:grid-cols-4 text-sm text-neutral-600">
|
|
5
|
+
{/* {{FOOTER_COLUMNS}} */}
|
|
6
|
+
</div>
|
|
7
|
+
<p className="mt-8 text-center text-xs text-neutral-500">
|
|
8
|
+
{/* {{FOOTER_LEGAL}} */}
|
|
9
|
+
</p>
|
|
10
|
+
</footer>
|
|
11
|
+
);
|
|
12
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function Hero() {
|
|
2
|
+
return (
|
|
3
|
+
<section className="px-6 py-24 sm:py-32">
|
|
4
|
+
<div className="mx-auto max-w-3xl text-center">
|
|
5
|
+
<h1 className="text-5xl font-bold tracking-tight">
|
|
6
|
+
{/* {{HERO_HEADLINE}} */}
|
|
7
|
+
</h1>
|
|
8
|
+
<p className="mt-6 text-lg text-neutral-700">
|
|
9
|
+
{/* {{HERO_SUBHEAD}} */}
|
|
10
|
+
</p>
|
|
11
|
+
<div className="mt-10 flex justify-center gap-4">
|
|
12
|
+
<a href="{{HERO_CTA_PRIMARY_HREF}}" className="rounded-md bg-[var(--color-primary)] px-5 py-3 text-white">
|
|
13
|
+
{/* {{HERO_CTA_PRIMARY_LABEL}} */}
|
|
14
|
+
</a>
|
|
15
|
+
<a href="{{HERO_CTA_SECONDARY_HREF}}" className="rounded-md px-5 py-3 ring-1 ring-neutral-300">
|
|
16
|
+
{/* {{HERO_CTA_SECONDARY_LABEL}} */}
|
|
17
|
+
</a>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</section>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function HowItWorks() {
|
|
2
|
+
return (
|
|
3
|
+
<section className="px-6 py-20">
|
|
4
|
+
<div className="mx-auto max-w-5xl">
|
|
5
|
+
<h2 className="text-3xl font-bold tracking-tight text-center">
|
|
6
|
+
{/* {{HOW_IT_WORKS_HEADLINE}} */}
|
|
7
|
+
</h2>
|
|
8
|
+
<ol className="mt-12 grid gap-8 md:grid-cols-3">
|
|
9
|
+
{/* {{HOW_IT_WORKS_STEPS}} */}
|
|
10
|
+
</ol>
|
|
11
|
+
</div>
|
|
12
|
+
</section>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function PricingTeaser() {
|
|
2
|
+
return (
|
|
3
|
+
<section className="px-6 py-16 bg-neutral-100 text-center">
|
|
4
|
+
<div className="mx-auto max-w-3xl">
|
|
5
|
+
<p className="text-lg text-neutral-700">
|
|
6
|
+
{/* {{PRICING_TEASER_LINE}} */}
|
|
7
|
+
</p>
|
|
8
|
+
<a href="/pricing" className="mt-4 inline-block underline">
|
|
9
|
+
{/* {{PRICING_TEASER_CTA_LABEL}} */}
|
|
10
|
+
</a>
|
|
11
|
+
</div>
|
|
12
|
+
</section>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function Problem() {
|
|
2
|
+
return (
|
|
3
|
+
<section className="px-6 py-20">
|
|
4
|
+
<div className="mx-auto max-w-3xl">
|
|
5
|
+
<h2 className="text-3xl font-bold tracking-tight">
|
|
6
|
+
{/* {{PROBLEM_HEADLINE}} */}
|
|
7
|
+
</h2>
|
|
8
|
+
<p className="mt-6 text-lg text-neutral-700">
|
|
9
|
+
{/* {{PROBLEM_BODY}} */}
|
|
10
|
+
</p>
|
|
11
|
+
</div>
|
|
12
|
+
</section>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function SocialProof() {
|
|
2
|
+
return (
|
|
3
|
+
<section className="px-6 py-10 border-y border-neutral-200">
|
|
4
|
+
<div className="mx-auto max-w-5xl">
|
|
5
|
+
<p className="text-center text-sm text-neutral-500">
|
|
6
|
+
{/* {{SOCIAL_PROOF_TAGLINE}} */}
|
|
7
|
+
</p>
|
|
8
|
+
<div className="mt-6 flex flex-wrap justify-center gap-8 opacity-70">
|
|
9
|
+
{/* {{SOCIAL_PROOF_LOGOS}} */}
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
</section>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function Solution() {
|
|
2
|
+
return (
|
|
3
|
+
<section className="px-6 py-20 bg-neutral-100">
|
|
4
|
+
<div className="mx-auto max-w-5xl">
|
|
5
|
+
<h2 className="text-3xl font-bold tracking-tight text-center">
|
|
6
|
+
{/* {{SOLUTION_HEADLINE}} */}
|
|
7
|
+
</h2>
|
|
8
|
+
<div className="mt-12 grid gap-8 md:grid-cols-3">
|
|
9
|
+
{/* {{SOLUTION_PILLARS}} */}
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
</section>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function Testimonials() {
|
|
2
|
+
return (
|
|
3
|
+
<section className="px-6 py-20">
|
|
4
|
+
<div className="mx-auto max-w-5xl">
|
|
5
|
+
<h2 className="text-3xl font-bold tracking-tight text-center">
|
|
6
|
+
{/* {{TESTIMONIALS_HEADLINE}} */}
|
|
7
|
+
</h2>
|
|
8
|
+
<div className="mt-12 grid gap-8 md:grid-cols-2">
|
|
9
|
+
{/* {{TESTIMONIALS_QUOTES}} */}
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
</section>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function UseCases() {
|
|
2
|
+
return (
|
|
3
|
+
<section className="px-6 py-20">
|
|
4
|
+
<div className="mx-auto max-w-5xl">
|
|
5
|
+
<h2 className="text-3xl font-bold tracking-tight text-center">
|
|
6
|
+
{/* {{USE_CASES_HEADLINE}} */}
|
|
7
|
+
</h2>
|
|
8
|
+
<div className="mt-12 grid gap-6 md:grid-cols-2 lg:grid-cols-3">
|
|
9
|
+
{/* {{USE_CASES_CARDS}} */}
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
</section>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{SITE_NAME}}",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "next dev",
|
|
7
|
+
"build": "next build",
|
|
8
|
+
"start": "next start",
|
|
9
|
+
"lint": "next lint"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"next": "^15.0.0",
|
|
13
|
+
"react": "^19.0.0",
|
|
14
|
+
"react-dom": "^19.0.0"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/node": "^20",
|
|
18
|
+
"@types/react": "^19",
|
|
19
|
+
"@types/react-dom": "^19",
|
|
20
|
+
"tailwindcss": "^4.0.0",
|
|
21
|
+
"@tailwindcss/postcss": "^4.0.0",
|
|
22
|
+
"postcss": "^8.4.0",
|
|
23
|
+
"typescript": "^5.4.0"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"allowJs": false,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"jsx": "preserve",
|
|
15
|
+
"incremental": true,
|
|
16
|
+
"plugins": [{ "name": "next" }],
|
|
17
|
+
"paths": { "@/*": ["./*"] }
|
|
18
|
+
},
|
|
19
|
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
20
|
+
"exclude": ["node_modules"]
|
|
21
|
+
}
|
|
@@ -54,6 +54,6 @@ overall_result: [pass|warn|fail]
|
|
|
54
54
|
## Run Metadata
|
|
55
55
|
|
|
56
56
|
- **Verify command:** `/ttm-verify [SLUG]`
|
|
57
|
-
- **Manifest:** `.
|
|
57
|
+
- **Manifest:** `.taketomarket/CAMPAIGNS/[SLUG]/MANIFEST.json`
|
|
58
58
|
- **Gate definitions:** `gates/base-gates.md`
|
|
59
59
|
- **Previous runs:** [PREVIOUS_RUN_COUNT]
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# LinkedIn Post Workflow
|
|
2
|
+
|
|
3
|
+
## Step 0: First-run inline education
|
|
4
|
+
|
|
5
|
+
Read `.taketomarket/CONFIG.md`. Parse `first_run_seen` (object) and `inline_education` (boolean, default true).
|
|
6
|
+
|
|
7
|
+
If `inline_education` is false: skip this step. Else if `first_run_seen.ttm-linkedin-post` is not `true`, print the explainer below verbatim, then mark this skill as seen:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" first-run mark ttm-linkedin-post
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Use this exact check (bash) to decide whether to print: `node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" first-run check ttm-linkedin-post --raw` -- the JSON `seen` field is `true` once the explainer has run before.
|
|
14
|
+
|
|
15
|
+
### Explainer for `/ttm-linkedin-post`
|
|
16
|
+
|
|
17
|
+
`/ttm-linkedin-post` generates a LinkedIn post from a campaign brief or
|
|
18
|
+
a raw thought, applies the LinkedIn-specific patterns (hook, scannable
|
|
19
|
+
structure, comment-bait, no link in body), and routes it through the
|
|
20
|
+
gate wall. Output is a ready-to-post draft plus a comment-thread plan.
|
|
21
|
+
|
|
22
|
+
Why it matters: LinkedIn rewards a specific format that violates
|
|
23
|
+
general copywriting rules (short lines, deliberate whitespace,
|
|
24
|
+
no-link bodies). Generic LLM output writes essays; this skill writes
|
|
25
|
+
posts that match the platform's actual distribution mechanics.
|
|
26
|
+
|
|
27
|
+
(Canonical source: `references/inline-education-blurbs.md`. Embedded verbatim because workflows do not @-resolve files at runtime.)
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
**Required reading:**
|
|
32
|
+
- `${CLAUDE_PLUGIN_ROOT}/references/linkedin-post-patterns.md`
|
|
33
|
+
- `${CLAUDE_PLUGIN_ROOT}/playbooks/linkedin.md`
|
|
34
|
+
- `${CLAUDE_PLUGIN_ROOT}/references/playwright-mcp-setup.md`
|
|
35
|
+
- `${CLAUDE_PLUGIN_ROOT}/templates/linkedin-base-template.md`
|
|
36
|
+
- `.taketomarket/POSITIONING.md`, `BRAND.md`, `PRODUCT-DNA.md`, `ICP.md`
|
|
37
|
+
- `.taketomarket/PLAYBOOKS/linkedin-base.md` (created on first run)
|
|
38
|
+
- `.taketomarket/CAMPAIGNS/linkedin/post-history.md` (created on first run)
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Step 1: Detect first-run
|
|
43
|
+
|
|
44
|
+
Check if `.taketomarket/PLAYBOOKS/linkedin-base.md` exists.
|
|
45
|
+
|
|
46
|
+
If NOT (or `--rebuild-base` flag): go to Step 2 (interview + scrape).
|
|
47
|
+
If YES: go to Step 6 (generate post).
|
|
48
|
+
|
|
49
|
+
## Step 2: First-run author interview
|
|
50
|
+
|
|
51
|
+
AskUserQuestion (priority: critical):
|
|
52
|
+
- "Which 2-5 LinkedIn creators write in the style you want to mimic? Paste their profile URLs."
|
|
53
|
+
- Freeform, expect 2-5 URLs.
|
|
54
|
+
|
|
55
|
+
## Step 3: Playwright check
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
node ${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs playwright-check --raw
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
If detected = false: print "Author scraping needs Playwright MCP. Run /ttm-playwright-setup first." Then exit the workflow.
|
|
62
|
+
|
|
63
|
+
Also check the extension capability:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
node ${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs config read --raw
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
If `playwright_mcp_extension` is not `true`: print "Author scraping needs the Chrome extension bridge (`--extension`) so Playwright can use your logged-in LinkedIn session. Re-run /ttm-playwright-setup and re-add Playwright with the `--extension` flag, then retry." Exit.
|
|
70
|
+
|
|
71
|
+
## Step 4: Scrape authors
|
|
72
|
+
|
|
73
|
+
For each profile URL:
|
|
74
|
+
- Call `browser_navigate` with the URL (Playwright MCP uses logged-in Chrome session via the bridge → reaches authenticated LinkedIn).
|
|
75
|
+
- Call `browser_snapshot` to read rendered DOM.
|
|
76
|
+
- Scroll-and-snapshot loop until ~10-20 posts are captured.
|
|
77
|
+
|
|
78
|
+
For each post: capture text + engagement count + post type (text / image / carousel / video).
|
|
79
|
+
|
|
80
|
+
Save raw scrapes to `.taketomarket/CAMPAIGNS/linkedin/scrapes/<author-handle>.md`.
|
|
81
|
+
|
|
82
|
+
## Step 5: Analyze + build linkedin-base.md
|
|
83
|
+
|
|
84
|
+
For each author:
|
|
85
|
+
- Compute sentence length distribution.
|
|
86
|
+
- Extract hook patterns (first 80 chars of each post).
|
|
87
|
+
- Identify recurring structure templates.
|
|
88
|
+
- Extract recurring phrases / voice tics.
|
|
89
|
+
- Note topics + cadence.
|
|
90
|
+
|
|
91
|
+
Synthesize across authors. Apply `references/linkedin-post-patterns.md` framework. Fill in `templates/linkedin-base-template.md` placeholders. Write to `.taketomarket/PLAYBOOKS/linkedin-base.md`.
|
|
92
|
+
|
|
93
|
+
## Step 6: Load context for this post
|
|
94
|
+
|
|
95
|
+
- Load linkedin-base.md, POSITIONING, BRAND, PRODUCT-DNA, ICP.
|
|
96
|
+
- Load post-history.md and extract from each row (pipe-format `| YYYY-MM-DD | <topic-tag> | <hook-pattern> | <slug> | <link> |`):
|
|
97
|
+
- `<topic-tag>` values from the last 30 days — these are the canonical topic keys (set by frontmatter `topic` in Step 11 and copied into the history row in Step 12).
|
|
98
|
+
- `<hook-pattern>` values from the last 5 rows.
|
|
99
|
+
- Avoid: any `<topic-tag>` that appears in the last 30 days; any `<hook-pattern>` that appears in the last 5 posts.
|
|
100
|
+
|
|
101
|
+
## Step 7: Web search for news angles
|
|
102
|
+
|
|
103
|
+
Unless `--no-news`:
|
|
104
|
+
- Read `.taketomarket/ICP.md` (top headings: industry, segments) + `.taketomarket/POSITIONING.md` `## Category`. Extract 2-3 industry terms.
|
|
105
|
+
- Construct 1-2 WebSearch queries combining those terms with `2026` and platform-specific operators (e.g., `site:techcrunch.com`).
|
|
106
|
+
- Pass `recency:7d` (or equivalent) to scope to last 7 days.
|
|
107
|
+
- Surface 3-5 recent stories. Rank by relevance to product positioning.
|
|
108
|
+
|
|
109
|
+
AskUserQuestion (non-critical, default: top-ranked):
|
|
110
|
+
- "Found these recent stories. Use one as an angle, or write standalone?"
|
|
111
|
+
- options: list 3-5 stories + "Standalone, no news angle"
|
|
112
|
+
|
|
113
|
+
## Step 8: Determine post topic
|
|
114
|
+
|
|
115
|
+
If `--topic` flag passed: use that.
|
|
116
|
+
Else: AskUserQuestion (priority: critical):
|
|
117
|
+
- "What's the topic for today's post?"
|
|
118
|
+
- options:
|
|
119
|
+
- "Use selected news story" (if Step 7 produced one)
|
|
120
|
+
- "Recent product update / behind-the-scenes"
|
|
121
|
+
- "Lesson from this week"
|
|
122
|
+
- "Counter-take on conventional wisdom"
|
|
123
|
+
- "Other (freeform)"
|
|
124
|
+
|
|
125
|
+
## Step 9: Generate 2-3 draft candidates
|
|
126
|
+
|
|
127
|
+
Apply linkedin-base.md style + chosen topic. Generate 2-3 candidates with different hook patterns from references/linkedin-post-patterns.md `## Hook patterns`.
|
|
128
|
+
|
|
129
|
+
Present each to user.
|
|
130
|
+
|
|
131
|
+
## Step 10: Pick or iterate
|
|
132
|
+
|
|
133
|
+
AskUserQuestion (priority: critical):
|
|
134
|
+
- "Which draft?"
|
|
135
|
+
- options: ["A", "B", "C", "Show me 3 more", "Combine these"]
|
|
136
|
+
|
|
137
|
+
Loop until user picks.
|
|
138
|
+
|
|
139
|
+
## Step 11: Mandatory humanize
|
|
140
|
+
|
|
141
|
+
Generate slug via `node ${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs slug "<topic-summary>" --raw` for consistency with the codebase's existing slug convention.
|
|
142
|
+
Generate timestamp via `node ${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs timestamp --raw`.
|
|
143
|
+
|
|
144
|
+
Write the chosen draft to `.taketomarket/CAMPAIGNS/linkedin/drafts/<timestamp>-<slug>.md` (frontmatter: `topic`, `hook_pattern`, `status: draft`).
|
|
145
|
+
|
|
146
|
+
Then invoke `/ttm-humanize <path>` via Skill tool. Re-read the file after humanize completes — it now contains the rewritten version.
|
|
147
|
+
|
|
148
|
+
## Step 12: Save + history append
|
|
149
|
+
|
|
150
|
+
- Print the humanized post text to the user (read from the file you wrote in Step 11).
|
|
151
|
+
- Update frontmatter in `.taketomarket/CAMPAIGNS/linkedin/drafts/<timestamp>-<slug>.md`: change `status: draft` → `status: ready`.
|
|
152
|
+
- Append to `post-history.md`:
|
|
153
|
+
```
|
|
154
|
+
| YYYY-MM-DD | <topic-tag> | <hook-pattern> | <slug> | <link-to-draft> |
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Step 13: Print next steps + cadence suggestion
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
✓ Post ready. Copy from .taketomarket/CAMPAIGNS/linkedin/drafts/<file>.md
|
|
161
|
+
|
|
162
|
+
Want daily cadence? If you have a scheduler skill installed (e.g. /schedule),
|
|
163
|
+
you can set up a recurring run — example syntax:
|
|
164
|
+
|
|
165
|
+
/schedule create "0 9 * * 1-5" "/ttm-linkedin-post"
|
|
166
|
+
|
|
167
|
+
This would run the skill every weekday at 9am. You'd review + post manually.
|
|
168
|
+
No scheduler? Re-run /ttm-linkedin-post when you want the next post.
|
|
169
|
+
|
|
170
|
+
Next: /ttm-next | /ttm-state
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## What if this doesn't fit?
|
|
174
|
+
|
|
175
|
+
Looks like /ttm-linkedin-post can't do that yet.
|
|
176
|
+
|
|
177
|
+
- Want a new skill? /ttm-request-skill
|
|
178
|
+
- Existing skill needs work? /ttm-improve-skill
|