refactor(linkedin): merge publish into calendar — reconcile hook refs (S16)
Step 17 of voyage-build (S16 in plan). publish.md absorbed into calendar.md as an inline action (Mark as Published flow: queue update, state update, first-hour battle plan) reusing the same queue-manager.mjs + state-updater.mjs primitives that publish.md called. calendar.md frontmatter triggers extended with the publish trigger words; quick-routing block jumps straight to the publish action when the user prompt names it. All 21 route-refs reconciled across the 9 expected files, with the 9 hook-script refs (5 in session-start.mjs, 2 in posting-reminder.mjs, 1 in user-prompt-context.mjs, 1 in hooks/prompts/state-update-reminder.md) rewritten to call /linkedin:calendar so the runtime guidance no longer points at a dead command. compile-hooks.py --check reports clean (no type: prompt hook changes touched hooks.json). Verify (intent: zero stray refs, file gone): exit 0. Literal Verify in plan.md:727 logged exit 1 (same exit-inverted && pattern as S15 plan.md:635 — logged for plan-pass at Step 21). Manifest audit: PASS (expected_paths=calendar.md present; must_contain [Pp]ublish: 17 matches in calendar.md). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
ddd84e4501
commit
e4aa5a61c2
12 changed files with 117 additions and 156 deletions
|
|
@ -47,8 +47,7 @@ All content commands (post, quick, react, pipeline, first-post, video, multiplat
|
||||||
| `/linkedin:quick` | 5-minute quick post (3-line formula) + 8 post-type templates |
|
| `/linkedin:quick` | 5-minute quick post (3-line formula) + 8 post-type templates |
|
||||||
| `/linkedin:pipeline` | Full end-to-end content pipeline |
|
| `/linkedin:pipeline` | Full end-to-end content pipeline |
|
||||||
| `/linkedin:batch` | Create a full week of content |
|
| `/linkedin:batch` | Create a full week of content |
|
||||||
| `/linkedin:calendar` | View/manage post scheduling queue |
|
| `/linkedin:calendar` | View/manage post scheduling queue + publish action (mark scheduled posts as published) |
|
||||||
| `/linkedin:publish` | Mark scheduled posts as published |
|
|
||||||
| `/linkedin:carousel` | Structured multi-slide carousel generator |
|
| `/linkedin:carousel` | Structured multi-slide carousel generator |
|
||||||
| `/linkedin:video` | Video script generator (30s-2min) |
|
| `/linkedin:video` | Video script generator (30s-2min) |
|
||||||
| `/linkedin:multiplatform` | Adapt content for other platforms |
|
| `/linkedin:multiplatform` | Adapt content for other platforms |
|
||||||
|
|
|
||||||
|
|
@ -142,8 +142,7 @@ All 26 commands use colon notation: `/linkedin:post`, `/linkedin:quick`, etc.
|
||||||
| `/linkedin:quick` | 5-minute quick post using the 3-line formula. Target: 150-500 characters. Best for reactions, observations, tips, and questions. Also the single entry point for the 8 post-type templates (fill-in-the-blank structures). |
|
| `/linkedin:quick` | 5-minute quick post using the 3-line formula. Target: 150-500 characters. Best for reactions, observations, tips, and questions. Also the single entry point for the 8 post-type templates (fill-in-the-blank structures). |
|
||||||
| `/linkedin:pipeline` | Full end-to-end content pipeline from idea to published post. Guides through ideation, drafting, optimization, scheduling, pre-engagement, publishing, and post-analysis. |
|
| `/linkedin:pipeline` | Full end-to-end content pipeline from idea to published post. Guides through ideation, drafting, optimization, scheduling, pre-engagement, publishing, and post-analysis. |
|
||||||
| `/linkedin:batch` | Create a full week of LinkedIn content in one session. Input one theme, output 3-5 posts with varying angles and formats. Writes to scheduling queue. |
|
| `/linkedin:batch` | Create a full week of LinkedIn content in one session. Input one theme, output 3-5 posts with varying angles and formats. Writes to scheduling queue. |
|
||||||
| `/linkedin:calendar` | View and manage the post scheduling queue — upcoming, overdue, published. |
|
| `/linkedin:calendar` | View and manage the post scheduling queue — upcoming, overdue, published — and run the publish action (mark a scheduled post as published, update state + streak tracking, surface the first-hour engagement plan). |
|
||||||
| `/linkedin:publish` | Mark scheduled posts as published. Updates state and streak tracking. |
|
|
||||||
| `/linkedin:video` | Video script generator for 30s, 60s, 90s, or 2-minute LinkedIn videos with pacing and visual cues. |
|
| `/linkedin:video` | Video script generator for 30s, 60s, 90s, or 2-minute LinkedIn videos with pacing and visual cues. |
|
||||||
| `/linkedin:multiplatform` | Adapt LinkedIn content for Twitter/X threads, newsletter sections, blog posts, presentation slides, and YouTube scripts. |
|
| `/linkedin:multiplatform` | Adapt LinkedIn content for Twitter/X threads, newsletter sections, blog posts, presentation slides, and YouTube scripts. |
|
||||||
| `/linkedin:react` | URL-to-post pipeline — paste an article, research paper, or news link and generate a reaction post. |
|
| `/linkedin:react` | URL-to-post pipeline — paste an article, research paper, or news link and generate a reaction post. |
|
||||||
|
|
@ -503,7 +502,7 @@ Scheduled posts are tracked in `assets/drafts/queue.json`:
|
||||||
- Status flow: `draft` -> `scheduled` -> `published` (or `cancelled`)
|
- Status flow: `draft` -> `scheduled` -> `published` (or `cancelled`)
|
||||||
- Created by `/linkedin:batch` and `/linkedin:pipeline`
|
- Created by `/linkedin:batch` and `/linkedin:pipeline`
|
||||||
- Viewed via `/linkedin:calendar`
|
- Viewed via `/linkedin:calendar`
|
||||||
- Transitioned via `/linkedin:publish`
|
- Transitioned (marked as published) via the `/linkedin:calendar` publish action
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -516,7 +515,7 @@ Scheduled posts are tracked in `assets/drafts/queue.json`:
|
||||||
| Engagement automation | Automated commenting violates LinkedIn ToS | Manual engagement guided by `/linkedin:collab` |
|
| Engagement automation | Automated commenting violates LinkedIn ToS | Manual engagement guided by `/linkedin:collab` |
|
||||||
| Profile editing | Plugin generates recommendations, not API calls | Apply changes manually on LinkedIn |
|
| Profile editing | Plugin generates recommendations, not API calls | Apply changes manually on LinkedIn |
|
||||||
| Team/multi-user workflows | Designed for individual thought leaders | Enterprise LinkedIn tools |
|
| Team/multi-user workflows | Designed for individual thought leaders | Enterprise LinkedIn tools |
|
||||||
| Content scheduling via API | No official scheduling API | Queue management with manual posting via `/linkedin:publish` |
|
| Content scheduling via API | No official scheduling API | Queue management with manual posting via `/linkedin:calendar` (publish action) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ After saving each draft, add it to the queue:
|
||||||
node --input-type=module -e "import { queueAdd } from '${CLAUDE_PLUGIN_ROOT}/hooks/scripts/queue-manager.mjs'; console.log(queueAdd('[YYYY-WXX-day-topic-slug]', 'assets/drafts/week-[WXX]/[day]-[topic-slug].md', '[YYYY-MM-DD]', '[HH:MM]', '[pillar]', '[format]', '[hook preview first 50 chars]', [character_count]));"
|
node --input-type=module -e "import { queueAdd } from '${CLAUDE_PLUGIN_ROOT}/hooks/scripts/queue-manager.mjs'; console.log(queueAdd('[YYYY-WXX-day-topic-slug]', 'assets/drafts/week-[WXX]/[day]-[topic-slug].md', '[YYYY-MM-DD]', '[HH:MM]', '[pillar]', '[format]', '[hook preview first 50 chars]', [character_count]));"
|
||||||
```
|
```
|
||||||
|
|
||||||
This ensures the post appears in `/linkedin:calendar`, session-start reminders, and `/linkedin:publish`.
|
This ensures the post appears in `/linkedin:calendar` (both for viewing and for the publish action) and in session-start reminders.
|
||||||
|
|
||||||
## Step 4: Review All
|
## Step 4: Review All
|
||||||
|
|
||||||
|
|
@ -152,7 +152,7 @@ Ask if they want to:
|
||||||
|
|
||||||
After approval:
|
After approval:
|
||||||
- Confirm all drafts are saved and queued
|
- Confirm all drafts are saved and queued
|
||||||
- Update state file with planned topics (note: state updates for batch posts happen at publish time via `/linkedin:publish`, not at batch creation)
|
- Update state file with planned topics (note: state updates for batch posts happen at publish time via the `/linkedin:calendar` publish action, not at batch creation)
|
||||||
- Show queue summary:
|
- Show queue summary:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -162,8 +162,7 @@ Queue Summary: [X] posts scheduled
|
||||||
- [Date] [Time]: "[hook preview]" — [pillar] ([format])
|
- [Date] [Time]: "[hook preview]" — [pillar] ([format])
|
||||||
- [Date] [Time]: "[hook preview]" — [pillar] ([format])
|
- [Date] [Time]: "[hook preview]" — [pillar] ([format])
|
||||||
|
|
||||||
View full schedule: /linkedin:calendar
|
View full schedule + mark as published: /linkedin:calendar
|
||||||
Mark as published: /linkedin:publish
|
|
||||||
|
|
||||||
Remember: Run 5x5x5 engagement 15 min before each post!
|
Remember: Run 5x5x5 engagement 15 min before each post!
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,26 @@
|
||||||
name: linkedin:calendar
|
name: linkedin:calendar
|
||||||
description: |
|
description: |
|
||||||
View and manage your post scheduling queue. Shows next 14 days of scheduled posts,
|
View and manage your post scheduling queue. Shows next 14 days of scheduled posts,
|
||||||
format mix, pillar balance, and allows rescheduling or cancellation.
|
format mix, pillar balance, and runs the publish action (mark a scheduled post
|
||||||
|
as published, update queue + state, first-hour engagement plan).
|
||||||
Triggers on: "calendar", "schedule", "queue", "upcoming posts", "what's scheduled",
|
Triggers on: "calendar", "schedule", "queue", "upcoming posts", "what's scheduled",
|
||||||
"show queue", "my schedule", "content calendar".
|
"show queue", "my schedule", "content calendar", "publish", "mark as published",
|
||||||
|
"posted today", "just published", "published a post", "post is live".
|
||||||
allowed-tools:
|
allowed-tools:
|
||||||
- Read
|
- Read
|
||||||
- Bash
|
- Bash
|
||||||
- Write
|
- Write
|
||||||
|
- Edit
|
||||||
- AskUserQuestion
|
- AskUserQuestion
|
||||||
---
|
---
|
||||||
|
|
||||||
# LinkedIn Content Calendar
|
# LinkedIn Content Calendar
|
||||||
|
|
||||||
You are a LinkedIn content calendar manager. Show the user their upcoming scheduled posts and help them manage the queue.
|
You are a LinkedIn content calendar manager. Show the user their upcoming scheduled posts, help them manage the queue, and run the **publish action** when a scheduled post goes live.
|
||||||
|
|
||||||
|
## Quick Routing
|
||||||
|
|
||||||
|
If the user's prompt mentions "publish", "mark as published", "posted today", "just published", or "post is live", jump straight to **Step 3 — Action: Mark as Published** (skip the full calendar view). Otherwise start at Step 1.
|
||||||
|
|
||||||
## Step 1: Load Queue
|
## Step 1: Load Queue
|
||||||
|
|
||||||
|
|
@ -72,20 +79,91 @@ OVERDUE:
|
||||||
|
|
||||||
Use AskUserQuestion:
|
Use AskUserQuestion:
|
||||||
|
|
||||||
1. **Reschedule a post** — Move a post to a different date/time
|
1. **Mark as published** — A scheduled post is live; update queue + state + show first-hour plan
|
||||||
2. **Cancel a post** — Remove from queue (set status to "cancelled")
|
2. **Reschedule a post** — Move a post to a different date/time
|
||||||
3. **Mark as published** — Quick route to `/linkedin:publish`
|
3. **Cancel a post** — Remove from queue (set status to "cancelled")
|
||||||
4. **View a draft** — Read the full draft content
|
4. **View a draft** — Read the full draft content
|
||||||
5. **Looks good** — No changes needed
|
5. **Looks good** — No changes needed
|
||||||
|
|
||||||
### Reschedule Flow
|
### Action: Mark as Published
|
||||||
|
|
||||||
|
This is the publish flow (no separate command — runs inline here).
|
||||||
|
|
||||||
|
**3a. Show publishable posts.** Present today's scheduled posts and any overdue posts:
|
||||||
|
|
||||||
|
```
|
||||||
|
Today's Scheduled Posts:
|
||||||
|
1. "[hook preview]" — [pillar] ([format]) — Scheduled for [time]
|
||||||
|
2. "[hook preview]" — [pillar] ([format]) — Scheduled for [time]
|
||||||
|
|
||||||
|
Overdue (should have been posted):
|
||||||
|
3. "[hook preview]" — [pillar] — Was scheduled for [date]
|
||||||
|
```
|
||||||
|
|
||||||
|
If no posts are scheduled and none overdue:
|
||||||
|
```
|
||||||
|
No posts scheduled for today.
|
||||||
|
- Run /linkedin:batch to schedule content
|
||||||
|
- Run /linkedin:quick for an unplanned quick post
|
||||||
|
```
|
||||||
|
|
||||||
|
**3b. Pick a post.** Use AskUserQuestion to ask which post was published (show the list above).
|
||||||
|
|
||||||
|
**3c. Update queue status:**
|
||||||
|
```bash
|
||||||
|
node --input-type=module -e "import { queueUpdateStatus } from '${CLAUDE_PLUGIN_ROOT}/hooks/scripts/queue-manager.mjs'; console.log(queueUpdateStatus('[post-id]', 'published'));"
|
||||||
|
```
|
||||||
|
|
||||||
|
**3d. Update state file deterministically:**
|
||||||
|
```bash
|
||||||
|
node --input-type=module -e "
|
||||||
|
import { writeState, updatePostTracking } from '${CLAUDE_PLUGIN_ROOT}/hooks/scripts/state-updater.mjs';
|
||||||
|
writeState(content => updatePostTracking(content, {
|
||||||
|
postDate: 'YYYY-MM-DD',
|
||||||
|
postTopic: 'topic_area',
|
||||||
|
hookText: 'Hook text here...',
|
||||||
|
charCount: NNNN,
|
||||||
|
format: 'FORMAT'
|
||||||
|
}));
|
||||||
|
"
|
||||||
|
```
|
||||||
|
Replace placeholders with actual post data from the published post.
|
||||||
|
|
||||||
|
**3e. First-hour battle plan.** Show after marking:
|
||||||
|
|
||||||
|
```
|
||||||
|
Post marked as published! Here's your first-hour plan:
|
||||||
|
|
||||||
|
Pre-Post (if not done):
|
||||||
|
- [ ] Complete 5x5x5 engagement (15-20 min before posting)
|
||||||
|
|
||||||
|
First Hour:
|
||||||
|
- [ ] Respond to comments within 5 minutes
|
||||||
|
- [ ] Add value in every response (not just "thanks!")
|
||||||
|
- [ ] Ask follow-up questions to deepen conversation
|
||||||
|
- [ ] Target: 15+ engagements in first 60 minutes
|
||||||
|
- [ ] Check back at 30-min and 60-min marks
|
||||||
|
|
||||||
|
48-Hour Check-In:
|
||||||
|
- Run /linkedin:analyze after 48 hours to review performance
|
||||||
|
- Or use post-feedback-monitor agent for real-time tracking
|
||||||
|
```
|
||||||
|
|
||||||
|
**3f. Ask about more.** Use AskUserQuestion:
|
||||||
|
1. **Mark another post** — I published more than one (loop back to 3a)
|
||||||
|
2. **View calendar** — Show remaining schedule (loop back to Step 2)
|
||||||
|
3. **Done** — All set for now
|
||||||
|
|
||||||
|
### Action: Reschedule
|
||||||
|
|
||||||
If they choose to reschedule:
|
If they choose to reschedule:
|
||||||
1. Ask which post (by number or hook preview)
|
1. Ask which post (by number or hook preview)
|
||||||
2. Ask for new date and time
|
2. Ask for new date and time
|
||||||
3. Update queue.json via queue_update_status + queue_add with new date
|
3. Update queue.json via queue_update_status + queue_add with new date
|
||||||
4. Show updated calendar
|
4. Show updated calendar
|
||||||
|
|
||||||
### Cancel Flow
|
### Action: Cancel
|
||||||
|
|
||||||
If they choose to cancel:
|
If they choose to cancel:
|
||||||
1. Ask which post
|
1. Ask which post
|
||||||
2. Confirm cancellation
|
2. Confirm cancellation
|
||||||
|
|
@ -94,7 +172,8 @@ If they choose to cancel:
|
||||||
node --input-type=module -e "import { queueUpdateStatus } from '${CLAUDE_PLUGIN_ROOT}/hooks/scripts/queue-manager.mjs'; console.log(queueUpdateStatus('[post-id]', 'cancelled'));"
|
node --input-type=module -e "import { queueUpdateStatus } from '${CLAUDE_PLUGIN_ROOT}/hooks/scripts/queue-manager.mjs'; console.log(queueUpdateStatus('[post-id]', 'cancelled'));"
|
||||||
```
|
```
|
||||||
|
|
||||||
### View Draft Flow
|
### Action: View Draft
|
||||||
|
|
||||||
If they want to see a draft:
|
If they want to see a draft:
|
||||||
1. Ask which post
|
1. Ask which post
|
||||||
2. Read the draft file from the `draft_path`
|
2. Read the draft file from the `draft_path`
|
||||||
|
|
@ -102,7 +181,7 @@ If they want to see a draft:
|
||||||
|
|
||||||
## Step 4: Balance Analysis
|
## Step 4: Balance Analysis
|
||||||
|
|
||||||
After showing the calendar, provide brief analysis:
|
After showing the calendar (or after a publish action loops back), provide brief analysis:
|
||||||
|
|
||||||
- **Format diversity**: Are formats varied enough? Flag if >2 consecutive same format.
|
- **Format diversity**: Are formats varied enough? Flag if >2 consecutive same format.
|
||||||
- **Pillar balance**: Are pillars well-distributed? Flag if any pillar >50%.
|
- **Pillar balance**: Are pillars well-distributed? Flag if any pillar >50%.
|
||||||
|
|
@ -112,4 +191,5 @@ After showing the calendar, provide brief analysis:
|
||||||
## Reference Files
|
## Reference Files
|
||||||
|
|
||||||
- `${CLAUDE_PLUGIN_ROOT}/references/scheduling-strategy.md`
|
- `${CLAUDE_PLUGIN_ROOT}/references/scheduling-strategy.md`
|
||||||
|
- `${CLAUDE_PLUGIN_ROOT}/references/engagement-frameworks.md`
|
||||||
- `${CLAUDE_PLUGIN_ROOT}/assets/drafts/queue.json`
|
- `${CLAUDE_PLUGIN_ROOT}/assets/drafts/queue.json`
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ Upcoming Posts (next 7 days):
|
||||||
If there are overdue posts, display with warning:
|
If there are overdue posts, display with warning:
|
||||||
```
|
```
|
||||||
OVERDUE (should have been posted):
|
OVERDUE (should have been posted):
|
||||||
[date]: "[hook preview]" — Run /linkedin:publish to update or /linkedin:calendar to reschedule
|
[date]: "[hook preview]" — Run /linkedin:calendar to mark as published or reschedule
|
||||||
```
|
```
|
||||||
|
|
||||||
If queue is empty: "No posts scheduled. Run /linkedin:batch to plan your week."
|
If queue is empty: "No posts scheduled. Run /linkedin:batch to plan your week."
|
||||||
|
|
@ -80,8 +80,7 @@ Present these options to the user:
|
||||||
| `/linkedin:video` | Create video scripts with hook, body, CTA, captions, and thumbnail suggestions |
|
| `/linkedin:video` | Create video scripts with hook, body, CTA, captions, and thumbnail suggestions |
|
||||||
| `/linkedin:newsletter` | Long-form orchestrator — newsletter editions, essays, series articles (research → draft → fact-check → persona-review → lock → delivery). The single long-form entry point |
|
| `/linkedin:newsletter` | Long-form orchestrator — newsletter editions, essays, series articles (research → draft → fact-check → persona-review → lock → delivery). The single long-form entry point |
|
||||||
| `/linkedin:batch` | Create a full week of content in one session |
|
| `/linkedin:batch` | Create a full week of content in one session |
|
||||||
| `/linkedin:calendar` | View and manage your post scheduling queue |
|
| `/linkedin:calendar` | View and manage your post scheduling queue + run the publish action (mark a scheduled post as published) |
|
||||||
| `/linkedin:publish` | Mark scheduled posts as published |
|
|
||||||
|
|
||||||
### Strategy & Optimization
|
### Strategy & Optimization
|
||||||
|
|
||||||
|
|
@ -164,7 +163,7 @@ If the user's intent is clear from context:
|
||||||
- Mentions "pipeline" or "end to end" → Route to `/linkedin:pipeline`
|
- Mentions "pipeline" or "end to end" → Route to `/linkedin:pipeline`
|
||||||
- Mentions "batch" or "week of content" → Route to `/linkedin:batch`
|
- Mentions "batch" or "week of content" → Route to `/linkedin:batch`
|
||||||
- Mentions "calendar" or "schedule" or "queue" or "upcoming posts" or "what's scheduled" → Route to `/linkedin:calendar`
|
- Mentions "calendar" or "schedule" or "queue" or "upcoming posts" or "what's scheduled" → Route to `/linkedin:calendar`
|
||||||
- Mentions "publish" or "mark as published" or "posted today" or "just published" or "post is live" → Route to `/linkedin:publish`
|
- Mentions "publish" or "mark as published" or "posted today" or "just published" or "post is live" → Route to `/linkedin:calendar` (publish action)
|
||||||
- Mentions "plan" → Suggest `content-planner` agent
|
- Mentions "plan" → Suggest `content-planner` agent
|
||||||
- Mentions "profile" or "360Brew" → Route to `/linkedin:profile`
|
- Mentions "profile" or "360Brew" → Route to `/linkedin:profile`
|
||||||
- Mentions "not working" or "low reach" → Route to `/linkedin:analyze`
|
- Mentions "not working" or "low reach" → Route to `/linkedin:analyze`
|
||||||
|
|
|
||||||
|
|
@ -705,9 +705,10 @@ Next: Step 10 — Scheduling.
|
||||||
## Step 10: Scheduling — register the edition in the plugin queue
|
## Step 10: Scheduling — register the edition in the plugin queue
|
||||||
|
|
||||||
The locked, conversion-passed edition is ready to ship. Register it in the
|
The locked, conversion-passed edition is ready to ship. Register it in the
|
||||||
plugin's native scheduling queue so it shows up in `/linkedin:calendar`,
|
plugin's native scheduling queue so it shows up in `/linkedin:calendar`
|
||||||
`/linkedin:publish`, and the posting-time reminders — the same queue the
|
(both for viewing and for the publish action) and the posting-time
|
||||||
short-form pipeline uses. The edition is now a first-class scheduled post.
|
reminders — the same queue the short-form pipeline uses. The edition is
|
||||||
|
now a first-class scheduled post.
|
||||||
|
|
||||||
**Procedure:**
|
**Procedure:**
|
||||||
|
|
||||||
|
|
@ -732,8 +733,8 @@ short-form pipeline uses. The edition is now a first-class scheduled post.
|
||||||
|
|
||||||
3. **Persist + close the edition.** Set the article's `status: "scheduled"`,
|
3. **Persist + close the edition.** Set the article's `status: "scheduled"`,
|
||||||
`scheduled: "<YYYY-MM-DD HH:MM>"`, and `currentPhase: "scheduling"` in
|
`scheduled: "<YYYY-MM-DD HH:MM>"`, and `currentPhase: "scheduling"` in
|
||||||
`edition-state.json`. Append a closing "edition scheduled → ready for
|
`edition-state.json`. Append a closing "edition scheduled → mark live via
|
||||||
`/linkedin:publish` on <date>" pointer to the HANDOVER §6. The pipeline is
|
`/linkedin:calendar` on <date>" pointer to the HANDOVER §6. The pipeline is
|
||||||
complete.
|
complete.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -741,7 +742,7 @@ Scheduling.
|
||||||
- Queue entry: <series-slug>-NN → assets/drafts/queue.json (status: scheduled)
|
- Queue entry: <series-slug>-NN → assets/drafts/queue.json (status: scheduled)
|
||||||
- Slot: YYYY-MM-DD HH:MM format: newsletter
|
- Slot: YYYY-MM-DD HH:MM format: newsletter
|
||||||
- Article status: scheduled
|
- Article status: scheduled
|
||||||
Edition complete. Visible in /linkedin:calendar; mark live with /linkedin:publish.
|
Edition complete. Visible in /linkedin:calendar; mark live via /linkedin:calendar (publish action).
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -1,115 +0,0 @@
|
||||||
---
|
|
||||||
name: linkedin:publish
|
|
||||||
description: |
|
|
||||||
Mark a scheduled post as published and update tracking state. Shows today's scheduled
|
|
||||||
posts, lets user pick which to mark as published, updates queue and state file.
|
|
||||||
Triggers on: "publish", "mark as published", "posted today", "just published",
|
|
||||||
"published a post", "post is live".
|
|
||||||
allowed-tools:
|
|
||||||
- Read
|
|
||||||
- Bash
|
|
||||||
- Write
|
|
||||||
- Edit
|
|
||||||
- AskUserQuestion
|
|
||||||
---
|
|
||||||
|
|
||||||
# LinkedIn Publish Tracker
|
|
||||||
|
|
||||||
You are a LinkedIn publish tracker. Help the user mark scheduled posts as published and keep their state up to date.
|
|
||||||
|
|
||||||
## Step 1: Load Today's Queue
|
|
||||||
|
|
||||||
```bash
|
|
||||||
node --input-type=module -e "
|
|
||||||
import { queueToday, queueOverdue, queueFormatSummary } from '${CLAUDE_PLUGIN_ROOT}/hooks/scripts/queue-manager.mjs';
|
|
||||||
console.log('=== TODAY ===');
|
|
||||||
console.log(queueFormatSummary(queueToday()));
|
|
||||||
console.log('=== OVERDUE ===');
|
|
||||||
console.log(queueFormatSummary(queueOverdue()));
|
|
||||||
"
|
|
||||||
```
|
|
||||||
|
|
||||||
Also read state: `~/.claude/linkedin-thought-leadership.local.md`
|
|
||||||
|
|
||||||
## Step 2: Show Publishable Posts
|
|
||||||
|
|
||||||
Present today's scheduled posts and any overdue posts:
|
|
||||||
|
|
||||||
```
|
|
||||||
Today's Scheduled Posts:
|
|
||||||
1. "[hook preview]" — [pillar] ([format]) — Scheduled for [time]
|
|
||||||
2. "[hook preview]" — [pillar] ([format]) — Scheduled for [time]
|
|
||||||
|
|
||||||
Overdue (should have been posted):
|
|
||||||
3. "[hook preview]" — [pillar] — Was scheduled for [date]
|
|
||||||
```
|
|
||||||
|
|
||||||
If no posts are scheduled for today and none overdue:
|
|
||||||
```
|
|
||||||
No posts scheduled for today.
|
|
||||||
- Run /linkedin:batch to schedule content
|
|
||||||
- Run /linkedin:calendar to view your schedule
|
|
||||||
- Run /linkedin:quick for an unplanned quick post
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 3: Select Post to Mark
|
|
||||||
|
|
||||||
Use AskUserQuestion to ask which post was published (show the list from Step 2).
|
|
||||||
|
|
||||||
## Step 4: Mark as Published
|
|
||||||
|
|
||||||
Update queue status:
|
|
||||||
```bash
|
|
||||||
node --input-type=module -e "import { queueUpdateStatus } from '${CLAUDE_PLUGIN_ROOT}/hooks/scripts/queue-manager.mjs'; console.log(queueUpdateStatus('[post-id]', 'published'));"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 5: Update State File
|
|
||||||
|
|
||||||
Update state deterministically:
|
|
||||||
```bash
|
|
||||||
node --input-type=module -e "
|
|
||||||
import { writeState, updatePostTracking } from '${CLAUDE_PLUGIN_ROOT}/hooks/scripts/state-updater.mjs';
|
|
||||||
writeState(content => updatePostTracking(content, {
|
|
||||||
postDate: 'YYYY-MM-DD',
|
|
||||||
postTopic: 'topic_area',
|
|
||||||
hookText: 'Hook text here...',
|
|
||||||
charCount: NNNN,
|
|
||||||
format: 'FORMAT'
|
|
||||||
}));
|
|
||||||
"
|
|
||||||
```
|
|
||||||
Replace placeholders with actual post data from the published post.
|
|
||||||
|
|
||||||
## Step 6: First-Hour Engagement Reminders
|
|
||||||
|
|
||||||
After marking as published, show the first-hour battle plan:
|
|
||||||
|
|
||||||
```
|
|
||||||
Post marked as published! Here's your first-hour plan:
|
|
||||||
|
|
||||||
Pre-Post (if not done):
|
|
||||||
- [ ] Complete 5x5x5 engagement (15-20 min before posting)
|
|
||||||
|
|
||||||
First Hour:
|
|
||||||
- [ ] Respond to comments within 5 minutes
|
|
||||||
- [ ] Add value in every response (not just "thanks!")
|
|
||||||
- [ ] Ask follow-up questions to deepen conversation
|
|
||||||
- [ ] Target: 15+ engagements in first 60 minutes
|
|
||||||
- [ ] Check back at 30-min and 60-min marks
|
|
||||||
|
|
||||||
48-Hour Check-In:
|
|
||||||
- Run /linkedin:analyze after 48 hours to review performance
|
|
||||||
- Or use post-feedback-monitor agent for real-time tracking
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 7: Ask About More
|
|
||||||
|
|
||||||
Use AskUserQuestion:
|
|
||||||
1. **Mark another post** — I published more than one
|
|
||||||
2. **View calendar** — See remaining schedule → `/linkedin:calendar`
|
|
||||||
3. **Done** — All set for now
|
|
||||||
|
|
||||||
## Reference Files
|
|
||||||
|
|
||||||
- `${CLAUDE_PLUGIN_ROOT}/assets/drafts/queue.json`
|
|
||||||
- `${CLAUDE_PLUGIN_ROOT}/references/engagement-frameworks.md`
|
|
||||||
|
|
@ -45,7 +45,7 @@ If posts were added to the queue during this session (`assets/drafts/queue.json`
|
||||||
|
|
||||||
If a scheduled post was published during this session:
|
If a scheduled post was published during this session:
|
||||||
- Verify it was marked as published in queue.json (status = "published")
|
- Verify it was marked as published in queue.json (status = "published")
|
||||||
- If not, remind: "Run /linkedin:publish to update the queue status"
|
- If not, remind: "Run /linkedin:calendar to mark the post as published and update queue status"
|
||||||
|
|
||||||
Provide reminders naturally based on what was done in the session. If no LinkedIn content was created, skip the reminders and just ensure state is consistent.
|
Provide reminders naturally based on what was done in the session. If no LinkedIn content was created, skip the reminders and just ensure state is consistent.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,8 +91,8 @@ if (followerCount > 0 && followerTarget > 0) {
|
||||||
try {
|
try {
|
||||||
const todayEntries = queueToday();
|
const todayEntries = queueToday();
|
||||||
const overdueEntries = queueOverdue();
|
const overdueEntries = queueOverdue();
|
||||||
if (todayEntries.length > 0) reminders.push(`You have ${todayEntries.length} post(s) scheduled for today. Run /linkedin:publish after posting to update your tracking.`);
|
if (todayEntries.length > 0) reminders.push(`You have ${todayEntries.length} post(s) scheduled for today. Run /linkedin:calendar after posting to mark as published.`);
|
||||||
if (overdueEntries.length > 0) reminders.push(`${overdueEntries.length} overdue post(s) in your queue. Run /linkedin:publish to mark as posted, or /linkedin:calendar to reschedule.`);
|
if (overdueEntries.length > 0) reminders.push(`${overdueEntries.length} overdue post(s) in your queue. Run /linkedin:calendar to mark as posted or reschedule.`);
|
||||||
} catch { /* ignore */ }
|
} catch { /* ignore */ }
|
||||||
|
|
||||||
// Peak posting time
|
// Peak posting time
|
||||||
|
|
|
||||||
|
|
@ -250,12 +250,12 @@ if (existsSync(STATE_FILE)) {
|
||||||
|
|
||||||
// Today's scheduled posts
|
// Today's scheduled posts
|
||||||
if (queueTodayText) {
|
if (queueTodayText) {
|
||||||
context += `## Today's Scheduled Posts\\n${queueTodayText.replace(/\n/g, '\\n')}\\nRun /linkedin:publish after posting to update tracking.\\n\\n`;
|
context += `## Today's Scheduled Posts\\n${queueTodayText.replace(/\n/g, '\\n')}\\nRun /linkedin:calendar after posting to mark as published.\\n\\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overdue posts
|
// Overdue posts
|
||||||
if (queueOverdueText) {
|
if (queueOverdueText) {
|
||||||
context += `## OVERDUE Posts\\n${queueOverdueText.replace(/\n/g, '\\n')}\\nRun /linkedin:publish to mark as posted, or /linkedin:calendar to reschedule.\\n\\n`;
|
context += `## OVERDUE Posts\\n${queueOverdueText.replace(/\n/g, '\\n')}\\nRun /linkedin:calendar to mark as posted or reschedule.\\n\\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Posting reminders
|
// Posting reminders
|
||||||
|
|
@ -330,10 +330,10 @@ if (existsSync(STATE_FILE)) {
|
||||||
|
|
||||||
// Queue-related reminders
|
// Queue-related reminders
|
||||||
if (queueTodayCount > 0) {
|
if (queueTodayCount > 0) {
|
||||||
reminders += `- You have ${queueTodayCount} post(s) scheduled for today. Run /linkedin:publish after posting.\\n`;
|
reminders += `- You have ${queueTodayCount} post(s) scheduled for today. Run /linkedin:calendar after posting to mark as published.\\n`;
|
||||||
}
|
}
|
||||||
if (queueOverdueCount > 0) {
|
if (queueOverdueCount > 0) {
|
||||||
reminders += `- ${queueOverdueCount} overdue post(s) in queue. Run /linkedin:publish or /linkedin:calendar to manage.\\n`;
|
reminders += `- ${queueOverdueCount} overdue post(s) in queue. Run /linkedin:calendar to mark as posted or reschedule.\\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reminders) context += `## Posting Reminders\\n${reminders}\\n`;
|
if (reminders) context += `## Posting Reminders\\n${reminders}\\n`;
|
||||||
|
|
@ -380,7 +380,7 @@ if (existsSync(STATE_FILE)) {
|
||||||
context += `- Queued posts (next 7 days): ${queueUpcomingCount}\\n`;
|
context += `- Queued posts (next 7 days): ${queueUpcomingCount}\\n`;
|
||||||
if (queueTodayCount > 0) context += `- Today: ${queueTodayCount} post(s)\\n`;
|
if (queueTodayCount > 0) context += `- Today: ${queueTodayCount} post(s)\\n`;
|
||||||
if (queueOverdueCount > 0) context += `- Overdue: ${queueOverdueCount} post(s)\\n`;
|
if (queueOverdueCount > 0) context += `- Overdue: ${queueOverdueCount} post(s)\\n`;
|
||||||
context += '- Manage: /linkedin:calendar | Publish: /linkedin:publish\\n\\n';
|
context += '- Manage + publish: /linkedin:calendar\\n\\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
context += `State file: ${STATE_FILE}\\n`;
|
context += `State file: ${STATE_FILE}\\n`;
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ let isLinkedin = false;
|
||||||
// Tier 1: Strong signals
|
// Tier 1: Strong signals
|
||||||
const strongSignals = [
|
const strongSignals = [
|
||||||
'/linkedin:post', '/linkedin:quick', '/linkedin:batch',
|
'/linkedin:post', '/linkedin:quick', '/linkedin:batch',
|
||||||
'/linkedin:pipeline', '/linkedin:publish', '/linkedin:video',
|
'/linkedin:pipeline', '/linkedin:calendar', '/linkedin:video',
|
||||||
'/linkedin:multiplatform', '/linkedin:react', '/linkedin:summarize',
|
'/linkedin:multiplatform', '/linkedin:react', '/linkedin:summarize',
|
||||||
'linkedin post', 'lag en post',
|
'linkedin post', 'lag en post',
|
||||||
'skriv en post', 'write a post', 'quick post', 'create post',
|
'skriv en post', 'write a post', 'quick post', 'create post',
|
||||||
|
|
|
||||||
|
|
@ -129,8 +129,7 @@ These rules apply to ALL content created by any skill or command:
|
||||||
| `/linkedin:import` | Import CSV export to structured JSON |
|
| `/linkedin:import` | Import CSV export to structured JSON |
|
||||||
| `/linkedin:report` | Generate weekly performance report |
|
| `/linkedin:report` | Generate weekly performance report |
|
||||||
| `/linkedin:batch` | Create a full week of content |
|
| `/linkedin:batch` | Create a full week of content |
|
||||||
| `/linkedin:calendar` | View and manage post scheduling queue |
|
| `/linkedin:calendar` | View + manage post scheduling queue, and run the publish action (mark a scheduled post as published) |
|
||||||
| `/linkedin:publish` | Mark scheduled posts as published |
|
|
||||||
| `/linkedin:pipeline` | Full end-to-end content pipeline |
|
| `/linkedin:pipeline` | Full end-to-end content pipeline |
|
||||||
| `/linkedin:newsletter` | Long-form orchestrator (newsletter editions, essays, series articles) -- single long-form entry point |
|
| `/linkedin:newsletter` | Long-form orchestrator (newsletter editions, essays, series articles) -- single long-form entry point |
|
||||||
| `/linkedin:multiplatform` | Adapt content for other platforms (short-form/cross-format) |
|
| `/linkedin:multiplatform` | Adapt content for other platforms (short-form/cross-format) |
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue