@profile-as-code/cli 0.3.0 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,160 @@
1
+ # SOTA Ko-fi — research versionado (2026-10-05)
2
+
3
+ Research date: 2026-10-05 (UTC). Same date for every source (each URL fetched
4
+ 2026-10-05). Tags: `[OFICIAL]` = Ko-fi's own docs/pages (primary) · `[WEB]` =
5
+ primary URL fetched (incl. via mirror) · `[BENCHMARK]` = real-profile
6
+ observation · `[?]` = not calibratable / not documented.
7
+
8
+ Method / caveats: discovery ran through Ko-fi's own help-center search API
9
+ (`help.ko-fi.com/api/v2/help_center/articles/search.json`, en-US, all 120
10
+ articles) plus direct fetches. `ko-fi.com` and `help.ko-fi.com` pages are
11
+ Cloudflare-challenged for plain HTTP fetch (HTTP 403); public page content was
12
+ verified through a headless reader mirror (`r.jina.ai/<url>`) and marked
13
+ `[WEB]`. `developers.ko-fi.com` does not resolve (NXDOMAIN) — Ko-fi documents
14
+ webhooks, not a management API ([OFICIAL S18]).
15
+
16
+ ## 1. Bio/text fields on a Ko-fi creator page
17
+
18
+ | Field (official UI name) | Where it appears publicly | Limit | Source |
19
+ |---|---|---|---|
20
+ | Display name / creator page label — "Buy a Coffee for {Name}"; browser `<title>` = "Buy {Name} a Coffee" | Profile header card, first element under cover | [?] no documented limit found | [OFICIAL S2] [WEB S12] |
21
+ | Bio / About text — Ko-fi calls it "your bio" (onboarding step) and "bio text" (Content Guidelines §4); shown inside the **About** tab | First content block of the About tab, with a "Show more" collapse | [?] no documented limit found (search evidence below) | [OFICIAL S2, S8] |
22
+ | Creator **status** ("Set a status" next to profile picture) | On your Ko-fi page next to your name, at checkout, and in DMs | **40 characters max**, emoji supported | [OFICIAL S1] |
23
+ | **Social links** ("Your social links") | Rendered as icon anchors inside the **About** section of your profile | **Up to 15 links**; full `https://` URL required; recognized platforms get icons | [OFICIAL S3] |
24
+ | Cover image (not text, same hero zone) | Top of page | 3:1 ratio, ideally 1200×400 px, under 8 MB, JPEG/PNG; not GIF | [OFICIAL S5] |
25
+ | Social preview (OG) image + text ("Set your preview image and text") | Link preview on social platforms only, not the page itself | Image 2:1 or 600×300 px recommended; text customizable via "Customize preview"; auto-generated by default | [OFICIAL S4] |
26
+ | Membership **standard terms** (not bio) | Pre-signup terms | **10,000 characters max** — the only bio-area text field with a Ko-fi-documented limit found | [OFICIAL S16] |
27
+ | Tier Description / Welcome Message / Thank-you message (memberships & payments) | Tier card / post-payment surfaces, not on the public page | [?] | [OFICIAL S16, S10] |
28
+
29
+ "No documented limit found" evidence for bio/About: full-text searched the
30
+ whole help center (all 120 articles) for `page description`, `bio`,
31
+ `About you introduce yourself`, `About me section add text to page`,
32
+ `username change page name`; read in full: Get started (S2), Set your status
33
+ (S1), Setting up your social links (S3), Change your social preview (S4),
34
+ Cover image (S5), QR code (S6), Page Unpublished (S7), Content Guidelines
35
+ (S8), Creating posts (S14), Polls (S15), Webhooks/API (S18), How do I get
36
+ paid (S10), Memberships (S16). No article documents a character limit for the
37
+ bio/About field → treat as unbounded-but-unknown; hard-validate nothing,
38
+ soft-cap only. [?]
39
+
40
+ ## 2. Formatting of the About/bio text
41
+
42
+ - The WYSIWYG toolbar (styling, links, embeds, images) is documented for
43
+ **Posts** (feed/blog), not for the profile bio: "Use the toolbar to control
44
+ the styling of your text and layout, add links, embed videos and images". [OFICIAL S14]
45
+ - For the **bio/About card itself**: no documented markup support found (no
46
+ markdown/HTML mention in any read article) → write **plain text**. [?]
47
+ - On a live page (ko-fi.com/webby), the About text rendered as one plain-text
48
+ run; the email inside the bio was NOT rendered as a clickable anchor, while
49
+ the social links right below (bio page, X, YouTube, Twitch, TikTok) were
50
+ real anchors. Bio lines longer than a few lines collapse behind "Show
51
+ more". [BENCHMARK/WEB S12]
52
+ - **Links:** the official way to link out from the About zone is the
53
+ Social-links feature (up to 15, anchored with icons), not inline links in
54
+ the bio. Custom/unrecognized sites show a standard link icon; several
55
+ custom links drop into a dropdown. [OFICIAL S3]
56
+ - **Line breaks:** no official statement; on S12 the creator's bio was a
57
+ single run visually — assume breaks not guaranteed. [?]
58
+ - **Emoji:** explicitly supported in status ("Yes, you can add an emoji
59
+ alongside your custom status text"); Ko-fi copy itself uses emoji in bios
60
+ on marketing pages. [OFICIAL S1] — `[?]` for the bio field itself.
61
+
62
+ ## 3. URL / identity
63
+
64
+ - Canonical pattern: `https://ko-fi.com/<username>`, with subpaths `/tiers`,
65
+ `/shop`, `/commissions` (official list in S9; observed also `/gallery`,
66
+ `/posts`, `/goal`). Help pages use `ko-fi.com/<em>yourusername</em>`. [OFICIAL S9, S16]
67
+ - "Claim" language: Ko-fi's own copy — "claim your free page" (sign-up CTA);
68
+ the handle is chosen at claim time. [OFICIAL S10]
69
+ - Rename: "you can change your Ko-fi username any time, and your QR code will
70
+ still work and link to your page" [OFICIAL S6]. Observed consequence: old
71
+ handle paths keep resolving — one creator's page served identical content
72
+ at both ko-fi.com/webby and ko-fi.com/peterwebby (same profile id);
73
+ profiles are also internally addressable by opaque id. [WEB S12][BENCHMARK]
74
+ → **rename-drift risk**: a pasted bio/URL may carry a stale handle; always
75
+ verify which handle is live before pasting.
76
+ - Social preview can retain an old/dead name after rename (help labels it
77
+ "deadname"; fix = re-generate preview in Page settings). [OFICIAL S4]
78
+ - Privacy/unpublish: pages have **no documented self-service hide/unpublish
79
+ setting**. "Unpublished" = Ko-fi-side suspension (strikes/three-strike
80
+ system; Trust & Safety review). Page-level **NSFW tag** exists. [OFICIAL S7, S8]
81
+ - Host nuance: `kofi.com` (no hyphen) and `www.kofi.com` **do not resolve at
82
+ all** (DNS lookup `ENOTFOUND`, 2026-10-05). Only `ko-fi.com` serves pages —
83
+ identity URLs and handle checks must use the hyphenated host. [WEB S17]
84
+
85
+ ## 4. Visibility / SEO
86
+
87
+ - robots.txt: `User-agent: *` disallows only `/Administration/`, `/Manage/`,
88
+ `/api/`, `/design-system/`, `/streamalerts/overlay`(+animated/goaloverlay).
89
+ Creator pages `/<handle>` are **not disallowed** → crawlable by default.
90
+ [WEB S11]
91
+ - Public search/directory: `ko-fi.com/explore` renders the logged-out landing
92
+ (no browsable creator directory/search in that path); Ko-fi states post
93
+ tags "are not for searches now, but will be handy when we improve the tag
94
+ function". No public profile-search is documented in the help center. [WEB S13] [OFICIAL S14] [?]
95
+ - Documented discoverability: none beyond external promotion. Ko-fi actively
96
+ bans "mass SEO abuse (commercial spam)" pages. [OFICIAL S8]
97
+
98
+ ## 5. GEO (LLM citability) — observed on one real page [WEB]
99
+
100
+ - Fetched ko-fi.com/webby (and its duplicate at /peterwebby) through a
101
+ headless reader: `<title>` "Buy Peter Webby a Coffee"; tab nav **About |
102
+ Membership | Gallery | Posts | Shop**; an **"About"** section heading
103
+ containing the creator's bio text with a "Show more" collapse; social-link
104
+ anchors; tier cards. An LLM/agent with a JS-capable fetcher can read the
105
+ full About text as rendered HTML. [BENCHMARK/WEB S12]
106
+ - Caveat: the page is a client-side app; whether the raw no-JS HTML contains
107
+ the resolved About text **was not verified** (direct fetch Cloudflare-blocked
108
+ 403; server-side proxies failed) → [?]. The platform is Cloudflare-hostile
109
+ to plain HTTP fetchers; GEO checks should use a browser-rendered fetcher and
110
+ expect ~403 on raw requests. [WEB S12]
111
+
112
+ ## 6. Deploy (manual paste flow) — dashboard paths [OFICIAL unless noted]
113
+
114
+ - Account-level: **Settings** (sidebar) → **Profile** tab
115
+ (`ko-fi.com/settings?tab=profile`): display name + "Your social links"
116
+ (add/remove, Save). [OFICIAL S3]
117
+ - **Settings → Page** tab (`ko-fi.com/settings?tab=page`): "Set your preview
118
+ image and text" → "Customize preview"; **Page focus** dropdown (default
119
+ landing tab: Feed/Memberships/Shop/Commissions); custom color;
120
+ coffee-counter toggle. [OFICIAL S4, S16]
121
+ - Your page: **`ko-fi.com/manage/mypage`** → top-right three-dots → "Set
122
+ Cover Image"; About content lives on the page's **About** area ("Your
123
+ about page > Add Something" pattern per the Posts/Polls articles). [OFICIAL S5, S14, S15]
124
+ - Status: page → "Set a status" next to profile pic → text (≤40) + emoji +
125
+ "Clear after" → Save. [OFICIAL S1]
126
+ - Paste-checklist reference order: name → status → bio/About text → social
127
+ links → preview text/image → page focus → cover image.
128
+
129
+ ## 7. Short vs long bios
130
+
131
+ - The page loads half-way down the cover image "so that your visitors can get
132
+ straight to your main content" — the About text is on the default (About)
133
+ tab and truncated behind "Show more" when long. [OFICIAL S5] [WEB S12]
134
+ - The only guaranteed short-slot line is the **status** (≤40 chars) next to
135
+ the name (also at checkout and in DMs). [OFICIAL S1]
136
+ - Link shares are governed by the customizable social preview text/image,
137
+ independent of the About text. [OFICIAL S4]
138
+ - No documented per-field limit for About → the engine treats About as
139
+ unbounded, with renderer/skill-side soft caps. [?]
140
+
141
+ ## Sources (all fetched 2026-10-05 UTC)
142
+
143
+ - S1 https://help.ko-fi.com/hc/en-us/articles/39075030682269-Set-your-status (API: help.ko-fi.com/api/v2/help_center/en-us/articles/39075030682269.json)
144
+ - S2 https://help.ko-fi.com/hc/en-us/articles/360014098514-Getting-started-on-Ko-fi
145
+ - S3 https://help.ko-fi.com/hc/en-us/articles/32432965286557-Setting-up-your-social-links
146
+ - S4 https://help.ko-fi.com/hc/en-us/articles/360020081893-Change-your-social-preview-image-and-text
147
+ - S5 https://help.ko-fi.com/hc/en-us/articles/360004243378-Make-your-page-stand-out-with-a-cover-image
148
+ - S6 https://help.ko-fi.com/hc/en-us/articles/28740826348701-Your-Ko-fi-QR-code
149
+ - S7 https://help.ko-fi.com/hc/en-us/articles/360010484497-What-does-Page-Unpublished-mean-and-what-should-I-do
150
+ - S8 https://help.ko-fi.com/hc/en-us/articles/360007937553-Ko-fi-Content-Guidelines (unpublish/ban, "bio text", SEO abuse, NSFW tag)
151
+ - S9 https://help.ko-fi.com/hc/en-us/articles/115004002614-Adding-a-Ko-fi-Button-to-your-WordPress-site-or-blog (URL patterns)
152
+ - S10 https://help.ko-fi.com/hc/en-us/articles/115003980093-How-do-I-get-paid ("claim your free page")
153
+ - S11 https://ko-fi.com/robots.txt
154
+ - S12 https://ko-fi.com/webby and https://ko-fi.com/peterwebby (fetched via r.jina.ai mirror; direct fetch HTTP 403)
155
+ - S13 https://ko-fi.com/explore and https://ko-fi.com/FAQ (via r.jina.ai mirror)
156
+ - S14 https://help.ko-fi.com/hc/en-us/articles/360007638073 (Creating posts; WYSIWYG toolbar; "tags… not for searches now")
157
+ - S15 https://help.ko-fi.com/hc/en-us/articles/19068973151133-Create-a-Poll-on-Ko-fi ("Your about page > Add Something")
158
+ - S16 https://help.ko-fi.com/hc/en-us/articles/4402945994001-Ko-fi-Memberships-and-Membership-Tiers (terms 10,000 chars; tier Description/Welcome Message; Settings > Page)
159
+ - S17 DNS checks: `kofi.com`, `www.kofi.com`, `developers.ko-fi.com` → getaddrinfo ENOTFOUND (fetch attempts 2026-10-05)
160
+ - S18 https://help.ko-fi.com/hc/en-us/articles/360004162298-Does-Ko-fi-have-an-API-or-webhook (webhooks = payments only; manage at ko-fi.com/manage/webhooks)
@@ -0,0 +1,50 @@
1
+ # LinkedIn post — skill (MVP)
2
+
3
+ > Week-1 post skill. The machine-readable limits live in `posting.yaml`; this file
4
+ > is the judgment layer the agent reads before writing. Sources are dated in
5
+ > `posting.yaml`; re-verify before making a hard claim.
6
+
7
+ ## What a LinkedIn post is for
8
+
9
+ One idea, one reader, one reason to keep reading. The post is not a profile
10
+ summary: it is a claim or a story that earns the next line. Write for a specific
11
+ audience from `positioning.audiences`; do not write for "everyone".
12
+
13
+ ## Shape
14
+
15
+ 1. **Hook** — the first 1–2 lines carry the whole post. A concrete tension,
16
+ observation or result; no throat-clearing ("En el mundo de…").
17
+ 2. **Body** — 2–5 short paragraphs. One idea per paragraph. Concrete nouns,
18
+ dates, numbers, links from the SSOT. Use `{{fact:...}}` for every fact.
19
+ 3. **Close** — a question, an invitation or a next step. No rage-bait, no
20
+ "comenta SÍ" engagement farming.
21
+
22
+ ## Rules
23
+
24
+ - **Length:** 3,000 characters max (LinkedIn's current limit; see
25
+ `posting.yaml` sources). Aim for 900–1,800 — the ceiling is not the target.
26
+ - **Links:** only from `identity.links`, `projects[].links`,
27
+ `publications[].url`, `credentials[].verifyUrl` or `artifacts[].locator.url`.
28
+ Do not invent or shorten a URL.
29
+ - **Hashtags:** 3–5 maximum, only if they are how the audience searches.
30
+ - **Facts:** never paraphrase a date, number, DOI or URL. Cite with
31
+ `{{fact:<pointer>}}`; the engine renders it and fails on a dangling pointer.
32
+ - **Voice:** first person, direct, no hype. Match `brandVoice` (tone, values,
33
+ avoid); the post should sound like the person, not like a content template.
34
+
35
+ ## Anti-patterns
36
+
37
+ - A hook that could belong to any post in the niche.
38
+ - A list of achievements without a claim.
39
+ - "I'm humbled to announce" / "Excited to share" openings.
40
+ - A link dump; a post is not a newsletter.
41
+ - Hashtag stuffing.
42
+
43
+ ## Output contract
44
+
45
+ Save one text block per variant at `posts/<seed>/linkedin/linkedin-<n>.md`, then
46
+ record it:
47
+
48
+ ```
49
+ pasco post choose <seed> --channel linkedin --variant linkedin-1
50
+ ```
@@ -0,0 +1,23 @@
1
+ # linkedin post rules — machine-readable (MVP)
2
+ #
3
+ # The `post check` command reads limits/settings/hashtags from here. The prose
4
+ # strategy lives in post.md; this file is the contract. Re-verify the source
5
+ # before changing a hard limit.
6
+
7
+ platform: linkedin
8
+ settings:
9
+ __type: linkedin
10
+ limits:
11
+ maxChars: 3000
12
+ links:
13
+ policy: identity-ssot-only
14
+ hashtags:
15
+ max: 5
16
+ structure:
17
+ - hook
18
+ - body
19
+ - close
20
+ sources:
21
+ - url: https://www.linkedin.com/help/linkedin/answer/a528565
22
+ date: 2026-10-20
23
+ note: "LinkedIn post character limit (3,000); re-verify, the platform changes limits."
@@ -0,0 +1,46 @@
1
+ # X post — skill (MVP)
2
+
3
+ > Week-1 post skill. The machine-readable limits live in `posting.yaml`; this file
4
+ > is the judgment layer the agent reads before writing. Sources are dated in
5
+ > `posting.yaml`; re-verify before making a hard claim.
6
+
7
+ ## What an X post is for
8
+
9
+ One sharp claim, observation or link. X rewards the first line and punishes
10
+ context-free threads. The post is a projection of the seed, not a summary of the
11
+ profile.
12
+
13
+ ## Shape
14
+
15
+ 1. **Hook** — one line, concrete, no "🧵" unless the thread is real.
16
+ 2. **Body** — 1–2 short lines. One idea. If it does not fit, the seed is a
17
+ thread, not a post; the MVP writes single posts, so cut.
18
+ 3. **Close** — optional link or question; do not bait replies.
19
+
20
+ ## Rules
21
+
22
+ - **Length:** 280 characters for standard accounts (see `posting.yaml` sources;
23
+ verified/premium accounts have a different ceiling — do not assume).
24
+ - **Links:** only from the SSOT. X may shorten visually; the URL you write must
25
+ be the canonical one.
26
+ - **Hashtags:** 0–3, only if they are how the audience searches. No stuffing.
27
+ - **Mentions:** only handles that are real and relevant; do not invent or
28
+ mass-mention.
29
+ - **Facts:** cite with `{{fact:<pointer>}}`; never invent a number, date or URL.
30
+ - **Voice:** first person, direct, no hype. Match `brandVoice`; the post should
31
+ sound like the person, not like a growth account.
32
+
33
+ ## Anti-patterns
34
+
35
+ - "A thread 🧵" on a single post.
36
+ - Engagement bait ("like if you agree").
37
+ - A link with no claim.
38
+ - Hashtag stuffing; emoji spam.
39
+
40
+ ## Output contract
41
+
42
+ Save one text block per variant at `posts/<seed>/x/x-<n>.md`, then record it:
43
+
44
+ ```
45
+ pasco post choose <seed> --channel x --variant x-1
46
+ ```
@@ -0,0 +1,24 @@
1
+ # x post rules — machine-readable (MVP)
2
+ #
3
+ # The `post check` command reads limits/settings/hashtags from here. The prose
4
+ # strategy lives in post.md; this file is the contract. Re-verify the source
5
+ # before changing a hard limit.
6
+
7
+ platform: x
8
+ settings:
9
+ __type: x
10
+ who_can_reply_post: everyone
11
+ limits:
12
+ maxChars: 280
13
+ links:
14
+ policy: identity-ssot-only
15
+ hashtags:
16
+ max: 3
17
+ structure:
18
+ - hook
19
+ - body
20
+ - close
21
+ sources:
22
+ - url: https://developer.x.com/en/docs/x-api/v2/tweets/create-post
23
+ date: 2026-10-20
24
+ note: "X post character limit (280 for standard accounts; verified/premium differ)."