Skip to content
Agentmart
Submit a tool

AGENTS.md · sergebulaev/linkedin-skills

AGENTS.md from sergebulaev/linkedin-skills: 169 lines covering Versioning, Commits, Skill bundle invariants, Voice rules + reference layout and more.

Template by sergebulaev

IndexedMIT★ 5,140
Write a review

Install

Works with Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code. Read the repository before you give any tool access to your data.

curl -fsSL https://raw.githubusercontent.com/sergebulaev/linkedin-skills/main/AGENTS.md -o AGENTS.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.

We use your email only for this newsletter. Privacy

About

The AGENTS.md file that sergebulaev/linkedin-skills (5,138 stars) keeps for coding agents. It has 169 lines in 9 sections: Versioning; Commits; Skill bundle invariants; Voice rules + reference layout; .claude/skills mirror; Layer separation; Codex marketplace package; testing/ is gitignored; Validation before push. Use it as a model for your own project's instructions.

Use cases: prompt-engineering, social-media

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

What's in it

An AGENTS.md file: instructions coding agents (Codex, Cursor, Copilot, Gemini CLI and others) read before working in a repo.

For
Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code
Length
169 lines
File
AGENTS.md

Sections

  1. Versioning
  2. Commits
  3. Skill bundle invariants
  4. Voice rules + reference layout
  5. .claude/skills mirror
  6. Layer separation
  7. Codex marketplace package
  8. testing/ is gitignored
  9. Validation before push

First lines (shown under the repo's MIT license)

# Project conventions - linkedin-skills

This file is for any Codex agent working on this repository. Read it
before making changes. Conventions here are mandatory unless the user asks
otherwise.

## Versioning

- Single source of truth: `.codex-plugin/plugin.json`,
  `.agents/plugins/marketplace.json`, `.claude-plugin/plugin.json`, and
  `.claude-plugin/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 `AGENTS.md` and `CLAUDE.md` aligned when changing shared project
  rules. Codex-specific workflow details belong here; Claude-specific
  workflow details belong in `CLAUDE.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 ("this is 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>"`. Verify with
  `git log -1 --format='%an <%ae>'` before pushing.
- Co-author trailers are fine when appropriate.
- 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: plugin manifests, marketplace entries,
  root `SKILL.md` bundle list, README skill table, every `linkedin-<name>`
  cross-reference in sibling SKILL.md files.

## Voice rules + reference layout

- 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.
- Don't suggest competitor schedulers (Buffer, Hootsuite, Later) by
  name in committed files - the bundle is positioned as the canonical
  Apify-read + Publora-write 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.

## testing/ is gitignored

- `testing/` is the local scratch directory: API keys, sample API
  responses, validation reports, integration scripts.
- Never write secrets above `testing/` (the rest of the repo is public).
- The `.gitignore` rule for `testing/` is load-bearing; do not change.

## Validation before push

Run from repo root:

```bash
python3 -c "from lib import publish, fetch_post, ApifyClient, PubloraClient; print('OK')"
python3 scripts/sync_codex_marketplace.py
wc -l SKILL.md skills/*/SKILL.md
ls skills/ | wc -l        # must equal 12
python3 scripts/check_frontmatter.py   # parses; a dir count does not prove a skill loads
python3 scripts/check_no_secrets.py    # .gitignore does not stop a rename of a tracked file
python3 scripts/check_config.py --offline   # credential wiring; --offline skips the live API calls
python3 scripts/check_actor_inputs.py  # Apify ignores unknown input keys; this catches a renamed one
python3 -m unittest discover -s tests    # contracts: docs vs code, response shapes, client behaviour
python3 scripts/selftest.py              # the whole picture: install, accounts, tests, what works now

Behaviour, not plumbing: `python3 evals/run_evals.py` runs the agent against
fixtures and grades what comes back (one model call per case, `--list` to see
them). Graders must have a right answer - the parentComment for a nested reply,
whether a scrub kept the user's figures. A grader that needs taste will drift,
and a wrong grader fails the skill for the grader's mistake.

Signals

Stars
5,140
Forks
845
Open issues
0
Last commit (this folder)
Sep 15, 2026 (1 month ago)
Last release
Oct 22, 2026 (8 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from sergebulaev

Cite this page

AGENTS.md · sergebulaev/linkedin-skills. Agent Mart. https://agentmart.dev/templates/sergebulaev-linkedin-skills-agents-md (last updated 2026-10-24)