ops-social-plannerlisted
Install: claude install-skill Lifecycle-Innovations-Limited/claude-ops
# /ops-social-planner — engine-agnostic planned-content viewer
Read-only dashboard of **every** scheduled post and ad, grouped **identity/project → channel → time**,
**regardless of posting engine**. Personal/founder identity and project brands stay strictly separated
(see `/ops-socials` identity rules). See `SPEC.md` for the full design.
## What it does
1. `bin/ops-social-planner collect` reads `$PREFS_PATH/preferences.json`
(`marketing.social_identities.personal.*` + `marketing.projects.*.social`), dispatches a
**per-engine fetcher** keyed on `social.engine.primary`, normalizes to one schema, and writes
`$OPS_DATA_DIR/social-planner/state.json` (**owner data — never committed**, Rule 0).
2. It then serves the static UI (`ui/`) on localhost and opens the browser.
## Engines
| `engine.primary` | Source | Status |
|---|---|---|
| `typefully` | `GET /v2/social-sets/{id}/drafts` (Bearer; key from `~/.config/typefully/config.json`) | ✅ wired |
| `upload-post` | `GET /api/uploadposts/schedule` (Apikey; key from `engine.upload_post.api_key_ref`) | ✅ wired |
| `meta-graph` / `meta-ads` | Graph Ads API per project BM/token | 🔌 hook (UI shows "pending") |
| `google-ads` | GAQL per project customer id | 🔌 hook |
| `null` / unprovisioned | — | shown fail-closed (0 items) |
Adding an engine = adding one `fetch<Engine>()` in `bin/ops-social-planner` + a dispatch branch. No UI change.
## Run it
```bash
"${CLAUDE_PLUGIN_ROOT}/bin/ops-social-planner" # collect