Deep strategic research engine — decomposes questions into parallel research threads, spawns multiple agents, and synthesizes into actionable strategic analysis
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Produce and attach native media (video teaser, GIF, card images) for every social post to maximize reach and interaction. Use whenever you post to X, LinkedIn, Reddit, or prepare HN/IndieHackers handoffs, and whenever a social-publishing step runs. A text-only social post is a draft, not a post.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
실행 점수 미검증
설치 방법 보기설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
Every social post carries a video, GIF, or image. Native media is the largest reach lever the feed algorithms give you. This skill defines the kit of assets, the visual rules that keep a campaign from looking templated, and the browser mechanics for attaching media on each platform.
Set these once. Scripts read them from environment variables, so nothing personal is hardcoded.
| Setting | Env var | Default |
|---|---|---|
| Signature shown bottom-right on cards | BRAND_URL | yourblog.example |
| Output folder for cards | CARD_OUT_DIR | . |
| Screenshot for the runner card | CARD_SCREENSHOT | unset (card skipped) |
| Quote card attribution | QUOTE_ATTRIBUTION | Your Name · your role |
| Pass / fail dot colors | CARD_ACCENT_PASS, CARD_ACCENT_FAIL | 3DD68C, F2555A |
| Banner accent color | BANNER_ACCENT | e13f5e (coral, configurable) |
| Fonts | HEADLINE_FONT, MONO_FONT | macOS Helvetica Neue and Menlo, DejaVu on Linux |
Your handles, avatar and brand colors belong in your own config or prompt, never in this skill.
pip install pillow)browser-harness skill, if you have it)Before posting, produce a kit folder (<scratchpad>/social-kit-<slug>/) with whichever of these the source material supports, in priority order:
| Asset | Spec | Best for |
|---|---|---|
teaser-16x9.mp4 | 30-60s cut of a master video, hook in the first 3s, H.264/AAC, captions burned in (feeds autoplay muted) | X thread root, LinkedIn |
teaser-1x1.mp4 | Same cut, 1080x1080 center-crop or pad | Mobile feeds |
hero-card.png | 1600x900 card with a padded screenshot or lane art | X, LinkedIn, Reddit image |
terminal.gif | Animated terminal replay, 15MB or less (X GIF cap), 2-6 frames or a reveal sequence | X, Reddit |
quote-card.png | 1600x900 dark card with one strong line | Follow-up posts, LinkedIn comment |
Reuse before creating. If your blog pipeline already produces per-post assets (OG gif, screenshots, a deep-dive mp4), a 30-60s ffmpeg cut of an existing master video beats a new render.
One visual language repeated on every asset reads as AI-generated. Rules:
terminal-replica skill), ASCII or OG gif, bare quote card, raw screenshot or recording.Cards follow a dark thin-line art language, inspired by linear.app/now. The renderer is scripts/linearcard.py. The accent colors and signature are configurable.
#0A0B0D, flat. No gradients, no glow, no dot grids.#43464C strokes flowing left to right, dots #9A9DA2 at start points, arrowheads at ends, lines breaking around thin circle nodes. Dashed lanes mean failures. The only accents are tiny green (pass) and red (fail) dots.#303338 border and 20px rounded corners. Never full-bleed. Keep a headline beside them.terminal-replica skill.BRAND_URL="myblog.dev" CARD_OUT_DIR=./kit python3 .claude/skills/social-media-kit/scripts/linearcard.py
The three cards in the script are examples. Edit the copy and numbers for your post.
Pick the treatment by what the post is, not by one default recipe.
| Post is about | Reach for | Why |
|---|---|---|
| A flagship or launch idea | linearcard.py art field, but invent one concrete metaphor object for this post first (a shape that puns the idea) | A bespoke metaphor is more scroll-stopping than the same background every time |
| "Watch it actually run" proof (a real terminal session, an agent run) | cardrender.py screenshot or clip without the padded card frame, raw footage | A card frame reads as marketing polish. Raw footage reads as "this is happening" |
| A tool or stack story with numbers | linearcard.py standard recipe with a mono data-chip row | The data chips carry the story |
| A long essay excerpt or killer quote | quote-card.png, and drop the lane art entirely: pure type on the dark field | Background linework competes with a typographic excerpt |
In any multi-message thread (X thread, LinkedIn post plus comments, Reddit post plus comments), media goes on the first message only, preferably a gif or video. Later messages stay text-only unless an illustration adds information (a chart under discussion, a before/after). Decorating every reply with a card reads as botting and dilutes the root asset.
# pick the strongest 30-60s arc: hook section plus one payoff section
ffmpeg -i master.mp4 -ss <hook_start> -to <hook_end> -c copy a.mp4
ffmpeg -i master.mp4 -ss <payoff_start> -to <payoff_end> -c copy b.mp4
printf "file 'a.mp4'\nfile 'b.mp4'\n" > cut.txt
ffmpeg -f concat -safe 0 -i cut.txt -c:v libx264 -crf 21 -pix_fmt yuv420p teaser-16x9.mp4
# 1:1 variant
ffmpeg -i teaser-16x9.mp4 -vf "crop=ih:ih,scale=1080:1080" -c:a copy teaser-1x1.mp4
If the teaser relies on narration, burn subtitles (-vf subtitles=teaser.srt:force_style='FontSize=22'). Muted autoplay kills uncaptioned voice-over.
scripts/cardrender.py renders 1920x1080 frames: a screenshot floating on a gradient with rounded corners and shadow, an optional animated cursor with click ripples, row highlight pulses, and zoom. Use Seg(...) and render() for motion clips. For a static hero-card.png, render one frame:
from cardrender import Seg
seg = Seg("screenshot.png", 1.0, waypoints=[(0.5, 800, 400)], clicks=[], highlights=[], zoom=None)
seg.frame(0.5).save("hero-card.png")
Edit the gradient colors at the top of make_bg() to match your brand.
Author frames with PIL and a mono font on a dark background, reveal lines progressively, then img.quantize(colors=64) and save(..., save_all=True, duration=[...], loop=0). Keep under 15MB for X: 64 colors and 20 frames or fewer does it.
scripts/terminal_banner.py <out.png> draws a 5:2 (1500x600) terminal-window banner with a prompt line, a big wordmark with a block cursor, status lines and a feature list. Edit the CONFIG block per product. Use it when a raw app screenshot makes a poor cover.
These mechanics assume a CDP-driven Chrome. Coordinates drift, so resolve elements through JS or getBoundingClientRect() each time. Screenshots can be a few percent larger than CSS pixels on retina displays, so never click straight from image coordinates.
The raw DOM.setFileInputFiles call is the cleanest path when an input[type=file] exists (see below). When it does not work, stream the file in:
js("window.__g += '<chunk>'") call. The JS pipe breaks above about 60KB.atob, then Uint8Array, then new File, then DataTransfer.DOM.getDocument(depth=-1, pierce=True), then DOM.querySelector('input[data-testid="fileInput"]'), then DOM.setFileInputFiles(files=[path], nodeId=...). An 8MB 64s mp4 was ready in about 20s. Wait until the attachments strip stops showing upload progress.DragEvent('drop') (with dragenter and dragover first) on [data-testid="tweetTextarea_0"] works. Click the reply box first, wait about 2s, type the text, verify via innerText, then drop.Input.insertText, not document.execCommand('insertText'). The draft editor silently mangles long multi-paragraph strings with execCommand. Focus the textarea via JS, call Input.insertText, then verify innerText (marker count, length range, URL present) before clicking Post.tweetTextarea_0, insert text, verify, click tweetButtonInline by its rect, then find the new reply's status href by matching the first 40 characters of its text.input[type=file] elements belong to the messaging widget (attaching there sends it to a chat draft). Correct flow: patch HTMLInputElement.prototype.click to capture the input instead of opening the picker, click the comment box's "Add a photo" button (capture lands about 1s later), then set input.files = dt.files and dispatch change. Restore the prototype afterwards..ql-editor, [contenteditable=true][role=textbox] with focus() plus Input.insertText. Some composers are closed shadow roots, so click by coordinates and verify by screenshot.lnkd.in shorteners. Verify an edit by curling the shortener, not by matching the raw URL.el.shadowRoot recursively. input[type=file][accept*=image] exists without clicking: assign files and dispatch input and change (bubbles and composed).Cleanest path when a real picker opens: cdp("Page.setInterceptFileChooserDialog", enabled=True), real-click the upload button, drain events, grab Page.fileChooserOpened's backendNodeId, call cdp("DOM.setFileInputFiles", files=[path], backendNodeId=bid), then disable the intercept. No base64 needed.
HN is link-only: the OG image on the blog page does the work, so verify og:image renders before submitting. IndieHackers allows images in the body: include hero-card.png.
Check the group's language and rules on its About page first, and confirm you are a member. Then:
div[role=dialog] with a div[role=textbox] exists before typing. Closing the dialog preserves the draft.Input.insertText.input[type=file]. Do not click Photo/video. Use DOM.querySelector('div[role=dialog] input[type=file]') plus DOM.setFileInputFiles with 2-4 images, and wait for blob <img> previews.div[aria-label="Post"] button. Posting shows a spinner for 15-25s in big groups.textarea[placeholder="Add a title"]. Input.insertText doubles text here, so set it with the native value setter plus an input event.div[contenteditable=true]. Input.insertText works and preserves paragraphs.input[data-testid="fileInput"], then DOM.setFileInputFiles, then Apply in the crop dialog. Generate a banner with scripts/terminal_banner.py instead of using a raw app screenshot..ql-editor).location.href inside the same call. Do whole flows in one script, and prefer JS or API actions over coordinate clicks while you are working in the browser.removed_by_category is moderator. Fetch /r/<sub>/comments/<id>.json and check removed_by_category and is_robot_indexable. A shadow-DOM file-input assign can also report success while attaching nothing, so check media_metadata on the live post JSON. If a subreddit removes your posts, move to a sibling community.hero-card.png아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
Deep strategic research engine — decomposes questions into parallel research threads, spawns multiple agents, and synthesizes into actionable strategic analysis
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Write and publish a post to your own static blog: TL;DR, ASCII art, markdown twin for agents, deploy, and social distribution
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Write and publish a post to your own static blog end to end: content checklist (embedded links, optional TL;DR), per-post ASCII art, an agent-readable markdown twin, deploy, and social distribution. Use when you say "write a blog post", "publish this to my blog", or "push this post to socials".
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Quick capture of raw thoughts with intelligent domain classification and competitive intelligence extraction
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Run one task through the V-model verification loop: CP-2 plan → CP-3 build → CP-3v component verify → CP-4 integration verify (full lane) → CP-5 acceptance. The worker never grades its own homework; evidence rows trace back to AC-n. Opt-in: invoke with /closed-loop or by asking for the closed loop, proper verification, or an evidence trail. Ordinary work does not run this.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Deep-dive 7-day analysis across all data sources for weekly reviews, board prep, and strategic planning
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.