[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6K5CTFQC1VZ5MW9CVNA6DN5":3,"skill-same:01M6K5CTFQC1VZ5MW9CVNA6DN5":66},{"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":36,"linkOnly":37,"markdownContent":38,"markdownBody":39,"frontMatter":40,"refName":44,"commitSha":45,"skillDirectory":46,"forksCount":47,"repositoryHtmlUrl":48,"repositoryHomepageUrl":49,"ownerHtmlUrl":50,"ownerBlogUrl":49,"ownerDescription":51,"updatedAt":52,"install":53,"resources":65},"01M6K5CTFQC1VZ5MW9CVNA6DN5","ingest-performance",null,"Turn a platform analytics export into per-post performance records and ranked winners. \"which of last month's posts worked\"","indranilbanerjee\u002Fsocialforge","indranilbanerjee","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1857369?v=4","01M6K5AJ210R87KXT6WF07RC4T","Indranil Banerjee","01M6K5AJ6FXW6Y1CDESBGX191P",43,"MIT","https:\u002F\u002Fgithub.com\u002Findranilbanerjee\u002Fsocialforge\u002Fblob\u002Fmain\u002Fskills\u002Fingest-performance\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35],"ingest performance","ingest","performance","records","source","which","true","last","posts","mm","post","name","platform","export","brand","csv","analytics","2026-11-10 10:12:30",false,"---\nname: ingest-performance\ndescription: \"Turn a platform analytics export into per-post performance records and ranked winners. \\\"which of last month's posts worked\\\"\"\nargument-hint: \"--brand \u003Cname> --month \u003CYYYY-MM> [--csv \u003Cexport.csv>] [--source \u003Clabel>] [--replace]\"\neffort: medium\nuser-invocable: true\n---\n\n# \u002Fsocialforge:ingest-performance — real numbers into the wins rung\n\n> **Script location.** If your host does not set `${CLAUDE_PLUGIN_ROOT}`, the scripts are in this plugin's `scripts\u002F` folder, next to `skills\u002F`. Run them with Python 3.10 or newer: `python`, or `python3` where `python` is not found (macOS, many Linux systems).\n\n`\u002Fsocialforge:ideate-month` compounds \"what worked last month.\" Before this\nskill, that meant whatever someone remembered in the planning call — and\nmemory favors the post that felt good, not the one that performed. This skill\nturns the platform's own export into the record ideation reads.\n\n## Step 1 — Get the export\n\nAsk the user for the analytics export covering the month. Any CSV works if it\nhas a column identifying the post (`post_id`, `post`, `id`) that matches the\ncalendar's post ids, plus whichever metrics the platform provides\n(impressions\u002Fviews, likes\u002Freactions, comments, shares\u002Freposts, saves, clicks,\nfollows — header aliases are normalized automatically). If the export keys\nposts by URL or caption instead of the calendar id, help the user add a\n`post_id` column first — matching is by calendar id, deliberately: wins must\nmap back to the topics and pillars that produced them.\n\n## Step 2 — Ingest\n\n```bash\npython \"${CLAUDE_PLUGIN_ROOT}\u002Fscripts\u002Fingest_performance.py\" --action ingest \\\n    --brand {brand} --month {YYYY-MM} --csv {export.csv} --source \"{platform} export\"\n```\n\n- Rows matching calendar post ids are stored in\n  `output\u002F{brand}\u002F{month}\u002Fperformance.json`, each row tagged with its source\n  label, and each source records the sha256 of its CSV. Different files append —\n  one CSV per platform is normal.\n- **The same file twice is a no-op.** Identical bytes answer\n  `\"status\": \"already_ingested\"` (exit 0) and name the earlier source; nothing\n  is added. That is not an error — report \"no new export\".\n- **Cumulative exports use `--replace`.** If the platform's new file repeats\n  the posts of last week's (month-to-date totals), ingest every snapshot under\n  one constant `--source` label with `--replace`: rows previously ingested under\n  that label are removed first, so only the latest snapshot counts. Other\n  labels are untouched. Ingest only the **newest** export under `--replace`: it\n  trusts the file it is given, so an older file ingested after a newer one\n  replaces the newer numbers. `--replace` refuses a label ingested before rows\n  carried their source label (use a new label or re-ingest the month), and a\n  file that matches no calendar post leaves the old snapshot in place.\n- **Unmatched rows are listed in the output, never silently dropped.** Show\n  the user the unmatched list; a typo'd id is data lost from the wins rung.\n- Exit 3 = nothing matched. Stop and reconcile ids before proceeding.\n\n## Step 3 — Rank the wins\n\n```bash\npython \"${CLAUDE_PLUGIN_ROOT}\u002Fscripts\u002Fingest_performance.py\" --action wins \\\n    --brand {brand} --month {YYYY-MM}\n```\n\nThe ranking is deliberately conservative:\n\n- **Sample floor** (default 100 impressions): a post nobody saw cannot be a\n  win, only noise. Below-floor posts are reported as `unranked` with the reason.\n- **Margin rule** (default 1.5× the month's median engagement rate): a \"win\"\n  must beat the month, not merely top a flat list.\n- **Unmeasured is not zero**: missing impressions → `engagement_rate: null`,\n  and the post lands in `unranked`, not at the bottom of the ranking.\n- A flat month returns `\"status\": \"no_clear_wins\"` — report that honestly.\n  Compounding a non-win manufactures a false signal for next month's plan.\n\n## Step 4 — Hand off to ideation\n\nRelay the wins output to `\u002Fsocialforge:ideate-month` (its \"last month's\nresults\" input). Winners carry their topic, pillar, tier, and\n`vs_month_median` multiple, so ideation can design follow-ups that compound\nthe validated angle — and label each one `measured` in \"What last month\nvalidated\". Anything the client reports that is NOT in the ranked output is\nstill usable, labeled `anecdotal`.\n\n## Pairs with\n\n- `\u002Fsocialforge:ideate-month` — consumes the wins output; measured beats remembered\n- `\u002Fsocialforge:finalize-month` — closing a month is the natural moment to ingest its numbers\n","# \u002Fsocialforge:ingest-performance — real numbers into the wins rung\n\n> **Script location.** If your host does not set `${CLAUDE_PLUGIN_ROOT}`, the scripts are in this plugin's `scripts\u002F` folder, next to `skills\u002F`. Run them with Python 3.10 or newer: `python`, or `python3` where `python` is not found (macOS, many Linux systems).\n\n`\u002Fsocialforge:ideate-month` compounds \"what worked last month.\" Before this\nskill, that meant whatever someone remembered in the planning call — and\nmemory favors the post that felt good, not the one that performed. This skill\nturns the platform's own export into the record ideation reads.\n\n## Step 1 — Get the export\n\nAsk the user for the analytics export covering the month. Any CSV works if it\nhas a column identifying the post (`post_id`, `post`, `id`) that matches the\ncalendar's post ids, plus whichever metrics the platform provides\n(impressions\u002Fviews, likes\u002Freactions, comments, shares\u002Freposts, saves, clicks,\nfollows — header aliases are normalized automatically). If the export keys\nposts by URL or caption instead of the calendar id, help the user add a\n`post_id` column first — matching is by calendar id, deliberately: wins must\nmap back to the topics and pillars that produced them.\n\n## Step 2 — Ingest\n\n```bash\npython \"${CLAUDE_PLUGIN_ROOT}\u002Fscripts\u002Fingest_performance.py\" --action ingest \\\n    --brand {brand} --month {YYYY-MM} --csv {export.csv} --source \"{platform} export\"\n```\n\n- Rows matching calendar post ids are stored in\n  `output\u002F{brand}\u002F{month}\u002Fperformance.json`, each row tagged with its source\n  label, and each source records the sha256 of its CSV. Different files append —\n  one CSV per platform is normal.\n- **The same file twice is a no-op.** Identical bytes answer\n  `\"status\": \"already_ingested\"` (exit 0) and name the earlier source; nothing\n  is added. That is not an error — report \"no new export\".\n- **Cumulative exports use `--replace`.** If the platform's new file repeats\n  the posts of last week's (month-to-date totals), ingest every snapshot under\n  one constant `--source` label with `--replace`: rows previously ingested under\n  that label are removed first, so only the latest snapshot counts. Other\n  labels are untouched. Ingest only the **newest** export under `--replace`: it\n  trusts the file it is given, so an older file ingested after a newer one\n  replaces the newer numbers. `--replace` refuses a label ingested before rows\n  carried their source label (use a new label or re-ingest the month), and a\n  file that matches no calendar post leaves the old snapshot in place.\n- **Unmatched rows are listed in the output, never silently dropped.** Show\n  the user the unmatched list; a typo'd id is data lost from the wins rung.\n- Exit 3 = nothing matched. Stop and reconcile ids before proceeding.\n\n## Step 3 — Rank the wins\n\n```bash\npython \"${CLAUDE_PLUGIN_ROOT}\u002Fscripts\u002Fingest_performance.py\" --action wins \\\n    --brand {brand} --month {YYYY-MM}\n```\n\nThe ranking is deliberately conservative:\n\n- **Sample floor** (default 100 impressions): a post nobody saw cannot be a\n  win, only noise. Below-floor posts are reported as `unranked` with the reason.\n- **Margin rule** (default 1.5× the month's median engagement rate): a \"win\"\n  must beat the month, not merely top a flat list.\n- **Unmeasured is not zero**: missing impressions → `engagement_rate: null`,\n  and the post lands in `unranked`, not at the bottom of the ranking.\n- A flat month returns `\"status\": \"no_clear_wins\"` — report that honestly.\n  Compounding a non-win manufactures a false signal for next month's plan.\n\n## Step 4 — Hand off to ideation\n\nRelay the wins output to `\u002Fsocialforge:ideate-month` (its \"last month's\nresults\" input). Winners carry their topic, pillar, tier, and\n`vs_month_median` multiple, so ideation can design follow-ups that compound\nthe validated angle — and label each one `measured` in \"What last month\nvalidated\". Anything the client reports that is NOT in the ranked output is\nstill usable, labeled `anecdotal`.\n\n## Pairs with\n\n- `\u002Fsocialforge:ideate-month` — consumes the wins output; measured beats remembered\n- `\u002Fsocialforge:finalize-month` — closing a month is the natural moment to ingest its numbers\n",{"name":5,"effort":41,"description":7,"argument-hint":42,"user-invocable":43},"medium","--brand \u003Cname> --month \u003CYYYY-MM> [--csv \u003Cexport.csv>] [--source \u003Clabel>] [--replace]",true,"main","552dba358f148de8439795c5e8becb57f9943ec8","skills\u002Fingest-performance",9,"https:\u002F\u002Fgithub.com\u002Findranilbanerjee\u002Fsocialforge","https:\u002F\u002Findranil.in","https:\u002F\u002Fgithub.com\u002Findranilbanerjee","Builder across trustworthy AI, agentic systems, and marketing engineering. Security roots; focused on human capability amplified by software.","2026-11-08 01:03:55",{"source":8,"skillName":5,"commands":54,"prompt":64,"zipAvailable":43},[55,58,61],{"tool":56,"command":57},"npx","npx skills add indranilbanerjee\u002Fsocialforge --skill ingest-performance",{"tool":59,"command":60},"bunx","bunx skills add indranilbanerjee\u002Fsocialforge --skill ingest-performance",{"tool":62,"command":63},"pnpm","pnpm dlx skills add indranilbanerjee\u002Fsocialforge --skill ingest-performance","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Findranilbanerjee\u002Fsocialforge\u002Fblob\u002Fmain\u002Fskills\u002Fingest-performance\u002FSKILL.md",[],[67,96,115,139,157,187],{"skillNo":68,"name":69,"nameZh":6,"description":70,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":71,"categories":72,"keywords":78,"publishedAt":36},"01M6K5E21QEYHCT7Z2HA4AQ804","setup","One-time setup of image and video generation credentials, verified before use. \"set up my API keys\"","https:\u002F\u002Fgithub.com\u002Findranilbanerjee\u002Fsocialforge\u002Fblob\u002Fmain\u002Fskills\u002Fsetup\u002FSKILL.md",[73],{"categoryNo":74,"categoryName":75,"taxonomyType":76,"taxonomyTypeDesc":77},"01JBSEEDCAT000000000000016","图像与多媒体","SCENARIO","使用场景",[69,79,80,81,82,83,25,84,85,86,87,88,89,90,91,92,93,94,95],"video generation","api keys","verified","keys","my","reset","generation","time","fallback","up","use","Video","api","credentials","SET","status","image",{"skillNo":97,"name":98,"nameZh":6,"description":99,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":105,"publishedAt":36},"01M6K5DWRWPF1ZHZ93VE8Z1NB4","research-month","Turn supplied comment exports and competitor ads into a what's-working brief before planning a month. \"analyse these competitor ads and comments\"","https:\u002F\u002Fgithub.com\u002Findranilbanerjee\u002Fsocialforge\u002Fblob\u002Fmain\u002Fskills\u002Fresearch-month\u002FSKILL.md",[102],{"categoryNo":103,"categoryName":104,"taxonomyType":76,"taxonomyTypeDesc":77},"01JBSEEDCAT000000000000021","资料检索与研究",[106,107,34,32,33,108,109,110,111,112,113,30,114,25,27,28],"research month","research","text","ads","brief","planning","screenshots","comments","high",{"skillNo":116,"name":117,"nameZh":6,"description":118,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":119,"categories":120,"keywords":124,"publishedAt":36},"01M6K5DQ47966ZG9N916VA7Y68","render-carousels","Render multi-slide carousels from HTML templates into platform-ready images or PDF. \"build the carousel slides\"","https:\u002F\u002Fgithub.com\u002Findranilbanerjee\u002Fsocialforge\u002Fblob\u002Fmain\u002Fskills\u002Frender-carousels\u002FSKILL.md",[121],{"categoryNo":122,"categoryName":123,"taxonomyType":76,"taxonomyTypeDesc":77},"01JBSEEDCAT000000000000002","文档处理",[125,126,31,127,128,129,29,130,114,25,131,132,133,134,135,136,137,138],"render carousels","render","type","id","carousel","multi","template","images","ready","html","slides","templates","PDF","build",{"skillNo":140,"name":141,"nameZh":6,"description":142,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":143,"categories":144,"keywords":145,"publishedAt":36},"01M6K5DHDFMZAK4BN2QFEVM614","price-check","Price a generation run from live provider rates before any spend. \"how much will this cost\"","https:\u002F\u002Fgithub.com\u002Findranilbanerjee\u002Fsocialforge\u002Fblob\u002Fmain\u002Fskills\u002Fprice-check\u002FSKILL.md",[],[146,147,148,149,25,150,30,128,85,151,152,153,154,155,156],"check","price","price check","live","compare","provider","cost","model","how","batch","run",{"skillNo":158,"name":159,"nameZh":6,"description":160,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":161,"categories":162,"keywords":172,"publishedAt":36},"01M6K5DDGBCGTN4SBEHZD5G9H8","parse-calendar","Parse a content calendar or plan from DOCX, XLSX, Notion or pasted text into structured posts. \"load this month's calendar\"","https:\u002F\u002Fgithub.com\u002Findranilbanerjee\u002Fsocialforge\u002Fblob\u002Fmain\u002Fskills\u002Fparse-calendar\u002FSKILL.md",[163,164,167],{"categoryNo":122,"categoryName":123,"taxonomyType":76,"taxonomyTypeDesc":77},{"categoryNo":165,"categoryName":166,"taxonomyType":76,"taxonomyTypeDesc":77},"01JBSEEDCAT000000000000004","电子表格",{"categoryNo":168,"categoryName":169,"taxonomyType":170,"taxonomyTypeDesc":171},"01JBSEEDCAT000000000000034","行政与办公人员","PROFESSION","适用职业",[173,174,27,175,176,177,108,178,179,180,181,182,183,184,185,186,25],"parse calendar","calendar","URL","structured","content calendar","plan","file","content","notion","xlsx","docx","paste","path","load",{"skillNo":188,"name":189,"nameZh":6,"description":190,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":191,"categories":192,"keywords":193,"publishedAt":36},"01M6K5D9NZ6QEP1F5M9P8EXM7E","model-check","Find the best current model for a capability from the live catalogue and record its source. \"which model should we use\"","https:\u002F\u002Fgithub.com\u002Findranilbanerjee\u002Fsocialforge\u002Fblob\u002Fmain\u002Fskills\u002Fmodel-check\u002FSKILL.md",[],[194,153,146,23,195,24,25,196,30,149,197,151,89,198],"model check","for","kind","record","find"]