Content Calendar Tool
A complete example of an AI-powered content calendar plugin that plans editorial calendars, researches topics, and drafts channel-optimized content.
What It Does
The Content Calendar plugin:
- Stores a user's content strategy profile (business description, audience, goals, channels, keywords)
- Uses
context.search()to research trends, competitors, and search intent - Generates a dated editorial calendar with AI using
context.ai.analyze() - Drafts channel-optimized content for LinkedIn, X/Twitter, and SEO blog posts
- Provides a launchable widget for browsing and managing the calendar
Tool Contract
The plugin exposes one tool — content_calendar — with these actions:
| Action | Description | Key Parameters |
|---|---|---|
show | Opens the calendar widget | — |
setup_strategy | Stores content strategy | businessSummary, audience, offers, goals, preferredChannels |
plan_calendar | Generates calendar items | startDate, endDate, instructions? |
list_items | Lists calendar items | channel?, status?, startDate?, endDate? |
items_for_date | Items for a specific date | date (YYYY-MM-DD or "tomorrow") |
update_item | Edits a calendar item | itemId, plus any fields to update |
refresh_research | Re-runs web search | itemId?, query? |
write_item | Drafts one calendar item | itemId |
write_for_date | Drafts all ready items for a date | date |
Database Schema
The plugin uses four single-user tables with pie_user_id RLS:
cc_strategy_profiles— One row per user. Business summary, audience, offers, goals, voice, channels, cadence, keywords.cc_research_runs— One row per search pass. Query, provider, normalized results, summaries, takeaways.cc_calendar_items— One row per content piece. Date, channel, status, pillar, title, hook, angle, CTA, brief, SEO fields.cc_drafts— One row per draft version. Item ID, version number, content payload, model metadata.
Status Flow
idea → scheduled → ready_to_write → drafting → drafted
↘ needs_refresh ↗
archivedUsing context.search() for Research
The plugin uses the platform search primitive to gather topical context:
var searchResult = await context.search('b2b saas content marketing trends 2026', {
type: 'web',
limit: 8,
includeText: true,
includeHighlights: true,
});
// Normalize results into research context
for (var i = 0; i < searchResult.results.length; i++) {
var r = searchResult.results[i];
console.log(r.title, r.url, r.snippet);
}Research results are stored in cc_research_runs and linked to calendar items via research_run_id.
Prompt Stack Architecture
The plugin uses a layered prompt builder for AI generation:
- Base system prompt — Action-specific instructions (
plan_calendar,write_item, etc.) - Content Playbook — Verbatim injection of the full content writing playbook with forbidden lexicon, formatting rules, and platform-specific optimization guides
- Channel guide — LinkedIn, X/Twitter, or blog-specific writing rules
- User strategy — Business summary, audience, offers, goals, voice
- Research context — Normalized search findings, source URLs, takeaways
- Calendar item brief — Title, angle, hook, CTA, date, channel, SEO fields
- Output schema — JSON structure expected in the response
Model Policy
All core AI tasks use google/gemini-3.1-pro-preview:
var result = await context.ai.analyze({
prompt: fullPromptStack,
data: { startDate: '2026-04-01', endDate: '2026-04-30', channels: ['linkedin', 'twitter', 'blog'] },
model: 'google/gemini-3.1-pro-preview',
});Cross-Chat Drafting
Any PIE chat can invoke the calendar tool to draft content:
"Write the content from the calendar for tomorrow"
This maps to the write_for_date action, which:
- Resolves "tomorrow" to a concrete date
- Finds all items with status
scheduled,ready_to_write, orneeds_refresh - Generates drafts for each item using the full prompt stack
- Stores each draft as a versioned row in
cc_drafts - Updates each item's status to
drafted
Widget UI
The launchable widget provides:
- Calendar view — Month grid with channel-colored dots per day
- Agenda view — Chronological list grouped by date with status badges
- Strategy form — Editable profile for business gist, audience, channels, and keywords
- Plan modal — Date range picker with optional instructions for AI calendar generation
- Item detail — Full brief display with write/research/delete actions and draft preview
The widget communicates with the handler via PIE.sendAction() and receives updates via PIE.onData(). Dark mode is supported via PIE.onTheme().