opc-symlink
v0.3.1
Published
CLI for logging in to OPC-symlink, publishing profile metadata, and discovering public profiles.
Readme
opc-symlink CLI
Publish profile metadata generated by opc-symlink-skill.
npm install -g opc-symlink@latest
opc-symlink login
opc-symlink upload metadata.json --slug your-name --template gridline
opc-symlink suggest your-name suggestion.json
opc-symlink suggest --homepage-id homepage-id suggestion.json
opc-symlink current-work suggest your-name current-work.json
opc-symlink search "AI automation" --limit 10
opc-symlink profile another-builderlogin uses a GitHub CLI-style device code flow. The CLI prints a code, opens
https://opcsymlink.com/cli/login, and stores a local access token after the
website approves the code.
OPC-symlink no longer accepts uploaded HTML. The platform stores metadata JSON and renders it with trusted built-in templates.
Commands:
opc-symlink login [--host https://opcsymlink.com] [--no-open]
opc-symlink upload <metadata-json-file> [--slug my-name] [--template gridline] [--title "My profile"]
opc-symlink suggest <slug> <suggestion-json-file>
opc-symlink suggest --homepage-id <id> <suggestion-json-file>
opc-symlink current-work suggest <slug> <current-work-json-file>
opc-symlink current-work suggest --example
opc-symlink current-work export <slug> [--out current-work-history.json]
opc-symlink list
opc-symlink delete <slug> [--yes] [--host <host>]
opc-symlink pull <slug> [--out metadata.json]
opc-symlink search <keyword> [--limit 10] [--sort best] [--tag t] [--offer o] [--audience a] [--location l] [--language lang] [--product-status s] [--out results.json] (Plus/Pro)
opc-symlink profile <slug> [slug ...] [--out profiles.json] (alias: view) (Plus/Pro)
opc-symlink templates [--refresh] [--host <host>]
opc-symlink whoami
opc-symlink logoutdelete <slug> removes a homepage permanently (slots are recalculated). In
an interactive shell it asks you to retype the slug; pass --yes for
scripts/CI. There is currently no suggest --withdraw: a submitted
suggestion cannot be recalled from the CLI — reject it via the Dashboard
review flow instead.
templates prints the current hosted-template directory (id + style notes)
without login. It is cache-first (24h TTL per host under
~/.opc-symlink/); pass --refresh to force a re-fetch, and when the
server cannot be reached it falls back to the embedded list (labeled
offline) so the command always works. Agents should run it before picking
a template: the same id must be used for --template and the embedded
metadata style.template.
Hosted templates are gridline, split-signal, cozy-archive,
handwritten, quiet-product, fireline, tile-playground,
night-director, pattern-field, continuous-axis, three-column,
pixel-arcade, copy-collage, ink-hover, and grainy-lab. The CLI rejects
an unknown --template instead of silently falling back to another style.
Legacy template names (terminal, cards, split, timeline, bento,
docs, column, dashboard, hero, poster) are no longer accepted and
are rejected locally with the list of hosted names.
upload creates a new homepage. To change an existing homepage, use
suggest; the server may apply a suggestion automatically according to the
homepage permission mode, otherwise the owner reviews it in the Dashboard.
current-work suggest is the specialized update path for the Current Work
section, and current-work export downloads its stored history when the
account plan allows it.
Suggestion format
suggest accepts a JSON file describing one homepage update. The authoritative
shape is also available offline: run opc-symlink suggest --example (works
without login) or check the Agent Setup page in the web Dashboard.
| Field | Type | Constraint | Required |
|---|---|---|---|
| type | string | One of identity, positioning, audience, offer, product, proof, content, current_work, cta, style, mixed | No — defaults to mixed |
| title | string | 1-120 characters (trimmed) | Yes |
| summary | string | 1-600 characters (trimmed) | Yes |
| affectedPaths | string[] | Up to 24 items, 1-160 characters each | No |
| affectedSections | string[] | Up to 12 items, 1-80 characters each | No |
| rawContent | any | Stored as-is, never validated | No |
| proposedPatch | object | Profile metadata patch | Yes |
Unknown top-level fields are ignored. The whole payload must stay within 128 KB. The CLI validates all of this locally before sending anything, so a bad payload fails fast with one line per offending field:
$ opc-symlink suggest your-name suggestion.json
title: Required (empty after trimming)
proposedPatch: Required (must be an object)Example suggestion.json:
{
"type": "positioning",
"title": "Shifted positioning toward design-engineering",
"summary": "Reframe the headline and summary around design-engineering work.",
"affectedPaths": ["positioning.headline", "positioning.summary"],
"affectedSections": ["positioning"],
"proposedPatch": {
"positioning": {
"headline": "Design engineer for developer tools",
"summary": "I build fast, accessible product surfaces."
}
}
}To update the Current Work section, always use current-work suggest — it
prefills type: 'current_work', the currentWork paths, and the patch shape
for you. Use suggest for everything else.
The CLI only checks the fields above. Deeper patch semantics (for example a dot-path that does not exist in your profile) are detected server-side and reported in the returned error text — no local mirror of that layer exists.
Authentication boundaries
CLI commands authenticate with the device-flow token stored by
opc-symlink login. MCP clients use a separate API key
(Authorization: Bearer <api-key>); a CLI login token and an MCP API key are
not interchangeable.
search and profile use the same logged-in CLI access token as the other
commands. They search and read public profiles owned by other users, and are
available only with an active Plus subscription. Plus users get 10 searches
per UTC day, up to 10 search results per request, and 10 detailed profile
reads per UTC day. profile accepts up to 10 slugs in one command; the server
enforces the daily profile-read limit as well.
