Creates and manages activity records in the CRM Communications database with AI-generated summaries. Activates when the user wants to log an email or meeting to CRM, record a client interaction, or asks 'save this to the client record.' Handles idempotent operations, deduplication, and AI summarization.
From founder-osnpx claudepluginhub thecloudtips/founder-os --plugin founder-osThis skill uses the workspace's default tool permissions.
references/activity-schema.mdDesigns and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
Create and manage activity records in the CRM Pro Communications database. Each synced email or meeting becomes a Communications record with an AI-generated summary, participant list, and unique identifier for deduplication. The skill ensures idempotent operations -- re-syncing the same activity updates rather than duplicates.
This skill handles the write layer only: activity record creation, summary generation, deduplication, and batch processing. Client resolution (matching email addresses and attendee names to CRM records) is delegated to the client-matching skill. Command-layer orchestration, source data fetching from Gmail and Calendar, and user-facing output formatting are handled by the commands (crm:sync-email, crm:sync-meeting).
Search for the database by title: "[FOS] Communications", "Founder OS HQ - Communications", "Communications", or "CRM - Communications" (in that priority order). Use dynamic database discovery -- search by title using the Notion search API, never hardcode database IDs. Prefer "[FOS] Communications" when it exists; otherwise prefer "Founder OS HQ - Communications", then the prefixed form ("CRM - Communications") over the short form. Cache the discovered database ID for the duration of the current command execution.
If the database is not found, report the absence to the calling skill and stop. Error message: "Communications database not found. Ensure the Founder OS HQ workspace template or CRM Pro template is installed in your Notion workspace."
Create each activity record with these properties:
| Property | Type | Source | Description |
|---|---|---|---|
| Title | title | Generated | AI summary headline (max 80 chars) |
| Type | select | Mapped | "Email Sent", "Email Received", "Meeting Held", "Meeting Scheduled" |
| Date | date | Source data | ISO 8601 timestamp of when the activity occurred |
| Contact | relation | client-matching skill | Matched contact Notion page ID |
| Company | relation | client-matching skill | Matched company Notion page ID |
| Summary | rich_text | AI-generated | 2-3 sentence summary of content |
| Sentiment | select | AI-classified | "Positive", "Neutral", "Negative" |
For the full list of optional properties beyond this core set, see ${CLAUDE_PLUGIN_ROOT}/skills/crm/activity-logging/references/activity-schema.md.
Map each source activity to the correct Type select value:
| Source | Activity | Type Value |
|---|---|---|
| Gmail sent folder | Email user sent | "Email Sent" |
| Gmail inbox | Email user received | "Email Received" |
| Calendar past event | Meeting that occurred (start time is in the past) | "Meeting Held" |
| Calendar future event | Upcoming meeting (start time is in the future) | "Meeting Scheduled" |
Apply these mapping rules:
Generate a concise 2-3 sentence summary for each activity. Write in plain English. Avoid jargon. A founder should understand the gist of the interaction in under 5 seconds.
For the Title field, extract the email subject line. Strip "Re:", "Fwd:", "RE:", "FW:", and "Fwd:" prefixes (including nested multiples like "Re: Re: Re:"). Truncate at 80 characters. Capitalize the first letter of the result if it is not already capitalized.
For the Title field, use the calendar event title directly. Truncate at 80 characters. Do not modify the casing of meeting titles.
Classify each activity into one of three sentiment values:
When signals are mixed (e.g., gratitude for past work but concern about upcoming deadlines), classify based on the dominant tone. When truly ambiguous, default to Neutral.
For detailed signal word lists and classification examples for each activity type, see ${CLAUDE_PLUGIN_ROOT}/skills/crm/activity-logging/references/activity-schema.md.
Prevent duplicate records when the same activity is synced multiple times. Use a two-step search before every write operation.
Use the Gmail Thread ID as the logical unique key. First check whether the Communications DB has a "Thread ID" property (an optional rich_text field). If it exists, query by exact Thread ID match for precise deduplication. If the property does not exist, approximate deduplication with a combined search:
Use the Calendar Event ID as the logical unique key. First check whether the Communications DB has a "Thread ID" property (which stores both Thread IDs and Event IDs). If it exists, query by exact Event ID match. If the property does not exist, approximate deduplication with a combined search:
When processing a batch of activities, perform the deduplication search as a single bulk query rather than one query per activity. Fetch all Communications records within the date range of the batch, then match locally against each incoming activity. This reduces Notion API calls from O(n) to O(1).
When an existing record is found during deduplication, update it using these rules:
When processing multiple activities in a single command invocation (e.g., crm:sync-email --days=7), follow this batch sequence:
created_count: N // New records written
updated_count: N // Existing records updated with new data
skipped_count: N // Records unchanged, no write needed
failed_count: N // Records that failed to write (with error details)
unmatched_count: N // Activities where client-matching returned NONE
Process activities in batches of 50. When the total exceeds 50, split into sequential batches of 50 and process each batch fully before starting the next. This avoids Notion API rate limiting. Between batches, pause for 1 second.
When the client-matching skill returns confidence NONE for an activity's participants:
When an email thread contains more than 10 messages:
When a calendar event is marked as all-day (no specific start/end time):
Each occurrence of a recurring meeting is a separate activity record. Do not collapse recurring instances into a single record. Deduplicate each occurrence independently by matching on both the meeting title and the specific occurrence date.
Skip cancelled meetings by default. Do not create Communications records for cancelled events. When the --include-cancelled flag is set on the command, log cancelled meetings with:
Skip draft emails (Gmail "DRAFT" label). Only sync sent and received emails. Draft emails are incomplete communications and should not appear in the CRM activity log.
When a Notion API call fails during batch processing:
When the source data provides insufficient content to generate a meaningful summary (e.g., an email with an empty body or a meeting with no title):
Never fail silently. Always report which operations succeeded and which failed.
For the detailed activity schema with all optional fields, full summary templates with examples for each activity type, sentiment signal word lists, title generation rules, and error recovery procedures, consult ${CLAUDE_PLUGIN_ROOT}/skills/crm/activity-logging/references/activity-schema.md.
For the standardized summary format template used during generation, consult ${CLAUDE_PLUGIN_ROOT}/templates/activity-summary.md.