Imported from khasky/awesome-agent-skills (
skills/awesome-content-repurpose/SKILL.md). Install upstream withnpx skills add khasky/awesome-agent-skills --skill awesome-content-repurpose. Copyright stays with the author (MIT).
Content Repurpose
One text in, one post per platform out, each written to that platform's register rather than trimmed to its cap. Then the posts are filed, and publishing them is one more step the user chooses.
The rule that makes this skill different from writing posts from scratch: the source is the boundary. A repurposed post may sharpen, cut and reframe, but it may not add a claim, a number or an implication the source does not carry, and it may not invert the source's point by compressing it. The text arrives settled — where it came from and whether it may be published are the user's business, decided before this runs.
This skill owns the repurposing craft and orchestrates the rest. Two of its own reference files carry what every run is checked against, and both are read before a line is written:
references/authored-style.md— the register, as countable patterns: the seven opening shapes that work, the five that are banned, the rule that the chosen persona is present in the opening of every post rather than in half of them, the three product-as-subject shapes that are banned outright, the literal read a hook has to survive, the headline shapes that fail on sight, the ban on crowning a single favourite, the closing that hands the thread back instead of restating the post, the specifics first person has to be paid for with, the ASCII-only rule for diagrams, and the paragraph-shape rules that keep a post from turning into a stack of one-line fragments.references/platform-specs.md— the output contract, the hard character caps, and the depth band each platform's version is written to.references/fidelity.md— the source-notes format with its IDs and positions, the claims ledger, the checks made in a fresh context, the shape of a finding, the drift check that proves a wording fix changed nothing, and the rewrite budget.references/run-memory.md— what persists between runs: the defaults, the rules learned from the user's corrections, the sources already run, the backlog of unused ideas, and what the user's best posts are allowed to teach.
Four files persist across runs in the runtime's scratch root, beside the per-run repurpose/<slug>/ folders and never in the invocation directory: repurpose/defaults.md (the interview answers from the last run), repurpose/platform-cache.md (the last live platform check, dated), repurpose/rules.md (the rules learned from the user's corrections) and repurpose/sources.md (the sources already run), all described in references/run-memory.md. All four are the agent's own temporary files; when the runtime wipes them the run simply asks in full again.
It reuses the rest by reference rather than by restating:
references/platforms.md(ships withawesome-content-campaign) — the canonical slug table: target detail per platform, media requirements, and which genre file governs each.references/genre-micro-post.md,references/genre-long-article.md,references/genre-community-post.md(same skill) — the register each genre demands.awesome-content-graphics— the whole image stage when a post needs a picture and none exists: the look inputs, the offline HTML/CSS renders, the headline question and the pick gate. Nothing about making graphics is reimplemented here, including the chart craft it takes fromdataviz.awesome-humanize-en,awesome-document-style,awesome-slop-audit— loaded only under--deep-audit. The part of their catalogs that applies to a feed post is written out as the Phase 4 checklist, so an ordinary run reads nine lines instead of three skills.awesome-content-voice— the author's voice, when a profile exists.awesome-content-publisher— everything about publishing: bridge, login, ledger, pacing, read-back.awesome-translate-ru-en— whenever the output language differs from the source, in either direction.
Invocation
/awesome-content-repurpose <url | file | pasted text> [--platforms <slug,slug>] [--publish] [--recheck] [--deep-audit]
No source given → ask for one before anything else. --publish is a preference recorded in Phase 2, not a bypass of the publisher's own confirmation gate. --recheck forces the live platform check in Phase 3 without asking; --deep-audit loads the external humanity catalogs in Phase 4 instead of the inline checklist.
Phase 1 — Read the source, write the source notes
Get the text onto disk first. Working state never lands in the invocation directory — it goes to the agent's own scratch or session directory for this run (whatever the runtime provides: a session scratchpad, a temp path under the agent's home such as ~/.claude/, or TMPDIR), in a repurpose/<slug>/ folder there. The user asked for posts, not for a folder appearing in whatever repository they happened to be standing in. The same holds for every file a tool writes on the way — a screenshot, a generated helper script, a dump a browser tool takes a filename for: those paths resolve against the invocation directory unless they are absolute, so they are given absolute paths inside the working folder from the first call rather than moved afterwards. Only the final deliverable moves to a place the user names (Phase 6), and the run states both paths.
- URL — a plain fetch first; a live browser when the page is a JS app that returns an empty shell, so rendered content is not silently missed. Driving a browser means driving one of the user's, so it is not a silent step: when the session exposes more than one browser bridge, ask which one before the first navigation and remember the answer for the run; either way, name the browser that was used and warn that it is busy while the read runs. A page that turns out to need a logged-in session is no longer a public read — run the full target gate in
references/browser-interaction.md(ships withawesome-content-publisher) before touching it. Save the extracted text tosource/inside the working folder. - File — read it directly; a folder gets an inventory first, then the prose.
- Pasted text — save it to
source/on arrival, like everything else. Long source text stays out of the conversation context. - Transcript, recording or talk — spoken text is extracted clean: fillers, false starts and repeated words removed, speaker labels kept only where who said it matters. A quotation from speech keeps every content word and marks a cut with an ellipsis. Whatever only worked in the room goes into the notes' Not transferable to text section with its position: a demo, a reference to something on screen, an audience moment. No post points at a thing its reader cannot see.
Then fingerprint the source and look it up, with its URL, in repurpose/sources.md. A match is the first thing the Phase 2 screen shows (references/run-memory.md).
Then write source-notes.md beside it, which every later phase is checked against. It opens with the source's paragraph count, and every fact-bearing line carries an ID and its position in the source, in the exact format references/fidelity.md fixes, because the gate reads it:
- The point — one sentence: what this text argues or reports. Compression that contradicts this line is a defect, not an interpretation.
- Supporting claims — one line each, in the source's own terms, each with its ID and position.
- Numbers — verbatim, with the conditions the source attaches to them. A number without its condition is not repurposable.
- Scope and hedges — who or what each finding covers, preview or beta status, the source's own
mayandin our tests, sample sizes. Compression turns a narrow finding into a general one more often than it does anything else, and this is what a sentence is narrowed back to. - Provenance — what this text actually is and where it came from: which release, which changelog, whose announcement, what date. Two sentences at most, and every post needs one of them, because a reader who does not know what is being discussed cannot use the rest. Record two things apart: the primary origin (the vendor, the paper, the model cards), which the posts may name, and the intermediary the user pasted (a list, a thread, a channel post, a translated article), which the notes describe and the posts never do. Its language, its item count and its layout stay in this file.
- Quotable lines — 3 to 5 verbatim excerpts worth keeping intact, with their location.
- Named things — people, products, versions, places the source names, spelled the way it spells them.
- What surprised the reader — the counterintuitive part, which a source usually buries in the middle rather than leading with.
- The honest exception — the one limit a reader would hit first. Every post's caveat comes from here; where the source names none, that is recorded, and the caveat is taken from verification or narrowed from Scope and hedges, never invented to fill the slot.
- Candidate ideas — three, each a mechanism or a consequence resting on named IDs. The interview picks one; the other two become the run's backlog.
- What the source does NOT say — the tempting adjacent claims a shorter version would drift into. This section exists because compression invents.
A historical source stays historical. Where the text is a retrospective, the posts say so in their own words, placing the author's knowledge at the time it was written and stating plainly that this is not a current-state audit, and an old product rule is never rewritten into a present-tense fact.
The link a post may carry is not automatically the link the source arrived on. A conversation with an assistant is a private artifact, so a share URL on an assistant's own domain never reaches a post: not in the body, not in frontmatter links, not as a "full thread" closer. The hosts this covers, and any other assistant's own domain that appears in a source: chatgpt.com, chat.openai.com, claude.ai, gemini.google.com, aistudio.google.com, notebooklm.google.com, deepseek.com, chat.deepseek.com, grok.com, x.ai, copilot.microsoft.com, chat.mistral.ai, chat.qwen.ai, kimi.com, poe.com, perplexity.ai, hf.co/chat, you.com, phind.com, meta.ai, character.ai. Three reasons, each sufficient: for most readers the URL does not open at all, a research transcript is the opposite of the author's own knowledge, and publishing a session is a decision the user never made. The URL stays inside source-notes.md as provenance and goes nowhere else.
So the run looks for the link the post deserves, and the search is bounded: one query for what the text is actually about (the release note, the changelog entry, the documentation page, the repository, the vendor announcement, the original article), the best public result opened once, and it counts only if it carries the claim the post will make. Nothing public in that one pass → the post ships with no link and an empty links, which is honest. A second query, a guessed URL, or a fall back to the chat share is not.
The point, the three candidate ideas, the notes and the proposed link are shown on the interview screen in Phase 2 rather than in a gate of their own, so the user answers everything in one round. Every gate in this skill goes through the structured-question UI: a gate written as a closing sentence the user must answer in prose reads as narration and gets passed over.
Phase 2 — Interview
One round, structured-question UI when available, custom answer always allowed. Where the UI caps a screen at four questions, a first run cannot literally be one screen, and "one round" then means the fewest full screens the answers fit on, planned before the first is sent: every screen carries four questions, the target detail each selected platform needs rides on the same screens as the settings, and no screen is spent on something a default already answers. Two round-trips are what a first run costs; a first run that took eight spent five of them on questions that could have shared a screen with the platform list, and one on a browser it did not need to open yet. Never open a browser mid-interview for a target the user can answer from memory: that question keeps its default-plus-escape-hatch shape, and only show me my options sends the run to the account, once the rest of the interview is settled.
The round opens with the Phase 1 notes: the point in one line, the provenance, and the link the run proposes (or that none exists), with the options correct · the point is wrong, here is the right one · use this link instead · no link at all · stop. A second question on the same screen offers the three candidate ideas, each in one line with what it rests on, and a custom idea the user types; a custom idea is framing only, and where the source does not support it, the source wins. Where the notes carry too little for the long platforms, that is on the same screen: how many distinct claims the source supports, which of the selected platforms cannot be filled without padding, and the options write those short · drop them · write them anyway. When repurpose/sources.md shows this source was run before, that comes first of all, with the idea the earlier run used, whether its posts went out, and its unused backlog.
Then the answers. When repurpose/defaults.md exists from an earlier run, the interview is one screen: the last run's answers summarised (platforms, every target detail, voice, language, shape, emoji, hashtags, closing questions, what happens after the files exist including any spread over days, and how many rules repurpose/rules.md carries, with an option to see them) and three options — same as last time (recommended) · change something · start from scratch. "Change something" re-asks only the items the user names; "start from scratch" runs the full interview below. With no defaults file the full interview runs once, and its answers are written to repurpose/defaults.md at the end of the round so the next run opens on the one screen. The file records answers, never source material: no notes, no text, no links from the source.
The full interview, on a first run or a reset:
-
Platforms — the default is every row of the canonical table in
awesome-content-campaign'sreferences/platforms.md, the single source both this skill and the publisher read;references/platform-specs.mdcarries the numbers for each of them and adds none of its own. The run asks whether the user wants all of them before it asks which ones. The realistic answer is "all", so the first question is a single one — write for the whole set, or trim it — with "all of them" the recommended option and the count stated asAll <n>, with n counted off that table in this run rather than carried in this sentence, where it would go stale the first time a platform is added. Only when the user chooses to trim does the checkbox pass run, split across several questions because the question UI caps options per question, and phrased as removing rather than adding (Untick anything you do not want). This ordering exists because the UI has no pre-checked state to give: a bare checkbox list makes the common answer the most laborious one, a tick per platform to say "everything", which is the shape that gets abandoned halfway.No slug on that table is held back for a special request: a platform the user can be published to is a platform the interview offers, because a set the run quietly narrows is a set the user cannot choose from. What varies is the target detail each one needs, collected below.
Never offer a shortlist, a bundle, a "recommended set", or a subset inferred from the source, the language, or what looks like a fit — narrowing the list is a decision the user did not delegate, and a platform missing from the question is a platform they cannot choose. Keep one open option for a platform the table does not carry.
Then collect the target detail each selected platform requires, under the rule below. Two annotations, when the data exists: mark platforms where
publish-state/performance.mdshows the user's own median engagement, and mark platforms where the publisher's ledger already carries this source — repurposing into a feed that already has this piece is usually a mistake worth surfacing. When the performance file holds three or more posts for a platform, Phase 4 also takes their countable traits, never their wording (references/run-memory.md).A target question offers what the user actually has, and it is one question per platform. The Target column names a kind of thing (an instance, a community, a board, a squad), and the failure to avoid is filling that in with plausible names the run made up — three Mastodon instances the user has never heard of, three Lemmy servers when their account lives on one, a menu of Pinterest boards chosen from general knowledge. A user cannot answer "which of these three" when nothing in the question says why those three or which is theirs, and the honest reading of such a menu is that the run does not know either.
So, in this order:
- The default plus an escape hatch, and a third option that opens the account. The question offers the value from
defaults.mdor the table's canonical default,another one, I will type it, andshow me my options. Only that third answer sends the run to the browser: then the real list is one read away and it is read — the communities their own instance carries, the squads they have joined, the boards on their profile, the client they are signed into — throughawesome-content-publisher'sreferences/browser-interaction.md, as a read and never a write, and the options come back ranked by fit to this post's topic with the number that makes each choosable. Reading the account on every run, unasked, is a browser session and a target gate spent on a question the user usually answers from memory in two words. - Never a menu of guesses.
mastodon.socialandanother serveris a real choice;mastodon.social · fosstodon.org · hachyderm.iois a quiz. - Never re-ask what is already settled. When the user has said
lemmy.world, the instance is decided and the only open question is which community there. Re-offeringlemmy.mlandprogramming.devreads as the run having forgotten, and it invites an answer that contradicts the account they actually have. - One platform per question. A question headed
lemmy target and daily-dev target?forces one answer to cover two unrelated decisions, so neither can be answered properly. Give each its own, and say in the question what the detail is for. - A hazard is not a question. Where a platform has a dangerous path and a safe one, take the safe one by default and say so in one line; do not turn the danger into a gate the user clears on every run.
substackis the worked example: publishing an Article from the personal profile sends no email at all, so the run takes that path and never opens with "publishing also sends email that cannot be recalled, which publication?" — a question that is unanswerable for an account with no publication, and that reappears every run because nothing about it can ever be settled. Ask only when the user wants the irreversible path.
- The default plus an escape hatch, and a third option that opens the account. The question offers the value from
-
Voice — first person, the author reporting their own experience with the thing (default) · first person plural · neutral third person, for a source the author has no standing to have used · a voice profile from
awesome-content-voice(path;voice/*.mdis where to look) · a style guide fromawesome-style-mimic. Whichever answer comes back binds every post in the run and the opening of every post, short platforms included; it is not a preference the writing stage gets to average out. -
Output language — same as the source (default) · another language. A different language means the posts are written in it by someone who thinks in it, never carried across word by word; Phase 4 holds the rules, and for the Russian and English pair they come from
awesome-translate-ru-en, applied in whichever direction this run needs. -
Length and shape per platform — native to the platform (default) · deliberately short · thread or multi-part where the platform supports it and the content is genuinely sequential. Under the long shape
threadscan also take a text attachment of up to 10,000 characters beside the post, asked as its own yes or no; it is neither indexed nor federated, so the post still carries the point. -
Emoji, on a screen of its own:
1-5 emoji(recommended) ·no emoji· a custom answer where the user types the count or the format. The first option is the placement rules of Phase 4, which put one or two on a short post, an update or a status and up to five across a long read; the second turns them off everywhere, and the human-signal rule then falls back on a question or an aside. -
Hashtags, on a screen of their own:
best practice (x-y)(recommended), with x and y filled from the hashtag table as the lowest and highest norm among the selected platforms ·no hashtags· a custom answer where the user types the count or the format. Best practice applies each platform's own norm, and a platform whose composer refuses tags carries none whatever the answer;no hashtagsis passed to the gate as--no-hashtags. -
Closing questions — rooms only (recommended):
reddit,lemmy,devto,hashnodeanddaily-devhand the thread back and every other post ends on its content · also onx,bluesky,threadsandlinkedin, for a user who will answer the replies. The answer binds the closing section ofreferences/authored-style.md. -
What happens after the files exist — publish now · publish at a time the user names · files only. Whatever the answer, the files are written first. With a named time, a follow-up offers to spread the platforms over a number of days the user names, so someone who follows the author in three places does not meet the same post three times in an hour; each file then carries its own
scheduledtime.
One image, and it goes everywhere the platform takes one. Ask for media once, with the cheap answers first: I will supply one (path) · no image, drop the media-required platforms · generate a set with awesome-content-graphics · a carousel for linkedin and instagram (below). Generation is the explicit third choice, never the default, because it opens a whole rendering stage and a second gate. On that yes, ask that skill's look question in the same round, with its three labels verbatim and nothing else: Random (based on the post topic, tone, purpose) · Reference (URL, text description, or another image) · the free-text entry for custom info. Never a mood, never same look as last run (the look is not a default repurpose/defaults.md carries), never the look bundled with the set size into one option; the reference itself is collected in a follow-up. Asked later, it interrupts the run for nothing.
No image supplied means a whole set and a second gate, never one graphic chosen by this skill. The post's title travels with the facts: it is the first line of the headline pool, and every generated headline is measured against it, so the picture and the post tell one story. The set size is the user's answer there (10, 50, 100 or a number they type), and the variant rules, the spread of the set, the spread across the source's different facts, the gallery and the pick gate all belong to awesome-content-graphics and are not restated here; this phase hands it the facts from source-notes.md, that file's "What the source does NOT say" section as the boundary, repurpose/<slug>/media/ as the output folder, the look inputs, the target ratio from Phase 3, and the output language the interview settled, so the words on the graphic match the posts and the user is not asked the same question twice. Then it takes back the chosen render, its alt text and the graphics.md receipt. That skill not installed → say so, and offer the same two options: the user supplies an image, or the media-required platforms are dropped. What belongs to this phase is the sequencing: the interview's media answer only settles whether a graphic is generated. Which one ships is a separate question, and it is never asked before the set is in front of the user: the gallery is opened on their machine and the message that asks carries its absolute path and the folder's, so a number in the question points at a picture they have already seen. A pick question sent while the gallery is still a path nobody opened is the defect this sequencing exists to prevent — the run has to wait for the open to happen, not mention the file afterwards. No post file declares an attachment until they have answered it. A user who supplied their own image never sees this gate. Whatever image the run ends up with — supplied or generated — is then attached to every selected platform whose Media column is optional as well as every platform where it is required, not only to the ones that cannot post without it. A run that renders a graphic for instagram and ships text-only posts everywhere else has done the work and thrown most of it away; the same picture earns its keep on linkedin, x, mastodon, tumblr, patreon and the rest, and on the article platforms it becomes the cover image.
Three exceptions, and only these: a platform whose Media column says media is not supported (hackernews) gets nothing; a platform whose requirement is video cannot be satisfied by a still, so it is dropped rather than given the graphic; and a post whose own text argues against the picture — the user says so, or the image contradicts what that version says — carries no attachment, with the reason recorded in campaign.md. Every attachment carries alt text describing what the image shows, the same text on every platform.
A carousel is the opt-in fourth answer and the one format that is a sequence rather than a picture: five to eight slides, a hook slide stating the post's point, one sourced fact per slide, and a closing slide naming the source. The slide plan goes into campaign.md first, each fact slide pointing at the note ID it shows, so the fidelity pass can check the slides like any other text. awesome-content-graphics renders them from that plan as one set; tell it the renders are a sequence, so the pick is an ordered choice of the slides that ship rather than one winner. Assemble the ordered slides into the single PDF linkedin takes as a document post — one page per slide, at the slide's own size, any transparency flattened onto white (frontmatter document); instagram takes the same slides as its attachments list, in order; every other platform gets the first slide as its single image. Every slide carries its own alt text. Engagement data favours these formats on both platforms, and it is correlation, which is why a carousel is offered and never chosen for the user.
Phase 3 — Platform check
The structural facts are already in the tables and do not expire: the hard caps are the floor in references/platform-specs.md, the hashtag norms and media requirements are in awesome-content-campaign's references/platforms.md, editor types do not move. Live research may only lower a cap, never raise it; a number that cannot be verified stays at the table value, and a number that looks higher is treated as unverified. So this phase is off by default and the user turns it on.
Read repurpose/platform-cache.md and ask one structured question: The last live format check for the selected platforms was YYYY-MM-DD (or: has never run). Check all selected platforms again? — no, use the last references (recommended) · yes, check all of them · check only these. --recheck answers yes without asking. On "no", the whole phase is skipped and the manifest records the cache date that was relied on.
Two things run regardless of the answer, because they are about the user's specific target rather than the platform, and they change without notice: the rules of the community actually being posted to — the subreddit, the Lemmy community, the Facebook group, the daily.dev squad, a Hashnode or Medium publication's submission rules — and a community that forbids link-drops or self-promotion is reported with the option to pick another target; and anything the user's account tier changes where the cache does not already record the tier.
Which hosts answer a plain fetch is settled knowledge, and the run does not rediscover it by retrying. Reddit refuses the fetcher on www.reddit.com and old.reddit.com alike, about/rules.json included, so a subreddit's rules are read only through the user's browser (asked once, with the bridge named) or confirmed by the user in words; a run that could do neither records the rules as not read and says so in campaign.md. X returns 403 to the fetcher, so a thread's text is taken from search snippets and marked as such. GitHub pages and raw files answer the fetch tool but not curl from this shell. Lemmy's instance API answers everything: /api/v3/search?q=<topic>&type_=Communities&listing_type=Local ranks communities with subscriber and post counts, and /api/v3/community?name=<name> returns the sidebar and its rules. A Lemmy community the user names is checked against those counts before it is accepted, because a room with a handful of subscribers and no posts is a room nobody will read, and the user is offered the live rooms on the same instance instead.
When the check does run, it verifies the volatile facts only (a cap that may have moved, a media format, a hashtag norm the table marks verify live), writes each entry to repurpose/platform-cache.md with its platform, values, source URL and checked-on date, and reports what changed against the tables. A cache entry records the page that was actually opened — a value recalled from memory, taken off a search-result snippet, or written from a URL that did not load is not a source: record that it could not be reached and treat the table value as still binding.
Phase 4 — Write
Load four things before writing: references/authored-style.md, references/platform-specs.md, the genre file for each selected platform, and repurpose/rules.md when it exists. A rule there outranks a default of the style file where the two disagree, because it is the user's own decision about their posts (references/run-memory.md). The register belongs to the genre, the shapes and the numbers belong to the two reference files, and this phase adds the repurposing craft on top.
Each platform version is composed to its own band from the start. The band is in platform-specs.md, and it is a writing instruction rather than a validation threshold: a buymeacoffee unit is drafted as a two-to-five-thousand-character mini-blog, a peerlist unit as four hundred characters, and neither is derived by cutting the other. Writing one long version and trimming it per platform at publication time is the single most expensive mistake this skill makes, because the cut always falls on the tail: the pricing, the closing line, the link. When a version comes out over its cap, it is rewritten to the band, never amputated.
The band is a shape and not a quota, and the material decides how much of it is used. Before a long version is drafted, count what this post actually has: the distinct claims, numbers and quotations from source-notes.md it will carry. One of them per 250 characters of prose is the honest density (platform-specs.md), so eight usable claims do not become a five-thousand-character essay, and a post that runs out of material finishes there, under its band, with the reason in campaign.md. Nothing is stretched to reach a floor: no paragraph restating the one above it, no section whose content is its own title, no caveat in three places, no mechanism explained twice at two depths, no closing that summarises the body. Where the source cannot fill the long-form platforms at all, the user hears it on the Phase 2 screen and chooses between shorter posts and fewer platforms; the run never quietly writes filler instead of asking.
The opener comes from the catalog in authored-style.md, and the run varies the shape across platforms rather than reaching for the same one every time. Three openers are drafted for the unit in three different shapes, each put through the five checks in that file, and the best survivor leads; the other two go into campaign.md and the report, so the user can swap the hook without a rewrite. On a platform with a fold (platform-specs.md), the opener's job is done above it. No post opens on an abstract category doing something a category cannot do, and none opens on a vague event with a vague time attached.
Paragraphs are paragraphs. Never three one-line paragraphs in a row, and in anything over 1500 characters the one-line share stays well under half. A stack of short lines is the loudest structural tell these posts carry and it survives every other pass, because each individual line reads fine.
One post, adapted per platform — not one post per platform. The run picks ONE idea out of the source and writes it once; every selected platform then gets that same post adjusted for its mechanics: trimmed to the verified cap, hashtags in that platform's norm, the title-and-body split where the platform has one, the hook above the fold where the feed cuts. A reader following the author on three of them should recognise the same post three times, not discover three unrelated ones. Producing a different extract per platform is the failure this rule exists to prevent: it multiplies the work, dilutes the message, and leaves nothing that can be pointed at as "the post".
The user asks for more than one idea → that is more than one run, or an explicit list of units decided together up front and stated in the manifest. It is never a side effect of having several platforms selected.
Choosing the idea: compression is selection, not summarizing. A 2,000-word article becomes one post about its sharpest single point: not a synopsis, not a table of contents, not a numbered set of takeaways unless the source genuinely is a set of takeaways. The reader who never opens the original should still get something whole. The choice is made on the Phase 2 screen from the three candidates in the notes; the two not taken are the backlog, never a second idea in this run.
What makes an idea worth the post. Prefer the mechanism, the consequence, the thing that changes how someone works, and skip the inventory. A list of version numbers, a table of names, a feature roll-call carries no insight even though it is factual and easy to extract: it tells a reader what exists, never what it means for them. A sentence that explains how something behaves and what that behaviour costs the reader is a post; a sentence of version floors per operating system is a footnote to one. Where a number genuinely matters, it belongs inside the mechanism it constrains, not as the subject.
Verify the claims the idea actually uses, and only those. Verification runs here, after the idea is chosen, because the ladder is expensive and a source carries far more claims than one post will ship. For each claim, number or command the unit will carry that is current, version-sensitive, priced, benchmarked, install-related, support-matrix-related or counted (stars, downloads, rank): the official site, the official repository, the official documentation, the paper or model card, the vendor's own announcement, in that order, stopping at the first that settles it. Reputable secondary sources only when none of those carries it. A claim the unit does not use is not verified, however tempting.
Where the source is stronger than the evidence, keep the interesting idea and correct the claim: narrow an absolute to what the evidence supports and name the caveat that bites, and where the source credits a capability to the wrong layer, give it to the layer that actually does the work. A claim that cannot be verified either goes with the hedge the evidence supports or does not go.
Numbers that came from the project rather than from an independent test say so: the project reports, the paper reports, the README shows. A project benchmark presented as a universal guarantee is a fabrication with a citation attached. Fast-moving counts are date-stamped in the notes and written evergreen in the post (200k+, when it landed), because a star count is stale within the week. An install command is verified or it is not published: never invented, and the official quick-start path is preferred over a source build unless the source is specifically about building from source.
Every post carries its provenance. One clause, early, saying what is being talked about and where it came from: the release, the changelog, the announcement. Without it a post about a mechanism reads as an opinion out of nowhere, and the reader cannot tell whether it is news, a manual, or a thought.
Provenance names the thing's own origin: the vendor, the release, the paper, the model card. It never names the text the user pasted in. A compilation, a channel post, a thread, a translated article or a list someone else assembled is the run's input, not the post's subject, and the post does not describe it: not its language, not how many items it held, not how it was sorted, not who put it together. Those are facts about a document the reader will never see. The post stands on its own. Claims are stated as what they are, with their conditions, and attributed to the primary source where attribution matters. One light mention of how the author ran into the topic is allowed when it earns its place, worded fresh like every other sentence, and then the intermediary leaves the post: it never becomes a character that says, files, suggests or closes on anything. Where the pasted text is the only support for a claim, the condition carries the honesty, not the intermediary's name.
Numbers follow the same logic, and references/authored-style.md carries the rule: a number that is the payoff is written in digits, because digits are what an eye in a feed catches, and a number that only counts the items in the source's container is not written at all. Every count of a technical thing is digits as well, however incidental it looks (3 agents, never three agents), and what stays spelled out is the language that counts nothing technical: idioms, an ordinal inside a phrase, and a deliberately vague quantity.
Write it as the author's own experience, because that is what a feed post is. Someone saw the thing, tried it, and is reporting back: ran into it, spent an evening on it, changed how they set something up, would not bother with half of it. First person, an opinion, a recommendation, a thing that annoyed them. A post that reads as a neutral summary of someone else's announcement has no reason to exist on a personal feed.
That applies to every post in the run and to the top of every post, not to a majority of them. The persona the interview settled is a property of the batch: under first-person, every post has the author in it, and the author arrives in the first two paragraphs rather than in paragraph eight after the mechanism has been explained by nobody. Phase 5's script measures exactly that, because it is the rule this skill broke most often: a run whose short platforms open with the product as the subject has published vendor copy under a personal name, and the shortest posts are where it happens, since that is where the author looks like the first thing worth cutting. The author is the last thing worth cutting. Cut a fact instead.
The product is never the grammatical subject of the post's own claim, and neither is a feature list. No capability roll-call, no support matrix, no stack of bare bullets standing in for sentences. references/authored-style.md carries the three banned shapes and the swap test that catches them: if the product's name could be replaced by a competitor's and the post would still be true, nobody wrote it.
Then read the hook literally before anything else is checked. It is read once, at speed, by someone who knows nothing, so a first line that is only defensible three paragraphs later is a defect however true it is. The failure this skill has actually shipped is a hook that praises a property which, read cold, is a defect: the point underneath is real and the reader leaves with its opposite. Where a hook rests on a word that reads negative out of context (slow, smaller, less accurate, more expensive), either the reason travels in the same sentence or the word goes.
Then the headline, which is read alone and gets its own rules in references/authored-style.md: it names the subject and states the point in one clause, and it never explains why something is good, announces what we just got, runs a product roll-call, bolts a qualifier on after the point has landed, or lets a product name read as a quantity. A title that needs a second sentence is a title plus the first line of the post.
Nothing is crowned. A declared favourite, a best or a go-to is a ranking a reader cannot check and cannot disagree with, so the description of what the thing does replaces it, and membership among several things the author keeps is the ceiling where the enthusiasm genuinely belongs in the sentence.
The first person is paid for with specifics. A post that carries an opinion and no number, command, version, name or quotation is a paraphrase with a pronoun in front of it, and the reader can tell. Every first-person post lands at least a couple of checkable details taken from the source and the Phase 4 verification: the number with its condition, the exact command, the flag, the limit that bites, the line the documentation actually uses. Depth is the same material, read further: what the mechanism is, what it costs, where it breaks, what was surprising when the author looked. The boundary does not move, though, and it is the one from the fidelity rule above: specifics come from the source or from verification, never from invention.
The ending does one of two jobs. On a surface that is a room (reddit, lemmy, and usually devto, hashnode and daily-dev) it hands the thread back with a question the author actually wants answered, specific to the post, never a call to action wearing a question mark. Everywhere else it lands the argument the facts made. What it never does is restate the post in general terms: a small-thing-big-effect pair of sentences, a maturity-stage label or one hedge set against another is derivable by anyone who read to that point, and it is the closing this skill produces most often when it has run out of things to say.
One diagram is allowed where the shape is the point, and it is ASCII: hyphens, pipes, plus signs, angle brackets, slashes, equals signs and spaces, never box-drawing glyphs or Unicode arrows, because those render as tofu or misalign on somebody else's font and a broken diagram is worse than none.
The frame is invented on purpose; the substance never is. Allowed: having read it, tried it, set it up this way, preferred one option, given up on another, expected something else. Forbidden: invented outcomes and measurements, a build time cut by a number, a bug caught, a team convinced, a client saved, any result the source does not carry. The Phase 5 fidelity pass reads first-person framing as framing and any specific result inside it as a fabrication.
No calendar dates, in any language. An audit stamp on the author's own reading, an as-of qualifier with a month, a dated opening line: each is the loudest machine tell a post can carry, because nobody stamps their own writing with an audit date. Recency is a relative word: yesterday, last week, the other day, recently, a few days ago, soon. The single date allowed to survive is one that is the subject itself, a deadline or an event day the reader has to show up for. A date attached to the author's act of reading, checking or verifying is never written, in the body, in a graphic, in alt text, or in a title. The frontmatter scheduled field is machinery, not prose, and is the one place a date belongs.
Cut the specification. Version floors, per-OS build numbers, tier matrices and requirement tables are what release notes are for, and a person writing about an update says roughly what changed and how recently, in one relative phrase rather than a number. Where a constraint genuinely decides whether the reader can use the thing at all, it gets one plain clause and never a matrix; a long-form platform may carry one line more, still as prose. Whatever number does survive keeps the condition source-notes.md recorded.
A public repository's price, licence and signup are never written. It is free to read, it asks for no account and its licence is permissive: the reader assumed all three before they clicked, and the clause otherwise lands in front of the link on every post in the run. The one exception is a post whose news is one of those three, and there the headline says so (references/authored-style.md, "Access boilerplate").
How technical each version gets is its own axis, set by the technical-depth table in platform-specs.md: concept, command, snippet or code. The topic can raise a version one level and never lowers it below the platform's own; the level decides what kind of material goes in, and the band decides how much of it.
Energy is set by the genre, and it is read before writing rather than after. A micro-post opens on the hook and carries its emoji where that platform's natives use them; a community post opens on the problem and stays plain; a long article earns its first line. Where the genre supports it a post is allowed to sound like someone who found something good: an opener that promises a payoff, a sharp line, the question the reader already has. Still banned everywhere: emoji as bullets, hype closers, and a loud label such as "PRO TIP" stamped on a post that carries no tip.
No em dash in a post. Zero, not "sparingly". The — character (and its long siblings – and ―) is the single most recognisable machine fingerprint in a feed, and hand-set typography is not what a person types into a composer anyway. Every one of them becomes a full stop, a comma, a colon, or a pair of parentheses, and the sentence is usually better for it. This covers the body, the title, hashtag lines, alt text, and any words on a graphic. Two exceptions and no others: a verbatim quotation that carries one (prefer quoting a different line), and text inside a code block or a command. A hyphen inside a compound word, a flag or a slug is not a dash and stays.
Emoji are part of how these platforms are written, so use them, and place them the way a person does. A writer does not decorate a post evenly. They punctuate it: the emoji lands right after the phrase that earned a reaction, and the choice reports what the reaction was. 🤯 after the number nobody expected, 🧐 next to the caveat, 🤑 on the cost, 😅 on the part that went wrong. Put it at the end of that sentence or open the post with it, and the reader feels a person reacting rather than a template being filled.
The budget is 0 to 5 for a whole text, scaled to its length, and the exact count matters less than the spacing. A micro-post carries none or one. A medium feed post carries one or two. A long article carries three to five across the whole piece, and it is allowed to go several paragraphs with none. Two emoji inside the same paragraph, or a pair a line apart, reads as decoration however good each one is on its own; keep real distance between them.
On a piece with headings, pick ONE surface and stay on it. Either the emoji live in the prose, three to five across the article, or one sits at the end of every heading down the whole outline. Never both surfaces in one piece, and never a subset of the headings: two decorated out of six is the pattern a reader clocks immediately, because it looks like whoever wrote it stopped caring after the second section. If the last heading has no emoji that honestly fits, that is the signal to use the prose surface instead and leave every heading bare. The article's own title sits outside the choice and may carry one either way. The check is countable: headings with an emoji must equal 0 or all of them.
Restraint still applies: never as bullet markers, never one per line, never a row of three, never in place of a word the sentence needs, and never on a platform whose natives do not use them (the genre file and the Phase 3 research decide that). The interview's emoji answer overrides this default in both directions, and a custom count the user typed replaces the budget above.
Write it in the English people speak. The register is a competent person talking, so the vocabulary stays where speech is. Literary and rare words are the tell that something reached for a synonym instead of a word: duller, says it outright, thus, hence, myriad, plethora, albeit, bespoke, salient, wherein, heretofore, deliberately. Write more boring, says it plainly, so, many, on purpose. The test is spoken, not written: would you say this word out loud to a colleague? No → replace it. Technical precision is untouched by this — worktree, merge conflict and file lock are the words for those things and stay.
Every post has a person in it. A run that produces four flat declarative sentences and stops has written a machine report, whatever the facts are. Somewhere in each post there is a reaction: the emoji where the surprise lands, the question the reader already has, a short fragment, an aside, an exclamation on the part that went wrong. One human signal per post is the floor, and it is checked in Phase 5. The exceptions are narrow and named: a platform whose natives write flat (hackernews), and an interview answer that turned emoji off — and even then a question or a wry half-line still belongs there, because flat register is not the same as nobody being home.
Name what a tool is the first time the post mentions it. A paragraph that compares products by bare name only works for a reader already inside the ecosystem and tells everyone else nothing. The first mention carries a short identifying clause: what kind of thing it is, who makes it where that matters, and, where it decides whether the reader can try it, how it is switched on (the flag, the setting, the plan). This applies to every platform and every length; on the shortest posts it is the reason to name one tool instead of three.
One hashtag set for the whole run, trimmed per platform, never re-invented. The tags come from the unit's subject once, then each platform gets the share its norm allows: the fuller block where hashtags are the discovery mechanism (mastodon, instagram, tumblr's tag field), one or two on x and never more (more measurably costs reach there), none where they read as noise (hackernews, community rooms, reddit). Trimming drops whole tags off the end. A tag is never cut mid-word to fit a cap, and no post ends on half a hashtag. A platform whose post file has an empty hashtags list because nobody thought about it is a defect, not a decision.
A tag of more than one word is written in CamelCase wherever the tag lives in the body, because a screen reader reads a lower-case compound as one unpronounceable word. The platforms that lower-case every tag themselves (devto, daily-dev) and the tag fields are exempt.
The link belongs to the sentence that points at it. Where a post refers the reader to the thing, the announcement or the documentation, the URL follows on that same line after a colon or a space, never on a line of its own with a blank line above it. A URL floating between two paragraphs is the shape of a post assembled out of blocks, and a reader scanning a feed sees a naked link rather than a reason to click. The exception is a platform whose composer wants the URL alone to build its preview card, and that comes from the Phase 3 research rather than from habit. Anywhere else, a blank line between prose and its own link is a defect: the closing sentence carries the URL inline.
And a URL never goes in parentheses. A link shoved into the middle of a clause reads as a footnote marker and breaks the sentence in half. The sentence makes its point, then hands over the link at its end.
The post lands without its link. Delete the URL and the sentence pointing at it, and the point is still there; a closing whose only words point at the link without naming what is behind it fails that test.
On a platform whose editor does not linkify text, the link is applied, not typed. A pasted URL in a rich editor publishes as dead characters — medium, substack, tumblr and telegraph all need the words selected and the editor's own link control used on them. The post file still carries the plain URL; making it a link is the composer step, and Phase 5 checks the published page rather than the file.
No trademark word carrying its ordinary meaning. A common noun that is also a large company's name stops reading as the noun the moment it lands in a feed: slack for spare capacity, stripe, square, notion, discord, prime, oracle, meta, swift, zoom, teams, windows. The reader sees the company, the sentence bends around it, and on a post about software the misread is instant. Write the ordinary synonym instead — head start, margin, band, idea, disagreement — and keep the word only where the post genuinely is about that company. This covers the body, the title, alt text, hashtags and any words on a graphic.
Distinctions that collapse under compression, and must not. Each pair below reads as a shorter version of the same claim and is a different claim: can run against runs fast; context capacity against reliable recall; a VRAM requirement against total system memory; official support against community compatibility; open-weight against free to use; model size against active parameters per token; local-first against fully offline; no cloud storage against no server involvement; an agent skill against a native model capability. Technical credibility outranks keeping a viral headline intact: where the headline needs one of these collapsed to work, the headline changes.
The shape a post about a tool takes, adapted to the platform's depth rather than forced whole into every one: the hook, what the thing is, why it matters, the concrete headline result, how it works, the caveat that matters most, who it is for, and the link or quick start. A short platform carries three of those, a long article carries all of them. The recurring framing that earns its place: the headline sounds like magic, the architecture is more interesting because it is not magic at all, then the actual mechanism.
Every post carries the caveat. Not a hedge and not a disclaimer, the one limit a reader would hit first: what it costs, what it does not do, where it breaks. A post with a result and no caveat is marketing copy, and it is the shape a reader has learned to discount.
Rules that hold across every platform:
- Numbers keep the conditions
source-notes.mdrecorded. A benchmark without its machine, a percentage without its base, a claim without its scope is not a shorter version — it is a different claim. - Quoted lines stay verbatim, inside quotation marks. A paraphrase presented as a quotation is a fabrication.
- The source's own terms and spellings survive; renaming its concepts to something punchier is how a repurposed post stops being about the source.
- Nothing from the "What the source does NOT say" section reaches a post.
- Threads only where the content is sequential, and each part must survive being read alone — the platform will show it alone. Before a thread is drafted its plan goes into
campaign.md: one line per part with what that part has to do and the note IDs it rests on, so the fidelity pass can check it part by part. - Tags with their own field in the composer never appear in the body. The article platforms (
devto,hashnode,hackernoon,medium) andtumblrtake tags in an input of their own, so the post file carries them as atagsfrontmatter list and the prose ends on prose. A line of bare words under the last paragraph (ai machine-learning video news) is a tag dump that publishes as literal text, and it is the tell that a feed post's hashtag habit was applied to a platform that does not work that way. Inline#hashtagsstay in the body only where the platform's own natives write them there. - No invented idiom. A phrase shaped like a saying that is not one is machine phrasing: it reaches for the rhythm of a colloquialism without any colloquialism behind it. Write what happened in ordinary words, the way it would be said out loud to a colleague. When a phrase cannot be found in speech, it does not belong in a feed post.
- Voice per the profile when there is one, including the habits its Personal tics section protects; those are exempt from the Phase 5 slop pass.
- The link is the one Phase 1 settled on, or none at all. An assistant's own domain never appears, and no post closes on a research transcript.
The author's own angle
Before the unit is cleaned and long before it fans out, the run does the one thing that separates a first-person post from a summary with a pronoun: it works on the material. A unit that restates the project's own numbers, however accurately, has an author in name only, and the reader can tell because nothing in it needed the author to exist. The step is written into the unit as its own paragraph or two, and references/authored-style.md ("The author's own angle") carries the full rule.
What the step produces, at least one of and usually two:
- Arithmetic the source did not do, from the source's own numbers: a total against an active count, a size on disk against a peak in memory, a rate against a price. The sum is shown in the sentence, and it lands in
source-notes.mdas a[D]line with the IDs it was computed from, so the gate grounds the result (references/fidelity.md). - A reading of what a published metric counts and leaves out, stated as the author's reading with the source's wording beside it.
- A comparison against a public fact verified in this phase, never a recalled one.
- The question the source leaves open, and the author's reasoning about it, marked as reasoning.
- A check made inside the material at hand: a line in the repository, a footnote on a card, two of the project's pages disagreeing.
The boundary does not move: a measurement the author did not make, a benchmark not run, an outcome on a machine the author does not own is a fabrication, and the fidelity pass reads it as one. The frame is the other half of the same step, and it is welcome: a sentence of the author's own history with the subject, what they have bought, kept, replaced or given up on, carrying no number and no claim about the thing. It is often the best opener a post has, and it is never evidence.
Two consequences for the wording. The author's effort lands on the project, the repository, the release or the model, never on a document: an evening spent with the README, a table saved from the model card, a verdict about what a file does or does not settle, all review a file the reader did not come for, and the gate counts both the effort verb wit
*Truncated - read the full file at https://github.com/khasky/awesome-agent-skills/blob/9fe5b6baff522307aef466c70bb67ff5362627bd/skills/awesome-content-repurpose/SKILL.
