CommunityWriting & Editinggithub.com

atokim4/freelance-proposal-lint

Write or check a freelance proposal, bid or first client reply on any marketplace (Upwork, Fiverr briefs and custom offers, Freelancer.com, PeoplePerHour, Contra, Guru) so it sounds like a person, keeps contact on the platform and claims only what the freelancer can back. Runs a Node linter for AI phrases, em dashes, placeholders, emails and phone numbers, word count, the closing question and claims missing from the user's facts file. Use when the user asks for a bid or proposal, asks to shorten or check one, or asks "does this sound like AI".

What is freelance-proposal-lint?

freelance-proposal-lint is a Claude Code agent skill that write or check a freelance proposal, bid or first client reply on any marketplace (Upwork, Fiverr briefs and custom offers, Freelancer.com, PeoplePerHour, Contra, Guru) so it sounds like a person, keeps contact on the platform and claims only what the freelancer can back. Runs a Node linter for AI phrases, em dashes, placeholders, emails and phone numbers, word count, the closing question and claims missing from the user's facts file. Use when the user asks for a bid or proposal, asks to shorten or check one, or asks "does this sound like AI".

Works with✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/atokim4/cover-letter-lint/tree/HEAD/skills/freelance-proposal-lint

Installed? Explore more Writing & Editing skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

Freelance proposal lint

Goal: a short bid that the client reads to the end and answers, on whatever marketplace the job is on, with every claim backed by the user's own facts file.

The linter is scripts/lint-cover.mjs in this skill's folder (Node 20+, no dependencies, no network). It is the same file as in the cover-letter-lint skill of this repo, shipped here so this skill installs on its own. Call it by its full path, node ${CLAUDE_SKILL_DIR}/scripts/lint-cover.mjs in Claude Code, or the skill's folder in other agents, e.g. node .claude/skills/freelance-proposal-lint/scripts/lint-cover.mjs.

1. Facts first

Look for facts.md, me/facts.md or a .cover-lint.json with a "facts" path. Claims come only from there. None found: offer to fill in templates/facts.md from this skill's folder with the user (skills, roles, track record exactly as their profile shows it, proof links, phrases never to use). Don't invent any of it. If the user declines, lint without --facts and tell them claims were not checked.

2. Fit the format to the site

Ask which marketplace if the user didn't say. Then:

  • Upwork: a cover letter of 50-90 words plus any screening answers. Answer each screening question directly, in the order asked.
  • Freelancer.com, PeoplePerHour, Guru: bids are compared side by side with a price and a delivery time. Put the concrete approach in the first line, and make sure the price and days in the text match the numbers the user enters in the bid form.
  • Fiverr brief or custom offer: the buyer chose a category, so open with their exact deliverable, then what the offer includes and how many revisions.
  • Contra or a direct inquiry: treat it as a first message; lint with --mode message.

Mirror the client: three casual lines get three casual lines back, another language gets that language.

3. Write

Plain sentences, no bullets or headings:

  1. A greeting in the client's style, then one concrete detail of THEIR post and what likely causes it or how you'd approach it. Never restate the post.
  2. One proof line from the facts file that really matches. A personal project is called a personal project. No honest match: leave proof out.
  3. The plan in one or two sentences, with hours and a price if the user gave a rate.
  4. One question, the one whose answer changes the scope or the price.
  5. The user's first name on its own line.

4. Lint and fix

node ${CLAUDE_SKILL_DIR}/scripts/lint-cover.mjs --facts facts.md --job job.md bid.md

- reads stdin, --mode message drops the word range for replies, --json gives machine output. Fix every error and rerun until it exits 0. Fix warnings too unless there's a reason, and say the reason.

What fails a bid (errors): template phrases ("I hope this finds you well", "seamless", "I'm excited to"), "not just X, but Y" contrasts, em dashes, placeholders like [Your Name], emails, phone numbers or "message me on WhatsApp" (most marketplaces ban moving contact off the site before a contract), links and "N years" the facts file doesn't back, phrases under "Never say", and more than 90 words in cover mode. Warnings cover tech names that are in neither the facts nor the post, a missing or second question, lists, "Dear Sir", "!!", emoji and very long sentences. Per-project tweaks go in .cover-lint.json: {"facts": "facts.md", "maxWords": 90, "minWords": 50, "extraPhrases": [], "allowPhrases": [], "disable": []}.

Never edit the facts file to make a claim pass without the user saying it's true.

5. Hand it over

Show the bid, the price and delivery time it states, and the linter's last line. Then read it once more against the facts file yourself: the linter checks links, years and tech names, not every sentence. The user sends it; never submit anything for them.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Related Skills