Skip to content

Commit d4c9fcd

Browse files
bloveclaude
andcommitted
chore(marketing): 0.1.0 launch campaign drafts
Adds the campaign for the 0.1.0 announcement, following the grade-a-trust structure: a plan doc, per-adapter JSON drafts for X and Dev.to, and a manual-channels file for Hacker News, r/Angular, Discord, LinkedIn, and newsletter pitches. Every draft is review_status: awaiting-brian. Merging this posts nothing. The plan assigns a different angle per channel rather than repeating one paragraph five times. Hacker News leads with the versioning confession — 55 breaking changes shipped under a patch counter — because a version-bump submission reads as promotion and gets flagged, while a self-critical semver post is something that community argues about on its own. Reddit and Dev.to lead with the "where it stops" list. X, Discord and LinkedIn carry the complete-and-free story, always pairing "free" with what the paid tiers actually sell. Two findings from reading the existing assets, both recorded in the plan: - marketing/assets/src/brand.ts:14 defaults the card eyebrow to 'Agent UI for Angular · MIT', which is retired positioning. The website's public-copy contract does not scan marketing/, so nothing catches it. The plan requires passing an explicit eyebrow and shows the call. - The X adapter's metrics() is a stub until the API tier is upgraded, so impressions are not collectable. Success is defined on referral sessions and the try-without-a-backend page instead. No competitor comparisons, unlike grade-a-trust, which named other frameworks only because it was reporting a public leaderboard. Verification: both adapter drafts pass the real validateDraft() — all eight X parts inside 280 code points, Dev.to tags matching ^[a-z0-9]+$. Every UTM link resolves against the live post, which was confirmed at HTTP 200 with its table, emphasis and index listing rendering correctly before these drafts were committed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 1a5a1b5 commit d4c9fcd

4 files changed

Lines changed: 347 additions & 0 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"_meta": {
3+
"campaign": "threadplane-0-1-0",
4+
"channel_note": "Day 2. canonicalUrl points at the blog so the blog keeps SEO credit. Deliberately NOT a copy of the blog post: this leads with the 'where it stops' section, which is the most Dev.to-native angle. Attach og-card (1200x630) as cover at post time. DRY_RUN=1 smoke first.",
5+
"review_status": "awaiting-brian"
6+
},
7+
"draft": {
8+
"channel": "devto",
9+
"article": {
10+
"title": "The most useful part of our release notes is the list of things we refuse to do for you",
11+
"tags": [
12+
"angular",
13+
"opensource",
14+
"ai",
15+
"webdev"
16+
],
17+
"canonicalUrl": "https://threadplane.ai/blog/threadplane-0-1-0",
18+
"description": "Threadplane 0.1.0 is out \u2014 an MIT Angular framework for agent UIs on LangGraph and AG-UI. The section worth reading first is the one that says where the library stops."
19+
},
20+
"text": "Threadplane 0.1.0 shipped this week. It is an Angular framework for building agent UIs on LangGraph and AG-UI, it is MIT, and every capability is in the free tier because there is no other tier.\n\nI want to write about one section of the release notes instead of the whole list, because it is the section I would read first if someone handed me this library.\n\n## The list that says where it stops\n\nHere is what Threadplane does **not** do for you, and will not quietly start doing in a patch release:\n\n- **The agent endpoint sits behind your proxy.** The browser should not talk to your graph server directly.\n- **API keys never reach the bundle.** There is no config option that makes this safe, so there is no config option.\n- **Thread IDs are server-generated.** Never mint one client-side.\n- **CORS is yours to configure.**\n- **The interrupt panel is yours to compose.** `<chat>` does not render it. The primitives ship; the review experience is a product decision.\n- **The resume payload is yours to choose.** Only you know what \"approved\" means in your domain.\n- **Tracing and evaluation are yours.** Runs get traced by tools built for tracing, not by a UI library.\n\nA feature list is a sales document unless it also says where it stops. Every row above is a place where taking the work off your hands would mean taking a decision off your hands too \u2014 and the ones I would most regret automating are the security ones.\n\nThat interrupt-panel row is the one I had to correct. An earlier draft of our homepage claimed destructive actions were held for approval automatically. They are not. `<chat>` gives you the primitives and you compose the panel. Checking that against our own docs turned one confident tick into two honest lines.\n\n## What it does do\n\nThe pitch is narrow on purpose: the last mile. Everything between \"my agent streams tokens\" and \"my team can put this in front of a customer.\"\n\n- `<chat>` plus 15 documented components \u2014 message list, input, tool-call cards, reasoning, trace, subagent cards, sidebar, popup, debug\n- Streaming markdown over a 26-node registry, sanitized, with per-instance overrides\n- Durable threads: persistence, checkpoints, durable execution, time travel\n- Interrupts and human approvals\n- Client tools that run in the browser and hand control back to the graph\n- Generative UI via json-render and A2UI v0.9, rendering only components you registered\n- Subagents as their own cards with their own transcripts\n- The five Deep Agents capabilities \u2014 planning, filesystem, subagents, memory, skills\n- `AgentError` classifying every failure as `connection`, `auth`, `server`, `interrupted`, or `aborted`, each with a `retryable` flag\n- A test path that runs with no model and no API key\n\n## The runtime is not a one-way door\n\n`@threadplane/langgraph` and `@threadplane/ag-ui` both produce the same `Agent` interface \u2014 six signals, four methods, one event stream. Components written against `<chat>` do not know which backend they are talking to. When the backend changes, your providers change and your components do not.\n\nI measured that rather than asserting it. Across three capability demos built twice, the same six of nine files differ every time, and four of those six are not application code.\n\nThe AG-UI side is protocol-first, so it got tested against runtimes that have nothing to do with LangGraph: AWS Strands, Microsoft Agent Framework, and Mastra. Three runtimes, two languages, no adapter changes for messages, tool calls, or state. Each has a standalone example and a committed transcript of its wire traffic.\n\n## About the version number\n\nThrough `v0.0.66` this project bumped only the patch digit. Fifty-five commits of accumulated breaking changes shipped under a counter that said nothing had broken.\n\nThat is not semver, and by the end the published packages were contradicting the documentation. So 0.1.0 is not a feature release. It is the release where the version number starts telling the truth. Six packages move as one fixed group, because an adapter and the surface it feeds are not independently upgradable in practice.\n\n## The free part\n\nThere is no open-core split. No capability is held back, no seat count, no activation, no runtime license check, no account.\n\nThere are paid offerings and I want to be precise about what they sell: review time, a private channel, and a response commitment. They sell my attention. They do not sell code you cannot otherwise have.\n\nThe moment a capability moves behind a paywall, every architectural decision in the library starts getting made by the pricing page, and you can feel that in the code long before you see it on the invoice.\n\nTry it without a backend first \u2014 it runs a fake agent in the browser, so you can see the UI before you stand up a server:\n\n```bash\nnpm install @threadplane/chat @threadplane/langgraph @langchain/core @langchain/langgraph-sdk marked\n```\n\nFull write-up with the complete capability table: https://threadplane.ai/blog/threadplane-0-1-0\n\nIf you try it, I would rather hear where it broke than that it was nice."
21+
}
22+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# Threadplane 0.1.0 — launch plan
2+
3+
> Campaign: `threadplane-0-1-0`. Anchor: <https://threadplane.ai/blog/threadplane-0-1-0>
4+
> Voice: `docs/gtm/voice.md`. Claims: `docs/gtm/messaging.md`. Audience: `docs/gtm/icp.md`.
5+
> Copy lives in the sibling files: `-x.json`, `-devto.json`, `-manual-channels.md`.
6+
> Status: **awaiting-brian**. Nothing posts until each draft is reviewed.
7+
8+
## The problem with this announcement
9+
10+
"We released version 0.1.0" is not a story. Nobody outside the repository cares that a
11+
number moved, and on Hacker News a version-bump post is downvoted as promotion before
12+
anyone reads it.
13+
14+
The campaign works only if each channel gets the angle that channel actually rewards.
15+
There are three real stories in this release, and the plan assigns them deliberately
16+
rather than repeating the same paragraph five times.
17+
18+
| Angle | What it says | Best channel |
19+
|---|---|---|
20+
| **The version number was lying** | 55 commits of breaking changes shipped under a patch counter. 0.1.0 is the correction. | Hacker News |
21+
| **The last mile is complete, and free** | Every capability, MIT, no paywalled tier, no account. | X, Discord, LinkedIn |
22+
| **Where it stops** | The proxy, the keys, the interrupt panel, tracing — still yours, on purpose. | r/Angular, Dev.to |
23+
24+
The first angle is the one I would lead with anywhere technical. It is self-critical,
25+
it is specific, and versioning is a subject engineers argue about for free. A confession
26+
travels where an announcement does not.
27+
28+
## Sequence
29+
30+
Front-load the channels we control, let HN and Reddit follow once the post has survived
31+
contact with readers. Same shape as `grade-a-trust`, which worked.
32+
33+
| Day | Channel | Draft | Posting |
34+
|---|---|---|---|
35+
| 0 | X thread | `-x.json` | Adapter (`getAdapter('x')`) |
36+
| 0 | Discord `#announcements` | `-manual-channels.md` | Manual |
37+
| 2 | Dev.to | `-devto.json` | Adapter (`getAdapter('devto')`) |
38+
| 4 | Hacker News | `-manual-channels.md` | Manual — Brian submits, stays in comments |
39+
| 4 | r/Angular | `-manual-channels.md` | Manual |
40+
| 5 | LinkedIn | `-manual-channels.md` | Manual (no adapter) |
41+
| 6–7 | Newsletter pitches | `-manual-channels.md` | Manual email |
42+
43+
Two days between Dev.to and HN is deliberate. If a technical claim in the post is wrong,
44+
Dev.to comments will find it before the HN thread does, and correcting it there costs
45+
nothing.
46+
47+
**Do not post HN and Reddit the same hour.** If HN takes off, that is where Brian needs
48+
to be, and a Reddit thread going unanswered in parallel reads worse than posting it a
49+
day later.
50+
51+
## Hacker News specifics
52+
53+
- Submit as a **link to the blog post**, not a Show HN. There is no interactive demo at
54+
that URL, and Show HN sets an expectation this post does not meet.
55+
- Title is neutral and technical. No version number in the title — it reads as a release
56+
announcement and gets flagged.
57+
- Brian posts the first comment himself immediately after submitting, and discloses that
58+
he is the author in the first sentence.
59+
- Best window: Tuesday–Thursday, 08:00–10:00 ET.
60+
- If it does not catch in 90 minutes, leave it. Do not repost, do not ask for upvotes.
61+
62+
## r/Angular specifics
63+
64+
Read the subreddit rules before posting; self-promotion policy changes. The draft leads
65+
with the practical question an Angular developer actually has and treats the release as
66+
the answer, not the headline. Brian engages in comments; a drive-by post is worse than
67+
no post.
68+
69+
## Assets
70+
71+
Render the social card before Day 0:
72+
73+
```bash
74+
npx tsx --tsconfig marketing/assets/tsconfig.lib.json marketing/assets/scripts/preview.ts
75+
```
76+
77+
**Pass `eyebrow` explicitly.** `marketing/assets/src/brand.ts:14` defaults to
78+
`'Agent UI for Angular · MIT'`, which is retired positioning — the current line is
79+
"The open-source thread-plane for agents." The website's copy contract does not scan
80+
`marketing/`, so nothing catches this for you. Use:
81+
82+
```ts
83+
await renderCard({
84+
template: 'x-card',
85+
eyebrow: 'Threadplane 0.1.0 · MIT',
86+
title: 'The coffee in the hangar is free',
87+
subtitle: 'Chat, durable threads, approvals, and generative UI for Angular. No paid tier.',
88+
});
89+
```
90+
91+
Card alt text (required by the X adapter, 1–1000 chars):
92+
93+
> Threadplane 0.1.0 announcement card: "The coffee in the hangar is free" over the
94+
> subtitle "Chat, durable threads, approvals, and generative UI for Angular. No paid tier."
95+
96+
Two cards needed: `x-card` (1200×675) for the X thread, `og-card` (1200×630) for Dev.to.
97+
98+
## Guardrails
99+
100+
- **No competitor comparisons.** The `grade-a-trust` campaign named other frameworks
101+
because it was reporting a public leaderboard. This campaign has no such excuse, and
102+
a "vs them" frame invites a fight we do not need. The story is what we ship.
103+
- **No absolute telemetry claims.** `apps/website/src/lib/public-copy-contract.ts` bars
104+
"off by default", "we never collect", and similar. Say what is true and checkable:
105+
no cloud service, no account, no activation.
106+
- **Contractions are fine here.** `voice.md` measures the no-contraction rule from the
107+
blog corpus. The shipped `grade-a-trust` social drafts use contractions freely, and
108+
they read correctly. Blog register and social register are not the same register.
109+
- **Name the weak spot.** Every draft in this campaign admits something — the version
110+
history, the gaps, or the adoption number. The `grade-a-trust` campaign did this and
111+
it was the most-quoted part. Do not let review sand it off.
112+
- **"Free" needs its qualifier in the same breath.** Free software, paid support. Say
113+
both, or the first one reads as bait.
114+
115+
## Measurement
116+
117+
Every link carries `utm_campaign=threadplane-0-1-0`, with `utm_source` per channel and
118+
`utm_medium` of `social` (X, LinkedIn), `community` (HN, Reddit, Discord), `referral`
119+
(newsletters), or `blog` (Dev.to).
120+
121+
Baseline before Day 0 so the delta is readable:
122+
123+
```bash
124+
npm run posthog:report
125+
```
126+
127+
Check at Day 7. What would make this a success:
128+
129+
- Referral sessions to `/blog/threadplane-0-1-0` from at least three distinct sources.
130+
- Any movement on `/docs/chat/getting-started/try-without-a-backend`. That page is the
131+
one that converts curiosity into an install, and it is linked from the post's table.
132+
- GitHub stars. Adoption was the honest weak signal in June and it still is.
133+
134+
Do not treat X impressions as a result. `metrics()` on the X adapter is a stub until the
135+
API tier is upgraded, so that number is not even collectable right now.
136+
137+
## Pre-flight checklist
138+
139+
- [ ] Blog post live at the anchor URL and rendering correctly
140+
- [ ] Both cards rendered with an explicit `eyebrow`, eyeballed for layout
141+
- [ ] `DRY_RUN=1` smoke for X and Dev.to adapters
142+
- [ ] Every draft reviewed by Brian (`review_status` flipped off `awaiting-brian`)
143+
- [ ] PostHog baseline captured
144+
- [ ] r/Angular self-promotion rules re-read
145+
- [ ] Brian available for the two hours after the HN submission

0 commit comments

Comments
 (0)