bl-draft
One idea in, one post out, in the voice of the person whose name goes on it.
Before you write anything
- Read
~/.claude/bylinekit/voice.md. If it is missing, stop and run/bl-setup. Do not invent a voice - a post in the wrong voice is worse than no post, because the user has to read it to discover it is wrong. - Read
~/.claude/bylinekit/ledger.md. Everything factual in the draft comes from here. - Read
openers.jsonin this folder. Sixteen patterns, each with the job it does, the shape, a filled example, when to use it and how it fails.
Get the idea to a fact
Most ideas arrive as a topic ("something about hiring"). A topic is not a post. Push until you have at least one of:
- a number the user owns
- a thing that actually happened, with a when
- an opinion the user holds that some of their audience does not
If none of those exist, say so and ask one question that would produce one. Do not write around the gap.
Pick three openers, not one
Choose three patterns from openers.json that genuinely fit the material, and
write line one for each. Show all three before writing the body:
A. [Cost] $18,000 is what skipping a written scope cost me last March.
B. [Interval] Writing a contract used to take me a full evening. Now it's 20 minutes.
C. [Refusal] I don't start work without a signed scope. Ever.
Say which you would pick and why, in one line. Then wait. The user picks.
Then write the body
- Line two pays off line one. Never setup, never a restatement.
- One idea. If a second idea is fighting for space, it is the next post.
- Short paragraphs. One to three lines. The feed is read on a phone.
- Specifics over adjectives. Every number comes from the ledger.
- Close by landing, not by begging. A question is fine if only this user could ask it. "Thoughts?" is not a question.
Length: 120-200 words is the working range. Go longer only when the story genuinely needs it, and never pad to reach a number.
Before showing the user, run the tools
This is not optional and it is not eyeballed:
cd ../bl-scrub
python3 scrub.py draft.txt -o clean.txt --explain
python3 score.py draft.txt clean.txt
If the score comes back below 65, fix what the weakest gauge points at and run it again. Show the user the cleaned draft, not the raw one. Mention the score in one line, not as a table.
Then act on whatever scrub.py flagged - those are the structures it refuses to
auto-fix because reshaping a sentence needs judgement. That judgement is yours.
Deliver it like this
- The chosen opener, and one line on why it was chosen.
- The full draft in a copy-ready block.
- The score, in one line.
- Any
{{placeholder}}still in the draft, called out explicitly. - Three hashtags at most, or none.
What never happens
- Nothing is posted. This skill writes; the user posts. There is no official API for posting to a personal profile, and automating the site through a browser breaks LinkedIn's User Agreement and gets accounts restricted. The copy-ready block is the deliverable, by design.
- Nothing is invented. No metric, client, outcome or credential that is not
in the ledger. A needed-but-missing fact comes back as
{{your number}}and gets flagged out loud. - No engagement bait. No "Agree?", no "Thoughts?", no tagging strangers.