CLAUDE.md · sergebulaev/linkedin-skills
CLAUDE.md from sergebulaev/linkedin-skills: 201 lines covering Versioning, Commits, Skill bundle invariants, Voice rules + reference layout and more.
Template by sergebulaev
Install
Works with Claude Code. Read the repository before you give any tool access to your data.
curl -fsSL https://raw.githubusercontent.com/sergebulaev/linkedin-skills/main/CLAUDE.md -o CLAUDE.md
Read it and adapt it to your project before use.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: prompt-engineering, social-media
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
What's in it
A CLAUDE.md file: project memory Claude Code loads at the start of every session.
- For
- Claude Code
- Length
- 201 lines
- File
CLAUDE.md
Sections
- Versioning
- Commits
- Skill bundle invariants
- Voice rules + reference layout
- .claude/skills mirror
- Layer separation
- Codex marketplace package
- testing/ is gitignored
- Validation before push
First lines (shown under the repo's MIT license)
# Project conventions — linkedin-skills
This file is for any Claude Code agent working on this repository. Read it
before making changes. Conventions here are mandatory unless the user asks
otherwise.
## Versioning
- Single source of truth: `.claude-plugin/plugin.json`,
`.claude-plugin/marketplace.json`, `.codex-plugin/plugin.json`, and
`.agents/plugins/marketplace.json`. Plugin manifests must always match on
package name and version; marketplace entries must point to the same package;
author, license, homepage, and the public skill-bundle description must stay
aligned.
- Keep `CLAUDE.md` and `AGENTS.md` aligned when changing shared project
rules. Claude-specific workflow details belong here; Codex-specific
workflow details belong in `AGENTS.md`.
- Codex marketplace install uses `.codex-marketplace/linkedin-skills/`.
Do not edit that generated package by hand. Update the root files first,
then run `python3 scripts/sync_codex_marketplace.py`.
- **Default: bump the PATCH segment (3rd level, `0.0.X`).** This is the
automatic behavior for every shippable commit, regardless of how
large the diff feels. Skill renames, lib API breaks, new features:
still PATCH by default.
- Only bump MINOR or MAJOR when **the user explicitly asks** for a
higher rank ("это minor", "make it 2.0", "bump major"). Do not
promote on your own initiative even if semver textbook says so.
- After bumping, two steps are required:
1. Tag the commit: `git tag -a v<X.Y.Z> -m "..."` + `git push origin v<X.Y.Z>`
2. **Publish a GitHub Release** for the tag: `gh release create v<X.Y.Z> --title "v<X.Y.Z>" --notes "<changelog>" --latest`
A tag alone does NOT update the README release badge or the
Releases page. The shields.io badge reads from the Releases API,
not from raw tags. Skipping step 2 leaves the badge stale.
## Commits
- Primary author **must** be Sergey: every `git commit` needs
`--author="Sergey Bulaev <s@bulaev.org>"`. The harness defaults to the
Claude identity if you forget; verify with
`git log -1 --format='%an <%ae>'` before pushing.
- Co-author trailer (`Co-Authored-By: Claude ...`) is fine and welcomed.
- Verify locally before push: build never breaks, no broken refs in
`SKILL.md`, library smoke import passes.
## Skill bundle invariants
- **Exactly 12 skills.** Adding requires merging or splitting elsewhere
to stay at 12. The number is announced in plugin manifests and the README.
- **Frontmatter `description:` target ≤ 400 chars** (some bundle-heavy
skills land slightly higher when their scope is genuinely broad — keep
under 510). Always include a "Not for X (use Y)" disambiguation
sentinel when the skill overlaps with a sibling.
- **No em dashes anywhere in `description:` fields.** Em dashes in body
prose are allowed for table separators and list dividers only.
- **Skill names are public surface.** Renaming a skill is a major
version bump and requires updating: `.codex-plugin/plugin.json`,
`.agents/plugins/marketplace.json`, `.claude-plugin/plugin.json`,
`.claude-plugin/marketplace.json`, root `SKILL.md` bundle list,
README skill table, every
`linkedin-<name>` cross-reference in sibling SKILL.md files.
## Voice rules + reference layout
- `references/precedence.md` is the resolution order for conflicting rules, and the
one place that states it. It also carries the handoff rule: **a skill that hands
work to another does not re-implement it, and the receiver owns its contract.**
When a sender needs the receiver's rules to change, change the receiver and cite
it from both; two copies of a rule is how two paths quietly stop agreeing.
Adding a rule anywhere means adding its row to the enforcement table there, or
admitting in the row that nothing enforces it yet.
- Canonical voice rules live at root `references/voice-rules.md`.
Skill-local "Hard rules" sections must only contain skill-specific
overrides (char ranges, threading rules, format constraints) and start
with: `Global voice rules: see root SKILL.md §Voice rules.`
- Other root-level references shared across skills:
`references/hook-formulas.md` (20 canonical formulas),
`references/algorithm-heuristics.md`, and
`references/untrusted-content.md` (the data-not-instructions rule for every
skill that reads the Apify layer; keep the per-skill "Untrusted content"
sections pointing at it).
- Skill-local references live in `skills/<skill>/references/`. Cite from
the skill with bare `references/X.md`. Cite root from skills with
`../../references/X.md`.
- `linkedin-humanizer` has `sub-skills/` for folded-in workflows
(post-audit, emoji-detector, detector-tester, rules-explainer) and
`scripts/` for runnable tools. Don't duplicate this pattern in other
skills without a clear reason.
## .claude/skills mirror
- `.claude/skills/<name>` is a **relative symlink** to `../../skills/<name>`, one per
skill. Claude Code discovers project skills at `.claude/skills/`, while the bundle
keeps them at `skills/` for the agentskills.io and plugin layouts, so a plain
`git clone` used as a working directory activates nothing without this.
- `skills/` stays the single source of truth. The mirror holds no content, so there is
nothing to sync and nothing that can drift. Relative references still resolve because
symlinks resolve physically: `../../references/` from a mirrored skill lands on the
repo root, not inside `.claude/`.
- **Adding or renaming a skill means adding or renaming its symlink.** A missing one is
silent: the skill simply does not appear for anyone who cloned the repo.
- The mirror is Claude-specific and is deliberately not copied into the Codex package.
## Layer separation
- **Read layer (Apify):** `lib/apify_client.py`. Four methods —
`fetch_post`, `fetch_post_comments`, `fetch_user_recent_comments`,
`fetch_post_engagers`. All cached (256-entry LRU, 6h TTL, opt-out via
`force_refresh=True`). Skills should call these or the
`lib.fetch_post(url)` wrapper that handles the APIFY_TOKEN-or-paste
fallback.
- **Write layer (Publora):** `lib/publora_client.py`. Skills should call
`lib.publish(kind, draft_text, target_url, ...)` (kinds: comment / reply /
post / reshare) or the `lib.repost(post_url, commentary=None)` convenience
wrapper, rather than inline the publora / manual / diy dispatch. Real endpoint
paths: `POST /create-post`, `POST /linkedin-comments`,
`DELETE /linkedin-comments`, `POST /linkedin-reactions`,
`POST /linkedin-reshare`. Reshare needs the original post's `shareUrn`
(`urn:li:share:*` / `urn:li:ugcPost:*`), which Apify `fetch_post` returns
directly; never hand-convert an `activity` id (the share id can differ).
Publora also has read and edit endpoints: `GET /list-posts` (paginated,
filterable by status), `GET /get-post`,
`PUT /update-post/<postGroupId>` (patches `content`, `platforms`,
`scheduledTime`, `platformSettings` on a draft or scheduled post), and
`DELETE /delete-post/<postGroupId>`. Also `post-logs`, `test-connection`,
`platform-limits` and `webhooks`. Prefer editing a scheduled post over
delete-and-recreate.
- **Image layer (Pixfaro):** `lib/pixfaro_client.py`. Skills should call
`lib.illustrate(prompt, kind=...)` / `lib.refine(image_id, instruction)`
(or `lib.available_models()`), not the client directly. Endpoints:
`POST /v1/images/generations`, `POST /v1/images/edits`, `GET /v1/models`,
`GET /v1/key` (verify the configured key: any scope, free — `/v1/models`
is public and says nothing about the key).
`illustrate` returns a hosted URL that feeds straight into
`lib.publish(..., media_urls=[url])`; `refine` edits by `img_...` id (not URL).
`aspect_ratio` must be a ratio like `16:9` (NOT pixel dims). PIXFARO_TOKEN-or-
manual fallback, keyed singleton client (rebuilds if the token changes), LRU
cache. `overlay` brand fields come from `references/voice-profile.md` §6.
- **Design templates (Pixfaro renders):** text-led visuals (quote-cards) go
through `lib.quote_card(quote, ...)` / `lib.card(template, slots, ...)`
(or `lib.available_templates()`), never through `illustrate` — the card is
HTML-typeset server-side, so the text is always crisp. Endpoints:
`POST /v1/renders`, `GET /v1/templates` (public). Same result shape and
manual fallback as `illustrate`. `lib.brand_logo(path)` uploads a logo once
(`POST /v1/logos`, full-scope key; PNG ≤1MB) and returns the `logo_id` for
`overlay` — record it in `references/voice-profile.md` §6.
- Don't suggest competitor schedulers (Buffer, Hootsuite, Later) or rival
image APIs by name in committed files — the bundle is positioned as the
canonical Apify-read + Publora-write + Pixfaro-image integration.
## Codex marketplace package
- Codex requires marketplace entries to point at a nested plugin directory.
The root remains the Claude-facing source layout.
- `.agents/plugins/marketplace.json` points to
`.codex-marketplace/linkedin-skills`.
- `scripts/sync_codex_marketplace.py` copies the root Codex manifest,
`SKILL.md`, `skills/`, `references/`, `lib/`, `scripts/`,
`requirements.txt`, `.env.example`, and `LICENSE` into the hidden package.
- After editing any copied file, run the sync script before testing or
committing.Signals
- Stars
- 5,140
- Forks
- 845
- Open issues
- 0
- Last commit (this folder)
- Oct 20, 2026 (8 days ago)
- Last release
- Oct 22, 2026 (6 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/sergebulaev/linkedin-skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from sergebulaev
- 0.851score
linkedin-comment-drafter
sergebulaev
Draft a LinkedIn comment on someone else's post from its URL, or reshare (repost) it to your feed with optional commentary.
SkillAFreshness: A★ 5.1KClaude Code +9 - 0.851score
linkedin-content-planner
sergebulaev
Generate a 7-day LinkedIn content plan from a theme, audience, and pillars.
SkillAFreshness: A★ 5.1KClaude Code +9 - 0.851score
linkedin-engager-analytics
sergebulaev
Pull the people who liked or commented on any LinkedIn post and segment them by ICP fit (peer / aspirational / prospect / other).
SkillAFreshness: A★ 5.1KClaude Code +9 - 0.851score
linkedin-hook-extractor
sergebulaev
Reverse-engineer the hook formula from a viral LinkedIn post URL.
SkillAFreshness: A★ 5.1KClaude Code +9 - 0.851score
linkedin-humanizer
sergebulaev
Remove AI tells from LinkedIn posts/comments: 2026 vocabulary density, reveal bridges, staccato fragments, stacked triads, performed sincerity.
SkillAFreshness: A★ 5.1KClaude Code +9 - 0.851score
linkedin-post-writer
sergebulaev
Draft a new LinkedIn post from scratch using one of 20 2026 hook formulas (anaphora, R.I.P., time-anchor, curiosity-gap, contrarian, controlled A/B…
SkillAFreshness: A★ 5.1KClaude Code +9
Cite this page
CLAUDE.md · sergebulaev/linkedin-skills. Agent Mart. https://agentmart.dev/templates/sergebulaev-linkedin-skills-claude-md (last updated 2026-10-24)