[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6AE9DBMV1ZGJ4PYE3QD0WGS":3,"skill-same:01M6AE9DBMV1ZGJ4PYE3QD0WGS":90},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":45,"linkOnly":46,"markdownContent":47,"markdownBody":48,"frontMatter":49,"refName":60,"commitSha":61,"skillDirectory":62,"forksCount":63,"repositoryHtmlUrl":64,"repositoryHomepageUrl":65,"ownerHtmlUrl":66,"ownerBlogUrl":67,"ownerDescription":68,"updatedAt":69,"install":70,"resources":83},"01M6AE9DBMV1ZGJ4PYE3QD0WGS","curviate-profile",null,"Read and write LinkedIn profiles and company pages with the Curviate CLI, and resolve human search terms into the opaque filter ids the search commands need. Covers `profile` (me, detail, sections, update, subscription, analytics, visitors, SSI), `company` (detail, employees, posts, jobs, followers, page inbox, follow-invite), `search parameters`, retrieval mode (`--mode`\u002F`--max-age`), and the session\u002Faccount commands (`login`, `config`, `account`). Use when fetching or updating a member or company profile, resolving a filter id, choosing between a stored copy and a live LinkedIn read, or connecting an account.","davila7\u002Fclaude-code-templates","davila7","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6216945?v=4","01M6ADEWWFPS191NFM0Y1EX1JH","Daniel Avila","01M6ADJHGM78PHQRD3XZTFDVKK",33602,"MIT","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fcurviate\u002Fcurviate-profile\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],"curviate profile","curviate","profile","read","when","company","invite","login","mode","posts","filter","human","me","max","write","cli","ids","Recruiting","https","search","inbox","update","plugin","analytics","config","github","2026-11-10 10:12:30",false,"---\nname: curviate-profile\ndescription: \"Read and write LinkedIn profiles and company pages with the Curviate CLI, and resolve human search terms into the opaque filter ids the search commands need. Covers `profile` (me, detail, sections, update, subscription, analytics, visitors, SSI), `company` (detail, employees, posts, jobs, followers, page inbox, follow-invite), `search parameters`, retrieval mode (`--mode`\u002F`--max-age`), and the session\u002Faccount commands (`login`, `config`, `account`). Use when fetching or updating a member or company profile, resolving a filter id, choosing between a stored copy and a live LinkedIn read, or connecting an account.\"\nlicense: MIT\nmetadata:\n  version: 0.1.0\n  author: Curviate\n  tags: [LinkedIn, CLI, Agents, Sales, Recruiting, Outreach]\n  repository: https:\u002F\u002Fgithub.com\u002FCurviate\u002Fcurviate-plugin\n---\n\n# Curviate: profiles, companies, and filter ids\n\nProfiles are the entry point for almost every LinkedIn workflow: you resolve a person or a company,\nthen act. This skill covers that resolution, the company page surface, the parameter lookup every\nstructured search depends on, and the account plumbing underneath all of it.\n\nCommand surface established against CLI `0.33.0`.\n\n## Before any command\n\n```bash\nnpm install -g @curviate\u002Fcli && curviate --version    # needs Node 18 or newer\ncurviate login --api-key \u003Ckey>                        # or export CURVIATE_API_KEY\ncurviate account list --json                          # verify: your connected LinkedIn accounts\n```\n\n- **Resolve the binary first.** If `curviate --version` fails, install it. Do not substitute a raw\n  HTTP call for a command you could not find; the command surface is the contract.\n- **Credentials resolve flag > environment > stored profile.** `CURVIATE_API_KEY`,\n  `CURVIATE_BASE_URL` and `CURVIATE_ACCOUNT` are the right path for a scripted run: the key stays out\n  of `argv`, out of `ps`, and out of shell history.\n- **`--json` on anything you parse.** It is already the default when stdout is not a terminal; ask\n  for it explicitly when a human might also be watching.\n- **`--preview` before every write.** It renders the resolved request without sending it. On a read\n  command it is refused with exit `2`.\n- **`--fields a,b,c` to project.** Profile responses carry 18 or more fields; projecting cuts most of\n  that away.\n- **`--verbose` when a slim response looks suspiciously empty.** An empty slim field is not proof the\n  data does not exist; see Traps.\n- **Put global flags at the end of the command.** Trailing placement is unambiguous on every version;\n  a leading global flag has been dropped silently by older builds, running under whichever account\n  was already active rather than the one you named.\n\n### `--profile` and `--account` are different questions\n\nBoth exist on every command and they answer different questions. Pass either, both, or neither:\n\n| Flag | Chooses | Reach for it when |\n|---|---|---|\n| `--profile \u003Cname>` | The stored credential set: API key, base URL, and a default account. | You hold several tenants or keys locally, or you want the call site to read as a name rather than an opaque id. |\n| `--account \u003Cacc_id>` | Which connected LinkedIn account performs this one command, overriding the profile's default. | The tenant has more than one connected account and this command must act as a specific one. |\n\n`--account` takes an account id only; an account *name* comes back `ACCOUNT_NOT_FOUND`, exit `4`.\nA structurally malformed value is refused at exit `2` before the request is built. Resolve ids live\nwith `curviate account list --json`; they change when an account is reconnected, so never hard-code\none.\n\n## Retrieval mode: `--mode` and `--max-age`\n\nExactly four reads decide between a stored copy and a live LinkedIn call: `profile me`,\n`profile \u003Cid>`, `inbox get` and `inbox messages`. Two of them are here.\n\n| `--mode` | Behaviour |\n|---|---|\n| `auto` (default) | A stored copy while it is fresh, otherwise fetch. |\n| `live` | Always fetch from LinkedIn. |\n| `refill` | A stored copy at any age; fetch only when nothing is stored. |\n| `cache_only` | Never fetch. A store miss is refused, not fetched. |\n\n`--max-age \u003Cseconds>` (0 to 31536000) overrides those presets in both directions; `--max-age 0` is\nthe same as `--mode live`.\n\nEvery response carries its provenance: `source: store | live` plus `observed_at` under `--json`, and\na `provenance:` line on stderr in human mode. Read `source` rather than assuming.\n\n```bash\ncurviate profile me --mode live --json          # source: live\ncurviate profile me --mode cache_only --json    # source: store, with observed_at\n```\n\nThree mechanics that decide whether a retrieval-mode call works:\n\n- **`cache_only` with `--max-age` is a usage error, exit `2`**, raised before any network call.\n  `cache_only` never reaches LinkedIn at any age, so a freshness threshold cannot change its answer.\n  Drop `--max-age`, or use `--mode refill`.\n- **`cache_only` on a store miss is exit `14` (`NOT_STORED`)**: the profile may exist perfectly well\n  on LinkedIn, this API just holds no copy. It is not \"not found\" (`4`), so re-checking the\n  identifier is the wrong move, and it is not retryable as sent. Re-read with `--mode refill` (fetch\n  once, store it), `auto`, or `live`.\n- **Every other command refuses the flags outright rather than ignoring them**: `unknown flag\n  --mode`, exit `2`. A retrieval-mode habit applied to `search people` fails loudly, which is the\n  good case: you are never silently served an unintended freshness.\n\nOne same-named flag is unrelated: `job publish --mode FREE|PROMOTED|PROMOTED_PLUS` selects a\npublishing mode and spends money. It has nothing to do with retrieval.\n\n## `profile`: members\n\n`profile \u003Cid>` accepts a vanity slug, a full profile URL (country subdomains such as\n`de.linkedin.com` included), a URN, a native member id (`ACoAA…`), or `me`.\n\n| Command | What it does | Confidence |\n|---|---|---|\n| `curviate profile \u003Cid>` | One member's profile. Accepts `--mode`\u002F`--max-age`, `--sections`, and the activity flags below. | proven |\n| `curviate profile me` | Your own connected profile. Accepts `--mode`\u002F`--max-age`. | proven |\n| `curviate profile \u003Cid> --posts` | That member's activity feed (posts and reposts). Same data as `post user-posts \u003Cid>`. | proven |\n| `curviate profile \u003Cid> --comments` | That member's comments on other people's posts. Same data as `comment user \u003Cid>`. | proven |\n| `curviate profile \u003Cid> --reactions` | That member's reactions. Works on any public profile. Returns `value` and `post_id`; no timestamp exists. | proven |\n| `curviate profile \u003Cid> --sections \u003Clist>` | LinkedIn sections: `linkedin_experience`, `linkedin_education`, `linkedin_languages`, `linkedin_skills`, `linkedin_certifications`, `linkedin_volunteer_experience`, `linkedin_projects`, `linkedin_recommendations`, `linkedin_interests`, or `linkedin_*` for all. A bare `skills` auto-prefixes. **Pair with `--verbose` every time.** | proven |\n| `curviate profile update [--headline] [--bio] [--first-name] [--last-name] [--skills] [--picture] [--background-picture]` | Update your own profile. Only the flags you pass are sent. | proven |\n| `curviate profile subscription` | Your premium entitlements and plan. A free account is a valid result (`has_premium: false`), not an error. | proven |\n| `curviate profile analytics` | Profile viewers, followers, post impressions and search appearances over LinkedIn's own fixed reporting windows. No window selector exists. | proven |\n| `curviate profile visitors` | Recent profile viewers, classified by disclosure fidelity: identified, semi-anonymous, or aggregate. Premium accounts see more identified viewers. | proven |\n| `curviate profile ssi` | Social Selling Index: overall score, four pillar breakdowns, industry and network percentile ranks. | proven |\n| `curviate profile endorse \u003Cid> --endorsement-id \u003Cid>` | Endorse a skill. Irreversible: there is no unendorse. | **wired, never live-fired** |\n\n`profile follow`, `unfollow`, `relations`, `followers` and `following` belong to the network\nworkflow; see `curviate-network`.\n\n### Traps\n\n- **`--sections` returns zero items unless you also pass `--verbose`.** The slim projection strips\n  the section payload even when you asked for that exact section. Always pair them.\n- **`emails` and `phone_numbers` need `--verbose`, and `--fields` does not escalate for you.**\n  `profile \u003Cid>` slim strips both; `profile me` slim keeps `emails` and drops `phone_numbers`.\n  `--fields emails,phone_numbers` without `--verbose` returns `{}` and a stderr warning, which\n  reads exactly like \"this member published no contact details\". It is not.\n- **Contact fields are gated on first-degree connection, and absent rather than empty below it.** At\n  second degree `emails` and `social_handles` are missing from the response entirely and\n  `phone_numbers` is `[]`. Fetch from whichever account is actually connected, and re-fetch after an\n  invitation is accepted. A profile read costs the same either way, so pass `--verbose` up front\n  rather than paying for two reads.\n- **`specifics.throttled_sections` is `--verbose`-only, and it is a correctness signal.** It names\n  the sections LinkedIn rate-limited on this request. Without it you cannot tell \"this member has no\n  listed experience\" from \"the experience section was throttled, retry it\". Read it before treating\n  an empty section as ground truth, and requery only sections that actually appear in it.\n- **A missing member and a premium-gated member are indistinguishable on a non-premium account.** A\n  nonexistent slug returns `LINKEDIN_FEATURE_NOT_SUBSCRIBED`, exit `5`, never `404`\u002Fexit `4`. Deep\n  reads of some out-of-network members hit the same gate even though the search that found them\n  needed no subscription at all. Verify a handle through `search people` before concluding that a\n  subscription would fix it.\n- **`profile update --headline` reads back on the `description` field, and there is no `--description`\n  flag.** The write takes `--headline`; the read response mirrors that text under `description`\n  (\"NOT the About\u002FSummary section\", which is `bio`). `--fields headline` on a read matches nothing and\n  is silently dropped like any unmatched path; project it as `--fields description`.\n- **A profile write can take minutes to about two and a half hours to appear on read-back.** A\n  `profile update` returning exit `0` was accepted. A stale-looking read immediately after is not\n  evidence the write failed.\n- **A profile fetch is a real, member-visible profile view** and consumes the account's daily\n  profile-view allowance. Do not fetch speculatively in a loop.\n- **Never write `profile me relations`.** The command is `profile relations`. Older builds silently\n  discarded `relations` and answered with your own profile at exit `0`; current builds exit `2`.\n\n## `company`: company pages\n\n`company \u003Cid>` takes a slug, URL or numeric id. **Its sub-resources need the numeric provider id**\nreturned by that first call, so it is always two steps.\n\n| Command | What it does | Confidence |\n|---|---|---|\n| `curviate company \u003Cid>` | The company profile: name, employee count, website, industry. | proven |\n| `curviate company \u003Cid> employees` | People who currently work there. Supports `--keywords`. | proven |\n| `curviate company \u003Cid> posts` | The page's posts. | proven |\n| `curviate company \u003Cid> jobs` | The page's open postings. | proven |\n| `curviate company managed` | The pages this account administers. An empty result is valid. | proven |\n| `curviate company \u003Cid> followers` | A page's followers, newest first. Admin-gated. | proven |\n| `curviate company \u003Cid> invitable-followers` | First-degree connections eligible to be invited to follow the page. Items carry no name or headline; hydrate a candidate with `profile \u003Cid>` before deciding. `invite_token` is always base64. | proven |\n| `curviate company \u003Cid> follow-invite --invitee \u003Cmember_id>` | Invite those connections to follow the page. Admin-gated write, one `--invitee` per person. | proven |\n| `curviate company \u003Cid> chats` | The page's admin message inbox. Admin-gated. Beta. | proven |\n| `curviate company \u003Cid> chat \u003Cchat_id>` | One conversation from that inbox. Admin-gated. Beta. | proven |\n| `curviate company \u003Cid> messages \u003Cchat_id>` | A page conversation's messages, newest first. Admin-gated. | proven |\n| `curviate company \u003Cid> message \u003Cchat_id> \u003Cmessage_id>` | One message from a page conversation. Admin-gated. | proven |\n| `curviate company \u003Cid> search-chats [query]` | Search the page inbox. Exactly one mode per call: free text, `--topic`, or `--unread`, mutually exclusive, enforced server-side. Admin-gated. | proven |\n| `curviate company \u003Cid> reply \u003Cchat_id> \u003Ctext>` | Reply in a page conversation, as the page. Admin-gated write. Reply-only: it cannot start a conversation. | proven |\n\n**`follow-invite` is all-or-nothing.** A request where every invitee id is valid returns one outcome\nper invitee in request order (`invited`, `already_invited`, `ineligible`, `not_found`). A single\ninvalid id rejects the whole request with a `404` rather than a partial result. Re-inviting someone\nalready invited is a safe no-op that returns the same invitation id, never a duplicate.\n\n## `search parameters`: turning words into filter ids\n\nStructured search filters take opaque ids, not human text. Resolve first, then search.\n\n```bash\ncurviate search parameters --type LOCATION --keywords \"Germany\" --limit 5 --json\ncurviate search people --location \u003Cid> --keywords \"AI engineer\" --json\n```\n\n| Command | What it does | Confidence |\n|---|---|---|\n| `curviate search parameters --type \u003CT> --keywords \"\u003Cterm>\"` | Resolve a term to filter ids. `--type` is one of `LOCATION`, `PEOPLE`, `CONNECTIONS`, `COMPANY`, `SCHOOL`, `INDUSTRY`, `SERVICE`, `JOB_FUNCTION`, `JOB_TITLE`, `EMPLOYMENT_TYPE`, `SKILL`. Both flags required for every type. | proven |\n| `curviate search service-parameters --keywords \"\u003Cterm>\" [--type service_category\\|location]` | The same resolution for the Services Marketplace filters `search services` accepts. `--type` defaults to `service_category`. | proven |\n\n- **A filter value that is a name rather than an id is silently dropped and the search runs\n  unfiltered, at exit `0`.** `--location \"Germany\"` has returned results from New York, Bengaluru and\n  Toronto with no warning at all. Resolve every `--location`, `--industry`, `--company` and\n  `--school` value through this command first.\n- **`JOB_FUNCTION` returns string tokens** (`eng`, `sale`), not numeric ids, unlike every other type.\n  Pass the string straight into `search jobs --function`.\n- **`--type PEOPLE` is a working name-to-member lookup** and returns real member profiles; it is also\n  how you resolve `search people --followers-of`.\n- Results carry both `id` and `public_identifier`, so they chain directly into a connect or a message.\n\n## Session and connected accounts\n\n| Command | What it does | Confidence |\n|---|---|---|\n| `curviate setup` | Connect this machine to your workspace: opens the dashboard, takes the code it shows you, and saves an API key. `--no-browser` prints the link instead of opening it; `--code -` reads the code from stdin, keeping it out of `argv`, `ps` and shell history. | proven |\n| `curviate doctor` | Check this machine can call the API: config, credential source, workspace, reachability and connected accounts. The first thing to run when a command fails for no obvious reason. | proven |\n| `curviate login --api-key \u003Ckey>` | Store an API key in a local profile. | proven |\n| `curviate config list` | Every stored profile and the active one. Keys are redacted. | proven |\n| `curviate config path` | The config file path. | proven |\n| `curviate config use \u003Cname>` | Set the active profile. | proven |\n| `curviate config rename \u003Cold> \u003Cnew>` | Rename a profile. | proven |\n| `curviate config set-account \u003Cacc_id>` | Set a profile's default acting account. | proven |\n| `curviate config set-base-url [url]` | Set or clear a profile's base URL. | proven |\n| `curviate config reset` | Remove the config file, or one profile. | proven |\n| `curviate account list` | Connected LinkedIn accounts: where an `acc_id` comes from. | proven |\n| `curviate account get \u003Cacc_id>` | One account, including `quotas[]`: per-action daily allowances with their reset times. **This is the one command that reads your remaining allowance back.** The id is positional even when the profile has a default. | proven |\n| `curviate account seats` | The workspace's live seats: `seat_id`, `occupied`, and `account_id` where occupied. A free seat (`occupied: false`) is the source of the `--seat-id` `account link` needs; not paginated, `--all` is refused. | wired, never live-fired |\n| `curviate account link --seat-id \u003Cid> --auth-method \u003Cm>` | Connect a LinkedIn account to an empty seat. Get a free `seat_id` from `curviate account seats` first. Prompts for a verification code interactively; a non-interactive shell exits `12` and you finish with `account checkpoint solve`. | proven |\n| `curviate account connect-session poll --session \u003Cid>` | Poll an in-progress connect. `status` is `pending`, `resolved`, `expired` or `failed`. `--wait` blocks until a terminal state. | proven |\n| `curviate account checkpoint solve \u003Cacc_id> --code \u003Cotp>` | Answer a checkpoint challenge with a one-time code. | proven |\n| `curviate account checkpoint poll \u003Cacc_id>` | Poll for mobile-app approval of a pending challenge. `--wait` blocks. | proven |\n| `curviate account checkpoint request \u003Cacc_id>` | Re-send the challenge notification. Not every challenge type can: an authenticator-app code has nothing to re-send. The response's `resent` boolean is honest; the command exits `0` either way, so read the field. | proven |\n| `curviate account update \u003Cacc_id>` | Update account metadata or custom-proxy configuration. | proven |\n| `curviate account disconnect \u003Cacc_id>` | Hard-disconnect an account and release its seat. | proven |\n\n**Zero connected accounts is a valid state**, not an error: a fresh tenant authenticates fine and\n`account list` returns an empty list. Every account-scoped command is unusable until an account is\nconnected.\n\n**Verify each account, not just the first.** `account list` proves an account exists and reads\n`status: \"active\"`; it does not prove the session round-trips. For each id:\n\n```bash\ncurviate profile me --account \u003Cacc_id> --fields first_name,last_name,description --json\n```\n\nExit `0` with a populated name proves auth, account scoping and field projection work together.\n\n## Full command surface\n\n\u003C!-- generated: command surface, CLI 0.33.0 -->\n\nRead from the CLI's own `--help` at version 0.33.0. Descriptions, traps and confidence\ntags elsewhere in this skill are hand-written and carry the version they were established against.\n\nEvery command below that takes flags at all also accepts `--json`.\n\n| Command | Arguments | Flags |\n|---|---|---|\n| `curviate config list` | *(none)* | *(none)* |\n| `curviate config path` | *(none)* | *(none)* |\n| `curviate config use` | `NAME` | *(none)* |\n| `curviate config rename` | `OLD` `NEW` | *(none)* |\n| `curviate config set-account` | `ACCOUNT` | `--profile` |\n| `curviate config set-base-url` | `URL` | `--profile`, `--reset` |\n| `curviate config reset` | *(none)* | `--profile`, `--yes` |\n| `curviate profile` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta`, `--posts`, `--comments`, `--reactions`, `--followers`, `--is-company`, `--mode`, `--max-age`, `--sections` |\n| `curviate profile me` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta`, `--mode`, `--max-age`, `--sections`, `--posts`, `--comments`, `--reactions`, `--followers` |\n| `curviate profile endorse` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--preview`, `--verbose`, `--beta`, `--endorsement-id` *(required)* |\n| `curviate profile update` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta`, `--headline`, `--bio`, `--first-name`, `--last-name`, `--skills`, `--picture`, `--background-picture` |\n| `curviate profile subscription` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta` |\n| `curviate profile analytics` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta` |\n| `curviate profile visitors` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta` |\n| `curviate profile ssi` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta` |\n| `curviate company` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--preview`, `--verbose`, `--beta`, `--sections` |\n| `curviate company employees` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta`, `--keywords`, `--location` |\n| `curviate company posts` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta` |\n| `curviate company jobs` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta`, `--keywords` |\n| `curviate company invitable-followers` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta` |\n| `curviate company follow-invite` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--preview`, `--verbose`, `--beta`, `--invitee` |\n| `curviate company reply` | `ID` `CHATID` `TEXT` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--preview`, `--verbose`, `--beta`, `--attach` |\n| `curviate company managed` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta` |\n| `curviate company followers` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta` |\n| `curviate company chats` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta` |\n| `curviate company chat` | `ID` `CHATID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--preview`, `--verbose`, `--beta` |\n| `curviate company messages` | `ID` `CHATID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta` |\n| `curviate company message` | `ID` `CHATID` `MESSAGEID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--preview`, `--verbose`, `--beta` |\n| `curviate company search-chats` | `ID` `QUERY` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta`, `--topic`, `--unread` |\n| `curviate search parameters` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--preview`, `--verbose`, `--beta`, `--type` *(required)*, `--keywords` *(required)* |\n| `curviate search service-parameters` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--preview`, `--verbose`, `--beta`, `--type`, `--keywords` *(required)* |\n| `curviate account list` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta` |\n| `curviate account get` | `ACCOUNT-ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta` |\n| `curviate account seats` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta` |\n| `curviate account link` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta`, `--seat-id` *(required)*, `--auth-method` *(required)*, `--email`, `--password`, `--password-stdin`, `--li-at`, `--li-at-stdin`, `--li-a`, `--country`, `--ip`, `--proxy-protocol`, `--proxy-host`, `--proxy-port`, `--proxy-username`, `--proxy-password`, `--user-agent`, `--recruiter-contract-id`, `--linkedin-premium`, `--account-id`, `--no-interactive` |\n| `curviate account connect-session poll` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta`, `--session` *(required)*, `--wait` |\n| `curviate account update` | `ACCOUNT-ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta`, `--metadata`, `--clear-proxy`, `--proxy-protocol`, `--proxy-host`, `--proxy-port`, `--proxy-username`, `--proxy-password` |\n| `curviate account disconnect` | `ACCOUNT-ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta` |\n| `curviate account checkpoint solve` | `ACCOUNT-ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta`, `--code` *(required)* |\n| `curviate account checkpoint poll` | `ACCOUNT-ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta`, `--wait` |\n| `curviate account checkpoint request` | `ACCOUNT-ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta` |\n\n\u003C!-- \u002Fgenerated -->\n\n## Exit codes to branch on here\n\nBranch on the exit code, never on the message text. Under `--json` an error prints\n`{\"error\": {\"code\", \"message\", …}}`.\n\n| Code | Meaning | What to do |\n|---|---|---|\n| `1` | `INTERNAL` from the server itself: a genuine bug on the platform side. | Worth one retry; if it repeats it is a bug to report, not a state to work around. |\n| `2` | Usage or invalid input, often raised before any network call. | Fix the invocation. Never retry unchanged. |\n| `4` | Not found. | Wrong identifier, or the resource is gone. |\n| `5` | Three causes, one code: read `error.code`. `NO_ACTIVE_SEAT`: the account is on no active seat. `LINKEDIN_FEATURE_NOT_SUBSCRIBED`: LinkedIn itself lacks the feature. `BETA_NOT_ENABLED`: the operation is beta-gated and this workspace has not opted in. | Branch on `error.code`: the three fixes have nothing in common, and none is fixed by retrying unchanged. |\n| `6` | `PLATFORM_RATE_LIMIT` and its siblings. Carries `retry_after` in whole seconds. A response naming `budgetRow` means only that row is paused; every other row on the account keeps working. | **Back off and retry** after that many seconds. On a named `budgetRow`, switch to other work on the account rather than backing off across the board. |\n| `7` | Transient platform fault: a request that got no response at all (network error, DNS failure, timeout) or one that came back as something other than a valid API answer. Carries `retryLikelyToSucceed: true`. | Retry with backoff. |\n| `8` | Account or connection state. Read `error.code`: `ACCOUNT_RESTRICTED`, `LINKEDIN_AUTH_FAILED` and `LINKEDIN_COOKIE_INVALID` need a reconnect; `LINKEDIN_OPERATION_NOT_SUPPORTED` is a permanent platform limitation and never retryable; `ACCOUNT_ALREADY_LINKED` means `account link` targeted a seat or account that is already connected. | Depends on `error.code`; do not assume \"reconnect\" covers all of them. On `ACCOUNT_ALREADY_LINKED`, pass `--account-id \u003Cexisting acc_...>` to `account link` to re-authenticate that account in place, or use the account it already names instead of retrying the original call. |\n| `9` | Checkpoint *failure*, the challenge is dead: `CHECKPOINT_NOT_FOUND`, `CHECKPOINT_EXPIRED`, `CHECKPOINT_INVALID_CODE`, `CHECKPOINT_MAX_ATTEMPTS`, `CHECKPOINT_ALREADY_RESOLVED` or `CHECKPOINT_UNSUPPORTED`. Raised by `checkpoint solve` on a wrong or stale code, `checkpoint poll --wait` timing out into a terminal state, or `checkpoint request` against a checkpoint that is already gone. | Start over: `curviate account link` (pass `--account-id \u003Cacc_...>` to reconnect an existing account in place). Distinct from `12`, which is still resolvable with the next step. |\n| `12` | A connect flow needs its next authentication step. | Run the checkpoint flow, or poll the connect session. Distinct from `9`, a checkpoint *failure*. |\n| `13` | `BUDGET_EXHAUSTED`: a safety rule of your own refused the action, not LinkedIn. Read `error.safetyReason`: `ceiling` means the row named in `error.budgetRow` hit its configured limit; `activity_window` means the account is outside the hours it works in (no `budgetRow` on that one). **Nothing reached LinkedIn and nothing was spent.** `reset_at` can be weeks out, and may be `null` where no clock frees it. | **Do not back off and retry.** `error.safetyHint.parameter` names the exact setting to change (for example `profile_views.ceiling`, or `posture` where no ceiling applies). Read `quotas[]` via `account get`, then either wait for the named reset or change that setting. A retry loop here only burns time. |\n| `14` | `NOT_STORED`: a `cache_only` read the store cannot answer. | Re-read with `refill`, `auto` or `live`. Re-checking the id is the wrong move. |\n","# Curviate: profiles, companies, and filter ids\n\nProfiles are the entry point for almost every LinkedIn workflow: you resolve a person or a company,\nthen act. This skill covers that resolution, the company page surface, the parameter lookup every\nstructured search depends on, and the account plumbing underneath all of it.\n\nCommand surface established against CLI `0.33.0`.\n\n## Before any command\n\n```bash\nnpm install -g @curviate\u002Fcli && curviate --version    # needs Node 18 or newer\ncurviate login --api-key \u003Ckey>                        # or export CURVIATE_API_KEY\ncurviate account list --json                          # verify: your connected LinkedIn accounts\n```\n\n- **Resolve the binary first.** If `curviate --version` fails, install it. Do not substitute a raw\n  HTTP call for a command you could not find; the command surface is the contract.\n- **Credentials resolve flag > environment > stored profile.** `CURVIATE_API_KEY`,\n  `CURVIATE_BASE_URL` and `CURVIATE_ACCOUNT` are the right path for a scripted run: the key stays out\n  of `argv`, out of `ps`, and out of shell history.\n- **`--json` on anything you parse.** It is already the default when stdout is not a terminal; ask\n  for it explicitly when a human might also be watching.\n- **`--preview` before every write.** It renders the resolved request without sending it. On a read\n  command it is refused with exit `2`.\n- **`--fields a,b,c` to project.** Profile responses carry 18 or more fields; projecting cuts most of\n  that away.\n- **`--verbose` when a slim response looks suspiciously empty.** An empty slim field is not proof the\n  data does not exist; see Traps.\n- **Put global flags at the end of the command.** Trailing placement is unambiguous on every version;\n  a leading global flag has been dropped silently by older builds, running under whichever account\n  was already active rather than the one you named.\n\n### `--profile` and `--account` are different questions\n\nBoth exist on every command and they answer different questions. Pass either, both, or neither:\n\n| Flag | Chooses | Reach for it when |\n|---|---|---|\n| `--profile \u003Cname>` | The stored credential set: API key, base URL, and a default account. | You hold several tenants or keys locally, or you want the call site to read as a name rather than an opaque id. |\n| `--account \u003Cacc_id>` | Which connected LinkedIn account performs this one command, overriding the profile's default. | The tenant has more than one connected account and this command must act as a specific one. |\n\n`--account` takes an account id only; an account *name* comes back `ACCOUNT_NOT_FOUND`, exit `4`.\nA structurally malformed value is refused at exit `2` before the request is built. Resolve ids live\nwith `curviate account list --json`; they change when an account is reconnected, so never hard-code\none.\n\n## Retrieval mode: `--mode` and `--max-age`\n\nExactly four reads decide between a stored copy and a live LinkedIn call: `profile me`,\n`profile \u003Cid>`, `inbox get` and `inbox messages`. Two of them are here.\n\n| `--mode` | Behaviour |\n|---|---|\n| `auto` (default) | A stored copy while it is fresh, otherwise fetch. |\n| `live` | Always fetch from LinkedIn. |\n| `refill` | A stored copy at any age; fetch only when nothing is stored. |\n| `cache_only` | Never fetch. A store miss is refused, not fetched. |\n\n`--max-age \u003Cseconds>` (0 to 31536000) overrides those presets in both directions; `--max-age 0` is\nthe same as `--mode live`.\n\nEvery response carries its provenance: `source: store | live` plus `observed_at` under `--json`, and\na `provenance:` line on stderr in human mode. Read `source` rather than assuming.\n\n```bash\ncurviate profile me --mode live --json          # source: live\ncurviate profile me --mode cache_only --json    # source: store, with observed_at\n```\n\nThree mechanics that decide whether a retrieval-mode call works:\n\n- **`cache_only` with `--max-age` is a usage error, exit `2`**, raised before any network call.\n  `cache_only` never reaches LinkedIn at any age, so a freshness threshold cannot change its answer.\n  Drop `--max-age`, or use `--mode refill`.\n- **`cache_only` on a store miss is exit `14` (`NOT_STORED`)**: the profile may exist perfectly well\n  on LinkedIn, this API just holds no copy. It is not \"not found\" (`4`), so re-checking the\n  identifier is the wrong move, and it is not retryable as sent. Re-read with `--mode refill` (fetch\n  once, store it), `auto`, or `live`.\n- **Every other command refuses the flags outright rather than ignoring them**: `unknown flag\n  --mode`, exit `2`. A retrieval-mode habit applied to `search people` fails loudly, which is the\n  good case: you are never silently served an unintended freshness.\n\nOne same-named flag is unrelated: `job publish --mode FREE|PROMOTED|PROMOTED_PLUS` selects a\npublishing mode and spends money. It has nothing to do with retrieval.\n\n## `profile`: members\n\n`profile \u003Cid>` accepts a vanity slug, a full profile URL (country subdomains such as\n`de.linkedin.com` included), a URN, a native member id (`ACoAA…`), or `me`.\n\n| Command | What it does | Confidence |\n|---|---|---|\n| `curviate profile \u003Cid>` | One member's profile. Accepts `--mode`\u002F`--max-age`, `--sections`, and the activity flags below. | proven |\n| `curviate profile me` | Your own connected profile. Accepts `--mode`\u002F`--max-age`. | proven |\n| `curviate profile \u003Cid> --posts` | That member's activity feed (posts and reposts). Same data as `post user-posts \u003Cid>`. | proven |\n| `curviate profile \u003Cid> --comments` | That member's comments on other people's posts. Same data as `comment user \u003Cid>`. | proven |\n| `curviate profile \u003Cid> --reactions` | That member's reactions. Works on any public profile. Returns `value` and `post_id`; no timestamp exists. | proven |\n| `curviate profile \u003Cid> --sections \u003Clist>` | LinkedIn sections: `linkedin_experience`, `linkedin_education`, `linkedin_languages`, `linkedin_skills`, `linkedin_certifications`, `linkedin_volunteer_experience`, `linkedin_projects`, `linkedin_recommendations`, `linkedin_interests`, or `linkedin_*` for all. A bare `skills` auto-prefixes. **Pair with `--verbose` every time.** | proven |\n| `curviate profile update [--headline] [--bio] [--first-name] [--last-name] [--skills] [--picture] [--background-picture]` | Update your own profile. Only the flags you pass are sent. | proven |\n| `curviate profile subscription` | Your premium entitlements and plan. A free account is a valid result (`has_premium: false`), not an error. | proven |\n| `curviate profile analytics` | Profile viewers, followers, post impressions and search appearances over LinkedIn's own fixed reporting windows. No window selector exists. | proven |\n| `curviate profile visitors` | Recent profile viewers, classified by disclosure fidelity: identified, semi-anonymous, or aggregate. Premium accounts see more identified viewers. | proven |\n| `curviate profile ssi` | Social Selling Index: overall score, four pillar breakdowns, industry and network percentile ranks. | proven |\n| `curviate profile endorse \u003Cid> --endorsement-id \u003Cid>` | Endorse a skill. Irreversible: there is no unendorse. | **wired, never live-fired** |\n\n`profile follow`, `unfollow`, `relations`, `followers` and `following` belong to the network\nworkflow; see `curviate-network`.\n\n### Traps\n\n- **`--sections` returns zero items unless you also pass `--verbose`.** The slim projection strips\n  the section payload even when you asked for that exact section. Always pair them.\n- **`emails` and `phone_numbers` need `--verbose`, and `--fields` does not escalate for you.**\n  `profile \u003Cid>` slim strips both; `profile me` slim keeps `emails` and drops `phone_numbers`.\n  `--fields emails,phone_numbers` without `--verbose` returns `{}` and a stderr warning, which\n  reads exactly like \"this member published no contact details\". It is not.\n- **Contact fields are gated on first-degree connection, and absent rather than empty below it.** At\n  second degree `emails` and `social_handles` are missing from the response entirely and\n  `phone_numbers` is `[]`. Fetch from whichever account is actually connected, and re-fetch after an\n  invitation is accepted. A profile read costs the same either way, so pass `--verbose` up front\n  rather than paying for two reads.\n- **`specifics.throttled_sections` is `--verbose`-only, and it is a correctness signal.** It names\n  the sections LinkedIn rate-limited on this request. Without it you cannot tell \"this member has no\n  listed experience\" from \"the experience section was throttled, retry it\". Read it before treating\n  an empty section as ground truth, and requery only sections that actually appear in it.\n- **A missing member and a premium-gated member are indistinguishable on a non-premium account.** A\n  nonexistent slug returns `LINKEDIN_FEATURE_NOT_SUBSCRIBED`, exit `5`, never `404`\u002Fexit `4`. Deep\n  reads of some out-of-network members hit the same gate even though the search that found them\n  needed no subscription at all. Verify a handle through `search people` before concluding that a\n  subscription would fix it.\n- **`profile update --headline` reads back on the `description` field, and there is no `--description`\n  flag.** The write takes `--headline`; the read response mirrors that text under `description`\n  (\"NOT the About\u002FSummary section\", which is `bio`). `--fields headline` on a read matches nothing and\n  is silently dropped like any unmatched path; project it as `--fields description`.\n- **A profile write can take minutes to about two and a half hours to appear on read-back.** A\n  `profile update` returning exit `0` was accepted. A stale-looking read immediately after is not\n  evidence the write failed.\n- **A profile fetch is a real, member-visible profile view** and consumes the account's daily\n  profile-view allowance. Do not fetch speculatively in a loop.\n- **Never write `profile me relations`.** The command is `profile relations`. Older builds silently\n  discarded `relations` and answered with your own profile at exit `0`; current builds exit `2`.\n\n## `company`: company pages\n\n`company \u003Cid>` takes a slug, URL or numeric id. **Its sub-resources need the numeric provider id**\nreturned by that first call, so it is always two steps.\n\n| Command | What it does | Confidence |\n|---|---|---|\n| `curviate company \u003Cid>` | The company profile: name, employee count, website, industry. | proven |\n| `curviate company \u003Cid> employees` | People who currently work there. Supports `--keywords`. | proven |\n| `curviate company \u003Cid> posts` | The page's posts. | proven |\n| `curviate company \u003Cid> jobs` | The page's open postings. | proven |\n| `curviate company managed` | The pages this account administers. An empty result is valid. | proven |\n| `curviate company \u003Cid> followers` | A page's followers, newest first. Admin-gated. | proven |\n| `curviate company \u003Cid> invitable-followers` | First-degree connections eligible to be invited to follow the page. Items carry no name or headline; hydrate a candidate with `profile \u003Cid>` before deciding. `invite_token` is always base64. | proven |\n| `curviate company \u003Cid> follow-invite --invitee \u003Cmember_id>` | Invite those connections to follow the page. Admin-gated write, one `--invitee` per person. | proven |\n| `curviate company \u003Cid> chats` | The page's admin message inbox. Admin-gated. Beta. | proven |\n| `curviate company \u003Cid> chat \u003Cchat_id>` | One conversation from that inbox. Admin-gated. Beta. | proven |\n| `curviate company \u003Cid> messages \u003Cchat_id>` | A page conversation's messages, newest first. Admin-gated. | proven |\n| `curviate company \u003Cid> message \u003Cchat_id> \u003Cmessage_id>` | One message from a page conversation. Admin-gated. | proven |\n| `curviate company \u003Cid> search-chats [query]` | Search the page inbox. Exactly one mode per call: free text, `--topic`, or `--unread`, mutually exclusive, enforced server-side. Admin-gated. | proven |\n| `curviate company \u003Cid> reply \u003Cchat_id> \u003Ctext>` | Reply in a page conversation, as the page. Admin-gated write. Reply-only: it cannot start a conversation. | proven |\n\n**`follow-invite` is all-or-nothing.** A request where every invitee id is valid returns one outcome\nper invitee in request order (`invited`, `already_invited`, `ineligible`, `not_found`). A single\ninvalid id rejects the whole request with a `404` rather than a partial result. Re-inviting someone\nalready invited is a safe no-op that returns the same invitation id, never a duplicate.\n\n## `search parameters`: turning words into filter ids\n\nStructured search filters take opaque ids, not human text. Resolve first, then search.\n\n```bash\ncurviate search parameters --type LOCATION --keywords \"Germany\" --limit 5 --json\ncurviate search people --location \u003Cid> --keywords \"AI engineer\" --json\n```\n\n| Command | What it does | Confidence |\n|---|---|---|\n| `curviate search parameters --type \u003CT> --keywords \"\u003Cterm>\"` | Resolve a term to filter ids. `--type` is one of `LOCATION`, `PEOPLE`, `CONNECTIONS`, `COMPANY`, `SCHOOL`, `INDUSTRY`, `SERVICE`, `JOB_FUNCTION`, `JOB_TITLE`, `EMPLOYMENT_TYPE`, `SKILL`. Both flags required for every type. | proven |\n| `curviate search service-parameters --keywords \"\u003Cterm>\" [--type service_category\\|location]` | The same resolution for the Services Marketplace filters `search services` accepts. `--type` defaults to `service_category`. | proven |\n\n- **A filter value that is a name rather than an id is silently dropped and the search runs\n  unfiltered, at exit `0`.** `--location \"Germany\"` has returned results from New York, Bengaluru and\n  Toronto with no warning at all. Resolve every `--location`, `--industry`, `--company` and\n  `--school` value through this command first.\n- **`JOB_FUNCTION` returns string tokens** (`eng`, `sale`), not numeric ids, unlike every other type.\n  Pass the string straight into `search jobs --function`.\n- **`--type PEOPLE` is a working name-to-member lookup** and returns real member profiles; it is also\n  how you resolve `search people --followers-of`.\n- Results carry both `id` and `public_identifier`, so they chain directly into a connect or a message.\n\n## Session and connected accounts\n\n| Command | What it does | Confidence |\n|---|---|---|\n| `curviate setup` | Connect this machine to your workspace: opens the dashboard, takes the code it shows you, and saves an API key. `--no-browser` prints the link instead of opening it; `--code -` reads the code from stdin, keeping it out of `argv`, `ps` and shell history. | proven |\n| `curviate doctor` | Check this machine can call the API: config, credential source, workspace, reachability and connected accounts. The first thing to run when a command fails for no obvious reason. | proven |\n| `curviate login --api-key \u003Ckey>` | Store an API key in a local profile. | proven |\n| `curviate config list` | Every stored profile and the active one. Keys are redacted. | proven |\n| `curviate config path` | The config file path. | proven |\n| `curviate config use \u003Cname>` | Set the active profile. | proven |\n| `curviate config rename \u003Cold> \u003Cnew>` | Rename a profile. | proven |\n| `curviate config set-account \u003Cacc_id>` | Set a profile's default acting account. | proven |\n| `curviate config set-base-url [url]` | Set or clear a profile's base URL. | proven |\n| `curviate config reset` | Remove the config file, or one profile. | proven |\n| `curviate account list` | Connected LinkedIn accounts: where an `acc_id` comes from. | proven |\n| `curviate account get \u003Cacc_id>` | One account, including `quotas[]`: per-action daily allowances with their reset times. **This is the one command that reads your remaining allowance back.** The id is positional even when the profile has a default. | proven |\n| `curviate account seats` | The workspace's live seats: `seat_id`, `occupied`, and `account_id` where occupied. A free seat (`occupied: false`) is the source of the `--seat-id` `account link` needs; not paginated, `--all` is refused. | wired, never live-fired |\n| `curviate account link --seat-id \u003Cid> --auth-method \u003Cm>` | Connect a LinkedIn account to an empty seat. Get a free `seat_id` from `curviate account seats` first. Prompts for a verification code interactively; a non-interactive shell exits `12` and you finish with `account checkpoint solve`. | proven |\n| `curviate account connect-session poll --session \u003Cid>` | Poll an in-progress connect. `status` is `pending`, `resolved`, `expired` or `failed`. `--wait` blocks until a terminal state. | proven |\n| `curviate account checkpoint solve \u003Cacc_id> --code \u003Cotp>` | Answer a checkpoint challenge with a one-time code. | proven |\n| `curviate account checkpoint poll \u003Cacc_id>` | Poll for mobile-app approval of a pending challenge. `--wait` blocks. | proven |\n| `curviate account checkpoint request \u003Cacc_id>` | Re-send the challenge notification. Not every challenge type can: an authenticator-app code has nothing to re-send. The response's `resent` boolean is honest; the command exits `0` either way, so read the field. | proven |\n| `curviate account update \u003Cacc_id>` | Update account metadata or custom-proxy configuration. | proven |\n| `curviate account disconnect \u003Cacc_id>` | Hard-disconnect an account and release its seat. | proven |\n\n**Zero connected accounts is a valid state**, not an error: a fresh tenant authenticates fine and\n`account list` returns an empty list. Every account-scoped command is unusable until an account is\nconnected.\n\n**Verify each account, not just the first.** `account list` proves an account exists and reads\n`status: \"active\"`; it does not prove the session round-trips. For each id:\n\n```bash\ncurviate profile me --account \u003Cacc_id> --fields first_name,last_name,description --json\n```\n\nExit `0` with a populated name proves auth, account scoping and field projection work together.\n\n## Full command surface\n\n\u003C!-- generated: command surface, CLI 0.33.0 -->\n\nRead from the CLI's own `--help` at version 0.33.0. Descriptions, traps and confidence\ntags elsewhere in this skill are hand-written and carry the version they were established against.\n\nEvery command below that takes flags at all also accepts `--json`.\n\n| Command | Arguments | Flags |\n|---|---|---|\n| `curviate config list` | *(none)* | *(none)* |\n| `curviate config path` | *(none)* | *(none)* |\n| `curviate config use` | `NAME` | *(none)* |\n| `curviate config rename` | `OLD` `NEW` | *(none)* |\n| `curviate config set-account` | `ACCOUNT` | `--profile` |\n| `curviate config set-base-url` | `URL` | `--profile`, `--reset` |\n| `curviate config reset` | *(none)* | `--profile`, `--yes` |\n| `curviate profile` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta`, `--posts`, `--comments`, `--reactions`, `--followers`, `--is-company`, `--mode`, `--max-age`, `--sections` |\n| `curviate profile me` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta`, `--mode`, `--max-age`, `--sections`, `--posts`, `--comments`, `--reactions`, `--followers` |\n| `curviate profile endorse` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--preview`, `--verbose`, `--beta`, `--endorsement-id` *(required)* |\n| `curviate profile update` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta`, `--headline`, `--bio`, `--first-name`, `--last-name`, `--skills`, `--picture`, `--background-picture` |\n| `curviate profile subscription` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta` |\n| `curviate profile analytics` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta` |\n| `curviate profile visitors` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta` |\n| `curviate profile ssi` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta` |\n| `curviate company` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--preview`, `--verbose`, `--beta`, `--sections` |\n| `curviate company employees` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta`, `--keywords`, `--location` |\n| `curviate company posts` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta` |\n| `curviate company jobs` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta`, `--keywords` |\n| `curviate company invitable-followers` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta` |\n| `curviate company follow-invite` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--preview`, `--verbose`, `--beta`, `--invitee` |\n| `curviate company reply` | `ID` `CHATID` `TEXT` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--preview`, `--verbose`, `--beta`, `--attach` |\n| `curviate company managed` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta` |\n| `curviate company followers` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta` |\n| `curviate company chats` | `ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta` |\n| `curviate company chat` | `ID` `CHATID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--preview`, `--verbose`, `--beta` |\n| `curviate company messages` | `ID` `CHATID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta` |\n| `curviate company message` | `ID` `CHATID` `MESSAGEID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--preview`, `--verbose`, `--beta` |\n| `curviate company search-chats` | `ID` `QUERY` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta`, `--topic`, `--unread` |\n| `curviate search parameters` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--preview`, `--verbose`, `--beta`, `--type` *(required)*, `--keywords` *(required)* |\n| `curviate search service-parameters` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--preview`, `--verbose`, `--beta`, `--type`, `--keywords` *(required)* |\n| `curviate account list` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--limit`, `--cursor`, `--all`, `--max-pages`, `--page-delay`, `--preview`, `--verbose`, `--beta` |\n| `curviate account get` | `ACCOUNT-ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta` |\n| `curviate account seats` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta` |\n| `curviate account link` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta`, `--seat-id` *(required)*, `--auth-method` *(required)*, `--email`, `--password`, `--password-stdin`, `--li-at`, `--li-at-stdin`, `--li-a`, `--country`, `--ip`, `--proxy-protocol`, `--proxy-host`, `--proxy-port`, `--proxy-username`, `--proxy-password`, `--user-agent`, `--recruiter-contract-id`, `--linkedin-premium`, `--account-id`, `--no-interactive` |\n| `curviate account connect-session poll` | *(none)* | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta`, `--session` *(required)*, `--wait` |\n| `curviate account update` | `ACCOUNT-ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta`, `--metadata`, `--clear-proxy`, `--proxy-protocol`, `--proxy-host`, `--proxy-port`, `--proxy-username`, `--proxy-password` |\n| `curviate account disconnect` | `ACCOUNT-ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta` |\n| `curviate account checkpoint solve` | `ACCOUNT-ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta`, `--code` *(required)* |\n| `curviate account checkpoint poll` | `ACCOUNT-ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta`, `--wait` |\n| `curviate account checkpoint request` | `ACCOUNT-ID` | `--api-key`, `--profile`, `--account`, `--base-url`, `--timeout`, `--fields`, `--preview`, `--verbose`, `--beta` |\n\n\u003C!-- \u002Fgenerated -->\n\n## Exit codes to branch on here\n\nBranch on the exit code, never on the message text. Under `--json` an error prints\n`{\"error\": {\"code\", \"message\", …}}`.\n\n| Code | Meaning | What to do |\n|---|---|---|\n| `1` | `INTERNAL` from the server itself: a genuine bug on the platform side. | Worth one retry; if it repeats it is a bug to report, not a state to work around. |\n| `2` | Usage or invalid input, often raised before any network call. | Fix the invocation. Never retry unchanged. |\n| `4` | Not found. | Wrong identifier, or the resource is gone. |\n| `5` | Three causes, one code: read `error.code`. `NO_ACTIVE_SEAT`: the account is on no active seat. `LINKEDIN_FEATURE_NOT_SUBSCRIBED`: LinkedIn itself lacks the feature. `BETA_NOT_ENABLED`: the operation is beta-gated and this workspace has not opted in. | Branch on `error.code`: the three fixes have nothing in common, and none is fixed by retrying unchanged. |\n| `6` | `PLATFORM_RATE_LIMIT` and its siblings. Carries `retry_after` in whole seconds. A response naming `budgetRow` means only that row is paused; every other row on the account keeps working. | **Back off and retry** after that many seconds. On a named `budgetRow`, switch to other work on the account rather than backing off across the board. |\n| `7` | Transient platform fault: a request that got no response at all (network error, DNS failure, timeout) or one that came back as something other than a valid API answer. Carries `retryLikelyToSucceed: true`. | Retry with backoff. |\n| `8` | Account or connection state. Read `error.code`: `ACCOUNT_RESTRICTED`, `LINKEDIN_AUTH_FAILED` and `LINKEDIN_COOKIE_INVALID` need a reconnect; `LINKEDIN_OPERATION_NOT_SUPPORTED` is a permanent platform limitation and never retryable; `ACCOUNT_ALREADY_LINKED` means `account link` targeted a seat or account that is already connected. | Depends on `error.code`; do not assume \"reconnect\" covers all of them. On `ACCOUNT_ALREADY_LINKED`, pass `--account-id \u003Cexisting acc_...>` to `account link` to re-authenticate that account in place, or use the account it already names instead of retrying the original call. |\n| `9` | Checkpoint *failure*, the challenge is dead: `CHECKPOINT_NOT_FOUND`, `CHECKPOINT_EXPIRED`, `CHECKPOINT_INVALID_CODE`, `CHECKPOINT_MAX_ATTEMPTS`, `CHECKPOINT_ALREADY_RESOLVED` or `CHECKPOINT_UNSUPPORTED`. Raised by `checkpoint solve` on a wrong or stale code, `checkpoint poll --wait` timing out into a terminal state, or `checkpoint request` against a checkpoint that is already gone. | Start over: `curviate account link` (pass `--account-id \u003Cacc_...>` to reconnect an existing account in place). Distinct from `12`, which is still resolvable with the next step. |\n| `12` | A connect flow needs its next authentication step. | Run the checkpoint flow, or poll the connect session. Distinct from `9`, a checkpoint *failure*. |\n| `13` | `BUDGET_EXHAUSTED`: a safety rule of your own refused the action, not LinkedIn. Read `error.safetyReason`: `ceiling` means the row named in `error.budgetRow` hit its configured limit; `activity_window` means the account is outside the hours it works in (no `budgetRow` on that one). **Nothing reached LinkedIn and nothing was spent.** `reset_at` can be weeks out, and may be `null` where no clock frees it. | **Do not back off and retry.** `error.safetyHint.parameter` names the exact setting to change (for example `profile_views.ceiling`, or `posture` where no ceiling applies). Read `quotas[]` via `account get`, then either wait for the named reset or change that setting. A retry loop here only burns time. |\n| `14` | `NOT_STORED`: a `cache_only` read the store cannot answer. | Re-read with `refill`, `auto` or `live`. Re-checking the id is the wrong move. |\n",{"name":5,"license":15,"metadata":50,"description":7},{"tags":51,"author":57,"version":58,"repository":59},[52,53,54,55,36,56],"LinkedIn","CLI","Agents","Sales","Outreach","Curviate","0.1.0","https:\u002F\u002Fgithub.com\u002FCurviate\u002Fcurviate-plugin","main","2b749c82b5d11fac39d9a6e021ce3f5b8a541bd1","cli-tool\u002Fcomponents\u002Fskills\u002Fcurviate\u002Fcurviate-profile",3963,"https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates","https:\u002F\u002Faitmpl.com","https:\u002F\u002Fgithub.com\u002Fdavila7","https:\u002F\u002Fdanielavila.me","Building AI dev tools with LLMs","2026-11-15 01:32:48",{"source":8,"skillName":5,"commands":71,"prompt":81,"zipAvailable":82},[72,75,78],{"tool":73,"command":74},"npx","npx skills add davila7\u002Fclaude-code-templates --skill curviate-profile",{"tool":76,"command":77},"bunx","bunx skills add davila7\u002Fclaude-code-templates --skill curviate-profile",{"tool":79,"command":80},"pnpm","pnpm dlx skills add davila7\u002Fclaude-code-templates --skill curviate-profile","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fcurviate\u002Fcurviate-profile\u002FSKILL.md",true,[84],{"path":85,"resourceType":86,"resourceTypeDesc":87,"sizeBytes":88,"sourceHtmlUrl":89},"agents\u002Fopenai.yaml","REFERENCE","参考文档",166,"https:\u002F\u002Fgithub.com\u002Fhareki\u002Fdotfiles\u002Fblob\u002Fmain\u002Fagents\u002F.agents\u002Fskills\u002Fto-questionnaire\u002Fagents\u002Fopenai.yaml",[91,122,149,182,217,241],{"skillNo":92,"name":93,"nameZh":6,"description":94,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":102,"publishedAt":45},"01M70NHBTQ8BV0A2SCAZXEPHCX","wealthville-pool-scoring","Score DeFi liquidity pools before providing liquidity. Returns a 0-100 pool score and an Enter\u002FHold\u002FExit\u002FReduce\u002FAvoid verdict with calibrated confidence for ~68,800 Solana pools and 575 EVM pools, plus a public miss-inclusive track record. Use when asked whether a pool is worth LPing into, which pools look best right now, or how accurate the scores have actually been.","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fweb-data\u002Fwealthville-pool-scoring\u002FSKILL.md",[97],{"categoryNo":98,"categoryName":99,"taxonomyType":100,"taxonomyTypeDesc":101},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[103,104,105,106,107,108,109,110,111,23,112,113,114,115,116,117,118,119,120,121],"scoring","pool","wealthville pool scoring","liquidity","which","for","exit","now","use","reduce","with","record","track","verdict","evm","solana","how","public","look",{"skillNo":123,"name":124,"nameZh":6,"description":125,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":126,"categories":127,"keywords":129,"publishedAt":45},"01M70MB6VR8ERJ4EM8D5KHBMEV","technical-debt-auditor","Scans a codebase and produces a quantified technical debt report with a prioritized remediation plan. Analyzes dead code, TODO\u002FFIXME\u002FHACK markers, dependency staleness, complexity hotspots, code duplication signals, test coverage gaps, unused exports, and outdated patterns. Use this skill when the user asks to audit their codebase for tech debt, wants a health check of their code quality, says things like \"where should I focus refactoring\", \"find code smells\", \"audit my codebase\", \"what technical debt do we have\", \"prioritize cleanup work\", or asks about code quality metrics. Also trigger when the user mentions \"code rot\", \"legacy cleanup\", \"refactoring priorities\", or wants to understand the overall health of a project before a major effort. Trigger even if the user doesn't say \"technical debt\" explicitly — any request to systematically assess code quality and identify improvement priorities belongs here.","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fdevelopment\u002Ftechnical-debt-auditor\u002FSKILL.md",[128],{"categoryNo":98,"categoryName":99,"taxonomyType":100,"taxonomyTypeDesc":101},[130,131,132,133,134,135,136,137,138,139,140,23,141,142,143,144,145,146,147,148],"technical debt","debt","technical","technical debt auditor","auditor","coverage","complexity","markers","project","cleanup","unused","code","todo","work","plan","focus","signals","audit","dependency",{"skillNo":150,"name":151,"nameZh":6,"description":152,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":153,"categories":154,"keywords":164,"publishedAt":45},"01M70KPYH9QNHCNME5GJQGE22K","readonly-sql-guard","Make an agent's database access provably read-only. Use when an agent runs caller-supplied SQL against a production\u002FERP\u002Fanalytics database (a \"query\" MCP tool, text-to-SQL, an admin console), or when reviewing DB-access code for write\u002FDDL\u002Fside-effect\u002Ftransaction-escape risks. Checks what a statement CALLS, not just its shape.","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fdatabase\u002Freadonly-sql-guard\u002FSKILL.md",[155,158,159],{"categoryNo":156,"categoryName":157,"taxonomyType":100,"taxonomyTypeDesc":101},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":98,"categoryName":99,"taxonomyType":100,"taxonomyTypeDesc":101},{"categoryNo":160,"categoryName":161,"taxonomyType":162,"taxonomyTypeDesc":163},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[165,166,167,168,169,170,171,108,172,173,174,175,176,177,178,111,179,180,23,181],"readonly","guard","sql guard","sql","readonly sql guard","erp","effect","read-only","db","just","tool","calls","only","MCP","access","database","query",{"skillNo":183,"name":184,"nameZh":6,"description":185,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":186,"licenseFileUrl":187,"sourceHtmlUrl":188,"categories":189,"keywords":193,"publishedAt":45},"01M6AFY6F7CC2BBZP1QD6VTNVC","web-artifacts-builder","Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn\u002Fui). Use for complex artifacts requiring state management, routing, or shadcn\u002Fui components - not for simple single-file HTML\u002FJSX artifacts.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Futilities\u002Fweb-artifacts-builder\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Futilities\u002Fweb-artifacts-builder\u002FSKILL.md",[190],{"categoryNo":191,"categoryName":192,"taxonomyType":100,"taxonomyTypeDesc":101},"01JBSEEDCAT000000000000009","前端开发",[194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,108,216],"artifacts builder","web","web artifacts builder","artifacts","builder","state","routing","state management","component","css","frontend","ui","Tools","file","components","shadcn","react","Tailwind","suite","jsx","html","single-file","ui components",{"skillNo":218,"name":219,"nameZh":6,"description":220,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":186,"licenseFileUrl":221,"sourceHtmlUrl":222,"categories":223,"keywords":228,"publishedAt":45},"01M6AFWF33SFV9Z3SF4PEEE4BF","webapp-testing","Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fsecurity\u002Fwebapp-testing\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fsecurity\u002Fwebapp-testing\u002FSKILL.md",[224,227],{"categoryNo":225,"categoryName":226,"taxonomyType":100,"taxonomyTypeDesc":101},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":191,"categoryName":192,"taxonomyType":100,"taxonomyTypeDesc":101},[229,230,231,232,233,195,234,204,205,235,236,237,238,108,239,113,240],"webapp testing","testing","webapp","browser","playwright","applications","debugging","toolkit","logs","screenshots","local","behavior",{"skillNo":242,"name":243,"nameZh":6,"description":244,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":186,"licenseFileUrl":245,"sourceHtmlUrl":246,"categories":247,"keywords":255,"publishedAt":45},"01M6AF67Q67JJJ5V51JR2P52KA","discernment-nudge","After you give a substantive answer or draft that the user may act on — advice or recommendations, drafted artifacts such as goals, plans, pitches, proposals, or emails, estimates or projections, analysis or interpretation of data, factual claims they may rely on, or a multi-step argument — invoke this skill BEFORE finalizing your reply and then, if it applies, append 2-3 short follow-up questions, each tied to something specific in what you just produced, that help the user check key facts, probe the reasoning or assumptions, and notice missing context. Do this at most once per conversation. Skip it when the user asked a trivial how-to or simple lookup, wants a purely educational explanation, asked you only to format, convert, or assemble a file from content they provided, is writing code they will run, is doing creative writing or casual chat, or already asked you to double-check, cite, or review — the skill file explains these boundaries and the exact output format.","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fproductivity\u002Fdiscernment-nudge\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fproductivity\u002Fdiscernment-nudge\u002FSKILL.md",[248,251,252],{"categoryNo":249,"categoryName":250,"taxonomyType":100,"taxonomyTypeDesc":101},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":98,"categoryName":99,"taxonomyType":100,"taxonomyTypeDesc":101},{"categoryNo":253,"categoryName":254,"taxonomyType":162,"taxonomyTypeDesc":163},"01JBSEEDCAT000000000000036","内容创作者",[256,257,258,259,260,261,262,263,197,264,207,141,265,266,267,268,269,177,270,23,271,272,273,274,275,119,276],"discernment nudge","nudge","interpretation","help","run","reasoning","data","writing","lookup","content","review","conversation","short","up","invoke","you","analysis","claims","argument","assemble","recommendations"]