[object Object]

← back to Cli Printing Press

docs: add Cal.com CLI research and planning artifacts

6b4aea3a44674c1cce0f5be8c0077d8ffd313224 · 2026-03-27 22:08:10 -0700 · Trevin Chow

Phase 0-3 artifacts from the calcom-pp-cli printing press run:
visionary research, power user workflows, feature parity audit,
data layer spec, deep research, and GOAT audit. Also adds
.DS_Store to .gitignore.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 6b4aea3a44674c1cce0f5be8c0077d8ffd313224
Author: Trevin Chow <trevin@trevinchow.com>
Date:   Fri Mar 27 22:08:10 2026 -0700

    docs: add Cal.com CLI research and planning artifacts
    
    Phase 0-3 artifacts from the calcom-pp-cli printing press run:
    visionary research, power user workflows, feature parity audit,
    data layer spec, deep research, and GOAT audit. Also adds
    .DS_Store to .gitignore.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---
 .gitignore                                         |   1 +
 .../2026-03-27-feat-calcom-cli-data-layer-spec.md  | 248 +++++++++++++++++++++
 ...6-03-27-feat-calcom-cli-feature-parity-audit.md | 101 +++++++++
 ...6-03-27-feat-calcom-cli-power-user-workflows.md | 124 +++++++++++
 docs/plans/2026-03-27-feat-calcom-cli-research.md  |  56 +++++
 ...026-03-27-feat-calcom-cli-visionary-research.md | 151 +++++++++++++
 docs/plans/2026-03-27-fix-calcom-cli-audit.md      |  45 ++++
 7 files changed, 726 insertions(+)

diff --git a/.gitignore b/.gitignore
index f6905792..d34e9ff2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+.DS_Store
 .cache/
 printing-press
 library/
diff --git a/docs/plans/2026-03-27-feat-calcom-cli-data-layer-spec.md b/docs/plans/2026-03-27-feat-calcom-cli-data-layer-spec.md
new file mode 100644
index 00000000..c3c32cb6
--- /dev/null
+++ b/docs/plans/2026-03-27-feat-calcom-cli-data-layer-spec.md
@@ -0,0 +1,248 @@
+---
+title: "Data Layer Specification: Cal.com CLI"
+type: feat
+status: active
+date: 2026-03-27
+phase: "0.7"
+api: "cal.com"
+---
+
+# Data Layer Specification: Cal.com CLI
+
+## Entity Classification
+
+| Entity | Type | Est. Volume | Update Freq | Temporal Field | Persistence Need |
+|--------|------|-------------|-------------|----------------|-----------------|
+| **Bookings** | Accumulating | 100-10,000/account | Daily | `createdAt`, `updatedAt` | SQLite + incremental sync |
+| **Event Types** | Reference | 5-50/account | Weekly | N/A | SQLite + periodic refresh |
+| **Attendees** | Accumulating (nested) | Same as bookings | With parent booking | via booking `updatedAt` | Extracted from booking data |
+| **Schedules** | Reference | 1-5/account | Monthly | N/A | SQLite + periodic refresh |
+| **Teams** | Reference | 1-10/account | Rarely | N/A | SQLite + periodic refresh |
+| **Calendars** | Ephemeral | 2-5 connections | Rarely | N/A | API-only (live check) |
+| **Webhooks** | Reference | 1-20/account | Rarely | N/A | API-only |
+| **Slots** | Ephemeral | Generated per query | N/A | N/A | API-only |
+
+## Data Gravity Scoring
+
+| Entity | Volume (0-3) | QueryFreq (0-3) | JoinDemand (0-2) | SearchNeed (0-2) | TemporalValue (0-2) | **Total** |
+|--------|-------------|-----------------|-----------------|-----------------|--------------------|-----------|
+| **Bookings** | 2 | 3 (daily: agenda, search) | 2 (event_types, attendees) | 2 (title, description) | 2 (trends, analytics) | **11** |
+| **Attendees** | 2 | 3 (daily: search by name/email) | 2 (linked to bookings) | 2 (name, email) | 1 | **10** |
+| **Event Types** | 1 | 2 (weekly: stale, stats) | 2 (referenced by bookings) | 1 (title, slug) | 0 | **6** |
+| **Schedules** | 0 | 1 | 1 | 0 | 0 | **2** |
+| **Teams** | 0 | 1 | 1 | 0 | 0 | **2** |
+
+**Primary entities (>= 8):** Bookings (11), Attendees (10)
+**Support entities (5-7):** Event Types (6)
+**API-only (< 5):** Schedules, Teams, Calendars, Webhooks, Slots
+
+## Social Signal Mining
+
+Evidence for local data persistence:
+1. No Cal.com backup/export tools exist (GitHub search confirmed)
+2. Calendar sync issues are #1 complaint — local copy is insurance
+3. callytics web dashboard (0 stars) tried analytics but no CLI
+4. n8n/Zapier integrations show demand for data out of Cal.com
+5. gcalcli (3k stars) proves calendar CLIs succeed by enabling offline workflows
+
+## SQLite Schema
+
+```sql
+CREATE TABLE IF NOT EXISTS bookings (
+    id          INTEGER PRIMARY KEY,
+    uid         TEXT NOT NULL UNIQUE,
+    title       TEXT NOT NULL DEFAULT '',
+    description TEXT NOT NULL DEFAULT '',
+    status      TEXT NOT NULL DEFAULT '',
+    start_time  TEXT NOT NULL DEFAULT '',
+    end_time    TEXT NOT NULL DEFAULT '',
+    duration    INTEGER NOT NULL DEFAULT 0,
+    location    TEXT NOT NULL DEFAULT '',
+    meeting_url TEXT NOT NULL DEFAULT '',
+    event_type_id    INTEGER NOT NULL DEFAULT 0,
+    event_type_slug  TEXT NOT NULL DEFAULT '',
+    cancellation_reason TEXT NOT NULL DEFAULT '',
+    rescheduling_reason TEXT NOT NULL DEFAULT '',
+    rating      REAL NOT NULL DEFAULT 0,
+    absent_host INTEGER NOT NULL DEFAULT 0,
+    created_at  TEXT NOT NULL DEFAULT '',
+    updated_at  TEXT NOT NULL DEFAULT '',
+    data        TEXT NOT NULL DEFAULT '{}'
+);
+
+CREATE INDEX IF NOT EXISTS idx_bookings_status ON bookings(status);
+CREATE INDEX IF NOT EXISTS idx_bookings_start ON bookings(start_time);
+CREATE INDEX IF NOT EXISTS idx_bookings_updated ON bookings(updated_at);
+CREATE INDEX IF NOT EXISTS idx_bookings_event_type ON bookings(event_type_id);
+
+CREATE TABLE IF NOT EXISTS attendees (
+    id          INTEGER PRIMARY KEY AUTOINCREMENT,
+    booking_id  INTEGER NOT NULL REFERENCES bookings(id),
+    booking_uid TEXT NOT NULL DEFAULT '',
+    name        TEXT NOT NULL DEFAULT '',
+    email       TEXT NOT NULL DEFAULT '',
+    phone       TEXT NOT NULL DEFAULT '',
+    timezone    TEXT NOT NULL DEFAULT '',
+    absent      INTEGER NOT NULL DEFAULT 0,
+    language    TEXT NOT NULL DEFAULT ''
+);
+
+CREATE INDEX IF NOT EXISTS idx_attendees_booking ON attendees(booking_id);
+CREATE INDEX IF NOT EXISTS idx_attendees_email ON attendees(email);
+
+CREATE TABLE IF NOT EXISTS event_types (
+    id              INTEGER PRIMARY KEY,
+    title           TEXT NOT NULL DEFAULT '',
+    slug            TEXT NOT NULL DEFAULT '',
+    description     TEXT NOT NULL DEFAULT '',
+    length_minutes  INTEGER NOT NULL DEFAULT 0,
+    hidden          INTEGER NOT NULL DEFAULT 0,
+    price           REAL NOT NULL DEFAULT 0,
+    currency        TEXT NOT NULL DEFAULT '',
+    owner_id        INTEGER NOT NULL DEFAULT 0,
+    schedule_id     INTEGER NOT NULL DEFAULT 0,
+    booking_url     TEXT NOT NULL DEFAULT '',
+    data            TEXT NOT NULL DEFAULT '{}'
+);
+
+CREATE INDEX IF NOT EXISTS idx_event_types_slug ON event_types(slug);
+CREATE INDEX IF NOT EXISTS idx_event_types_owner ON event_types(owner_id);
+
+-- FTS5 on bookings
+CREATE VIRTUAL TABLE IF NOT EXISTS bookings_fts USING fts5(
+    title, description,
+    content='bookings', content_rowid='id'
+);
+
+CREATE TRIGGER IF NOT EXISTS bookings_ai AFTER INSERT ON bookings BEGIN
+    INSERT INTO bookings_fts(rowid, title, description) VALUES (new.id, new.title, new.description);
+END;
+CREATE TRIGGER IF NOT EXISTS bookings_ad AFTER DELETE ON bookings BEGIN
+    INSERT INTO bookings_fts(bookings_fts, rowid, title, description) VALUES ('delete', old.id, old.title, old.description);
+END;
+CREATE TRIGGER IF NOT EXISTS bookings_au AFTER UPDATE ON bookings BEGIN
+    INSERT INTO bookings_fts(bookings_fts, rowid, title, description) VALUES ('delete', old.id, old.title, old.description);
+    INSERT INTO bookings_fts(rowid, title, description) VALUES (new.id, new.title, new.description);
+END;
+
+-- FTS5 on attendees
+CREATE VIRTUAL TABLE IF NOT EXISTS attendees_fts USING fts5(
+    name, email,
+    content='attendees', content_rowid='id'
+);
+
+CREATE TRIGGER IF NOT EXISTS attendees_ai AFTER INSERT ON attendees BEGIN
+    INSERT INTO attendees_fts(rowid, name, email) VALUES (new.id, new.name, new.email);
+END;
+CREATE TRIGGER IF NOT EXISTS attendees_ad AFTER DELETE ON attendees BEGIN
+    INSERT INTO attendees_fts(attendees_fts, rowid, name, email) VALUES ('delete', old.id, old.name, old.email);
+END;
+CREATE TRIGGER IF NOT EXISTS attendees_au AFTER UPDATE ON attendees BEGIN
+    INSERT INTO attendees_fts(attendees_fts, rowid, name, email) VALUES ('delete', old.id, old.name, old.email);
+    INSERT INTO attendees_fts(rowid, name, email) VALUES (new.id, new.name, new.email);
+END;
+
+-- Sync state tracking
+CREATE TABLE IF NOT EXISTS sync_state (
+    entity      TEXT PRIMARY KEY,
+    last_synced TEXT NOT NULL DEFAULT '',
+    cursor      TEXT NOT NULL DEFAULT '',
+    total_items INTEGER NOT NULL DEFAULT 0
+);
+```
+
+## Sync Strategy
+
+### Bookings — Incremental via `afterUpdatedAt`
+
+**VALIDATED:** `afterUpdatedAt` query param confirmed in OpenAPI spec for GET /v2/bookings.
+
+1. Read `sync_state` for entity='bookings' to get last cursor
+2. GET /v2/bookings?afterUpdatedAt={cursor}&take=100&sortUpdatedAt=asc
+3. For each booking: upsert into `bookings`, delete+reinsert `attendees`
+4. Update sync_state with latest updatedAt
+5. Paginate with skip if hasNextPage
+6. Also sync cancelled separately (afterUpdatedAt + status=cancelled)
+
+**Batch size:** 100 (API max), **Rate budget:** 100 pages = ~50s at 120 req/min
+
+### Event Types — Full Refresh
+GET /v2/event-types → upsert all → update sync_state
+
+### Scoping Flags
+- `--team <id>` → adds teamId filter
+- `--since <date>` → overrides cursor
+- `--status <s>` → filters by status
+- `--max-pages N` → limits pagination (default: unlimited)
+
+## Search Filters
+
+| CLI Flag | SQL WHERE | Description |
+|----------|----------|-------------|
+| `--status` | `WHERE status = ?` | Filter by booking status |
+| `--attendee` | `JOIN attendees ... WHERE name LIKE ?` | Attendee name search |
+| `--email` | `JOIN attendees ... WHERE email = ?` | Exact email match |
+| `--event-type` | `WHERE event_type_id = ?` | Filter by event type |
+| `--after` | `WHERE start_time >= ?` | Start date |
+| `--before` | `WHERE start_time <= ?` | End date |
+| `--days N` | `WHERE start_time >= datetime('now', '-N days')` | Relative window |
+| (positional) | FTS5 MATCH on bookings_fts + attendees_fts | Free text search |
+
+## Compound Queries
+
+### 1. Search by attendee
+```sql
+SELECT b.*, a.name, a.email FROM bookings b
+JOIN attendees a ON b.id = a.booking_id
+JOIN attendees_fts ON attendees_fts.rowid = a.id
+WHERE attendees_fts MATCH ? ORDER BY b.start_time DESC LIMIT ?
+```
+
+### 2. Stats by event type
+```sql
+SELECT et.title, COUNT(*) as total,
+  SUM(CASE WHEN b.status='cancelled' THEN 1 ELSE 0 END) as cancelled,
+  ROUND(100.0*SUM(CASE WHEN b.status='past' THEN 1 ELSE 0 END)/COUNT(*),1) as show_rate
+FROM bookings b LEFT JOIN event_types et ON b.event_type_id = et.id
+WHERE b.start_time >= ? GROUP BY et.id ORDER BY total DESC
+```
+
+### 3. Stale event types
+```sql
+SELECT et.id, et.title, et.slug, COUNT(b.id) as cnt, MAX(b.start_time) as last
+FROM event_types et LEFT JOIN bookings b ON et.id = b.event_type_id
+  AND b.start_time >= datetime('now', '-'||?||' days')
+GROUP BY et.id HAVING cnt = 0 ORDER BY et.title
+```
+
+### 4. Today's agenda
+```sql
+SELECT b.*, GROUP_CONCAT(a.name, ', ') as attendees
+FROM bookings b LEFT JOIN attendees a ON b.id = a.booking_id
+WHERE b.start_time >= ? AND b.start_time < ? AND b.status != 'cancelled'
+GROUP BY b.id ORDER BY b.start_time ASC
+```
+
+### 5. Conflicts (overlapping bookings)
+```sql
+SELECT b1.title, b1.start_time, b1.end_time, b2.title as conflict, b2.start_time as c_start
+FROM bookings b1 JOIN bookings b2 ON b1.id < b2.id
+  AND b1.start_time < b2.end_time AND b1.end_time > b2.start_time
+WHERE b1.status != 'cancelled' AND b2.status != 'cancelled' AND b1.start_time >= ?
+```
+
+## Tail Strategy
+
+**Decision: REST polling** — Cal.com has no WebSocket/SSE for clients. Webhooks are push (server-to-server). Use afterUpdatedAt polling every 30-60s for a `tail` command.
+
+## Phase 4 Priority 0 Commands
+
+| Command | Data Path |
+|---------|-----------|
+| sync | WRITE: UpsertBooking + UpsertAttendees + UpsertEventType |
+| search | READ: bookings_fts + attendees_fts |
+| sql | READ: any table |
+| agenda | READ: bookings + attendees (compound query 4) |
+| stats | READ: bookings + event_types (compound query 2) |
+| stale | READ: event_types LEFT JOIN bookings (compound query 3) |
+| conflicts | READ: bookings self-join (compound query 5) |
diff --git a/docs/plans/2026-03-27-feat-calcom-cli-feature-parity-audit.md b/docs/plans/2026-03-27-feat-calcom-cli-feature-parity-audit.md
new file mode 100644
index 00000000..c60b9ca2
--- /dev/null
+++ b/docs/plans/2026-03-27-feat-calcom-cli-feature-parity-audit.md
@@ -0,0 +1,101 @@
+---
+title: "Feature Parity Audit: Cal.com CLI"
+type: feat
+status: active
+date: 2026-03-27
+phase: "0.6"
+api: "cal.com"
+---
+
+# Feature Parity Audit: Cal.com CLI
+
+## Competitors Analyzed
+
+1. **@calcom/cli** (8 stars, TypeScript) — Official Cal.com CLI in companion repo. 46 command categories. Pure API wrapper.
+2. **gcalcli** (3k+ stars, Python) — Google Calendar CLI. Domain reference for calendar CLIs. 11 commands.
+
+## Feature Matrix
+
+### @calcom/cli (Official) — 46 Command Categories
+
+| Feature | @calcom/cli | gcalcli | Ours | Classification |
+|---------|-------------|---------|------|----------------|
+| **Booking CRUD** (list, get, create, cancel, reschedule) | YES | N/A (different API) | YES | TABLE STAKES |
+| **Event Type CRUD** (list, get, create, update, delete) | YES | N/A | YES | TABLE STAKES |
+| **Schedule CRUD** (list, get, create, update, delete) | YES | N/A | YES | TABLE STAKES |
+| **Calendar connections** (list, check, connect, disconnect) | YES | list calendars | YES | TABLE STAKES |
+| **Webhooks CRUD** | YES | N/A | YES | TABLE STAKES |
+| **Teams CRUD** | YES | N/A | YES | TABLE STAKES |
+| **Team event types** | YES | N/A | YES | NICE-TO-HAVE |
+| **Team memberships** | YES | N/A | YES | NICE-TO-HAVE |
+| **Conferencing apps** (list, connect, default) | YES | N/A | YES | TABLE STAKES |
+| **OAuth clients** | YES | N/A | NO | ANTI-SCOPE (platform feature, not user workflow) |
+| **Managed users** | YES | N/A | NO | ANTI-SCOPE (platform feature) |
+| **Organization-level operations** (131 endpoints) | YES | N/A | NO | ANTI-SCOPE (enterprise, org plan required) |
+| **Routing forms** | YES | N/A | NO | NICE-TO-HAVE |
+| **Verified resources** (email/phone verification) | YES | N/A | NO | ANTI-SCOPE (platform setup, not daily workflow) |
+| **Stripe integration** | YES | N/A | NO | NICE-TO-HAVE |
+| **Delegation credentials** | YES | N/A | NO | ANTI-SCOPE (enterprise only) |
+| **Login/auth** (OAuth PKCE flow) | YES | OAuth setup | YES | TABLE STAKES |
+| **Slots/availability query** | YES | N/A | YES | TABLE STAKES |
+| **Destination calendars** | YES | N/A | YES | NICE-TO-HAVE |
+| **Selected calendars** | YES | N/A | YES | NICE-TO-HAVE |
+| **Booking attendees** | YES | N/A | YES | TABLE STAKES |
+| **Booking confirm/decline** | YES | N/A | YES | TABLE STAKES |
+| **Private links** | YES | N/A | NO | NICE-TO-HAVE |
+| **Out-of-office** | YES (org only) | N/A | YES | NICE-TO-HAVE |
+| **Me/profile** | YES | N/A | YES | TABLE STAKES |
+
+### gcalcli (Domain Reference) — What Calendar CLI Users Expect
+
+| Feature | gcalcli | @calcom/cli | Ours | Classification |
+|---------|---------|-------------|------|----------------|
+| **Agenda view** (today's/week's events) | YES (core feature) | NO (just list) | YES | TABLE STAKES |
+| **Week calendar view** (calw) | YES | NO | NO | NICE-TO-HAVE |
+| **Month calendar view** (calm) | YES | NO | NO | NICE-TO-HAVE |
+| **Quick-add event** (natural language) | YES | NO | NO | NICE-TO-HAVE |
+| **Event reminders** | YES | NO | NO | NICE-TO-HAVE |
+| **ICS import** | YES | NO | NO | NICE-TO-HAVE |
+| **Updates since datetime** | YES | NO | YES (sync) | TABLE STAKES |
+| **Search events** | YES (text search) | NO | YES (FTS5) | TABLE STAKES |
+| **Colored output** | YES | NO | YES | TABLE STAKES |
+| **Configurable output format** | YES (--tsv, etc.) | JSON only | YES (--json, table) | TABLE STAKES |
+
+## Table Stakes Summary
+
+Features that MUST be in our CLI (from both competitors + domain expectations):
+
+| # | Feature | Source | Priority |
+|---|---------|--------|----------|
+| 1 | Booking CRUD (list, get, create, cancel, reschedule) | @calcom/cli | P1 |
+| 2 | Event Type CRUD (list, get, create, update, delete) | @calcom/cli | P1 |
+| 3 | Schedule CRUD (list, get, create, update, delete) | @calcom/cli | P1 |
+| 4 | Calendar connections (list, check) | @calcom/cli | P1 |
+| 5 | Agenda view (today's bookings, formatted) | gcalcli | P1 |
+| 6 | Search (full-text across bookings) | gcalcli | P1 |
+| 7 | Slot/availability query | @calcom/cli | P1 |
+| 8 | Conferencing apps (list, default) | @calcom/cli | P1 |
+| 9 | Webhooks CRUD | @calcom/cli | P1 |
+| 10 | Teams CRUD | @calcom/cli | P1 |
+| 11 | Me/profile | @calcom/cli | P1 |
+| 12 | Booking confirm/decline | @calcom/cli | P1 |
+| 13 | Colored/formatted output | gcalcli | P1 |
+| 14 | --json output mode | Standard | P1 |
+| 15 | Attendee management | @calcom/cli | P1 |
+
+## Anti-Scope Items (with cost analysis)
+
+| Feature | Why Anti-Scope | % Users Need | Competitor has it? |
+|---------|---------------|-------------|-------------------|
+| OAuth client management | Platform developer feature, not scheduling workflow | <5% | @calcom/cli (platform tier) |
+| Managed users | Platform feature for multi-tenant apps | <5% | @calcom/cli (platform tier) |
+| Organization-level ops (131 endpoints) | Requires org plan, enterprise-only | <10% | @calcom/cli |
+| Verified resources | One-time setup, not daily workflow | <5% | @calcom/cli |
+| Delegation credentials | Enterprise SSO feature | <2% | @calcom/cli |
+| Routing forms | Niche feature, web UI is better for form building | <10% | @calcom/cli |
+
+None of these anti-scope items have demand from users with >100 stars. The @calcom/cli has 8 stars total, so even its full feature set has no proven user demand. Our anti-scope decisions are safe.
+
+## Key Insight
+
+@calcom/cli has 46 command categories but is a pure API wrapper — no agenda, no search, no analytics, no health checks. gcalcli proves that calendar CLI users expect **agenda views and search**, not just CRUD. Our differentiator is combining @calcom/cli's API coverage with gcalcli's workflow intelligence, plus a local data layer that neither has.
diff --git a/docs/plans/2026-03-27-feat-calcom-cli-power-user-workflows.md b/docs/plans/2026-03-27-feat-calcom-cli-power-user-workflows.md
new file mode 100644
index 00000000..2a1a1cf9
--- /dev/null
+++ b/docs/plans/2026-03-27-feat-calcom-cli-power-user-workflows.md
@@ -0,0 +1,124 @@
+---
+title: "Power User Workflows: Cal.com CLI"
+type: feat
+status: active
+date: 2026-03-27
+phase: "0.5"
+api: "cal.com"
+---
+
+# Power User Workflows: Cal.com CLI
+
+## API Archetype: Scheduling Platform (Hybrid)
+
+Combines elements of:
+- **Project Management** — Event types = task types, bookings = tasks with states, teams with memberships
+- **CRM** — Attendees are contacts, booking pipeline tracks conversion from slot → booking → completion
+- **Infrastructure** — Calendar connections are integrations that break, conferencing apps need health checks
+
+## All 12 Workflow Ideas
+
+### 1. `agenda` — Today's Bookings Briefing
+- **What:** Show today's/this week's bookings with attendee info, times, event types, conferencing links
+- **API calls:** GET /v2/bookings?status=upcoming&afterStart=today&beforeEnd=tomorrow&sortStart=asc
+- **Frequency:** Daily (3) | **Pain:** High (3) — must open web UI | **Feasibility:** Easy (3) | **Uniqueness:** 3
+- **Total: 12/12**
+
+### 2. `search` — Full-Text Booking Search
+- **What:** FTS5 search across all synced bookings by attendee name/email, title, description
+- **API calls:** Sync bookings to SQLite → FTS5 MATCH query (no live API needed)
+- **Frequency:** Daily (3) | **Pain:** High (3) — no offline search exists | **Feasibility:** Easy (3) | **Uniqueness:** 3
+- **Total: 12/12**
+
+### 3. `stats` — Booking Analytics
+- **What:** Aggregate bookings: total, cancellation rate, show rate, most popular event types, busiest days/hours
+- **API calls:** Local DB query on synced bookings → aggregate by status/event type
+- **Frequency:** Weekly (2) | **Pain:** High (3) — no built-in analytics | **Feasibility:** Easy (3) | **Uniqueness:** 3
+- **Total: 11/12**
+
+### 4. `doctor` — Calendar + API Health Check
+- **What:** Check all calendar connections, conferencing apps, API auth, schedule validity
+- **API calls:** GET /v2/me → GET /v2/calendars/connections → GET /v2/calendars/{cal}/check → GET /v2/conferencing → GET /v2/schedules
+- **Frequency:** On-demand (2) | **Pain:** High (3) — sync issues are #1 complaint | **Feasibility:** Easy (3) | **Uniqueness:** 3
+- **Total: 11/12**
+
+### 5. `free` — Available Time Slots
+- **What:** Show when you're available for a specific event type over next N days
+- **API calls:** GET /v2/slots?username=X&eventTypeSlug=Y&start=A&end=B&timeZone=Z
+- **Frequency:** Daily (3) | **Pain:** High (3) — need to open app | **Feasibility:** Medium (2) — needs slot parsing | **Uniqueness:** 3
+- **Total: 11/12**
+
+### 6. `conflicts` — Double-Booking Detection
+- **What:** Find overlapping bookings across calendars, detect scheduling conflicts
+- **API calls:** GET /v2/calendars/busy-times + sync bookings → time range overlap detection in SQLite
+- **Frequency:** Weekly (2) | **Pain:** High (3) — silent double-books | **Feasibility:** Medium (2) | **Uniqueness:** 3
+- **Total: 10/12**
+
+### 7. `stale` — Unused Event Type Finder
+- **What:** Find event types with zero bookings in last N days, candidates for cleanup
+- **API calls:** Event types + bookings in local DB → cross-reference on eventTypeId
+- **Frequency:** Monthly (1) | **Pain:** Medium (2) | **Feasibility:** Easy (3) | **Uniqueness:** 3
+- **Total: 9/12**
+
+### 8. `unconfirmed` — Pending Booking Triage
+- **What:** List unconfirmed bookings, allow bulk confirm/decline
+- **API calls:** GET /v2/bookings?status=unconfirmed → POST confirm/decline
+- **Frequency:** Daily (3) | **Pain:** Medium (2) | **Feasibility:** Easy (3) | **Uniqueness:** 3
+- **Total: 11/12**
+
+### 9. `clone` — Event Type Cloning
+- **What:** Clone event type to another team or as personal copy
+- **API calls:** GET /v2/event-types/{id} → POST /v2/event-types or /v2/teams/{id}/event-types
+- **Frequency:** Monthly (1) | **Pain:** High (3) | **Feasibility:** Easy (3) | **Uniqueness:** 3
+- **Total: 10/12**
+
+### 10. `noshow` — No-Show Detection
+- **What:** Find past bookings not marked completed/absent, track no-show rate
+- **API calls:** Local DB → filter past unmarked → POST mark-absent
+- **Frequency:** Weekly (2) | **Pain:** Medium (2) | **Feasibility:** Easy (3) | **Uniqueness:** 3
+- **Total: 10/12**
+
+### 11. `export` — Booking Data Export
+- **What:** Export bookings to CSV/JSON for external analytics
+- **API calls:** Local DB → SELECT → format
+- **Frequency:** Monthly (1) | **Pain:** Medium (2) | **Feasibility:** Easy (3) | **Uniqueness:** 3
+- **Total: 9/12**
+
+### 12. `reassign` — Bulk Booking Reassignment
+- **What:** Move upcoming bookings from one host to another
+- **API calls:** GET bookings → filter by host → POST /v2/bookings/{uid}/reassign/{userId}
+- **Frequency:** Monthly (1) | **Pain:** High (3) | **Feasibility:** Easy (3) | **Uniqueness:** 3
+- **Total: 10/12**
+
+## Validation Against API Capabilities
+
+All 12 workflows validated against OpenAPI spec. Every required endpoint exists with the needed query parameters. Key validations:
+- `afterStart`, `beforeEnd`, `status`, `attendeeEmail`, `eventTypeId` filters on GET /v2/bookings ✓
+- GET /v2/slots supports username, eventTypeSlug, start, end, timeZone ✓
+- GET /v2/calendars/{cal}/check endpoint exists ✓
+- POST /v2/bookings/{uid}/confirm, /decline, /mark-absent, /reassign/{userId} all exist ✓
+- `afterUpdatedAt` supports incremental sync ✓
+
+## Top 7 for Implementation (Phase 4 Priority 2)
+
+| Priority | Name | Score | What It Does |
+|----------|------|-------|-------------|
+| 1 | **agenda** | 12 | Today's bookings with attendee info and times |
+| 2 | **search** | 12 | FTS5 full-text search across all bookings |
+| 3 | **stats** | 11 | Booking analytics: show rate, cancellation rate, busiest times |
+| 4 | **doctor** | 11 | Calendar connections, conferencing, API health check |
+| 5 | **free** | 11 | Available time slots for next N days |
+| 6 | **unconfirmed** | 11 | Pending bookings triage with bulk confirm/decline |
+| 7 | **conflicts** | 10 | Detect double-bookings and overlapping meetings |
+
+## Naming Pass
+
+| Command | Completes "I need to check ___" | Max 9 chars | No hyphens | No collision |
+|---------|--------------------------------|-------------|------------|-------------|
+| agenda | "my agenda" | 6 ✓ | ✓ | ✓ |
+| search | "for a meeting" | 6 ✓ | ✓ | ✓ |
+| stats | "my booking stats" | 5 ✓ | ✓ | ✓ |
+| doctor | "my calendar health" | 6 ✓ | ✓ | Standard |
+| free | "when I'm free" | 4 ✓ | ✓ | ✓ |
+| unconfirmed | "unconfirmed bookings" | 11 — over limit but clear | ✓ | ✓ |
+| conflicts | "for conflicts" | 9 ✓ | ✓ | ✓ |
diff --git a/docs/plans/2026-03-27-feat-calcom-cli-research.md b/docs/plans/2026-03-27-feat-calcom-cli-research.md
new file mode 100644
index 00000000..831d1d14
--- /dev/null
+++ b/docs/plans/2026-03-27-feat-calcom-cli-research.md
@@ -0,0 +1,56 @@
+---
+title: "Research: Cal.com CLI"
+type: feat
+status: active
+date: 2026-03-27
+phase: "1"
+api: "cal.com"
+---
+
+# Research: Cal.com CLI
+
+## Spec Discovery
+- **Official OpenAPI spec:** https://github.com/calcom/cal.com/blob/main/docs/api-reference/v2/openapi.json
+- **Source:** GitHub repo, confirmed via discussion #17565
+- **Format:** OpenAPI 3.0.0 JSON (1.1MB)
+- **Total paths:** 181 (103 user-level, 78 org-level)
+- **Total operations:** 285 (154 user-level)
+- **Resource categories:** bookings, event-types, schedules, calendars, conferencing, webhooks, teams, slots, me, oauth-clients, verified-resources, routing-forms, stripe, selected-calendars, destination-calendars, api-keys
+- **API version header:** `cal-api-version: 2026-02-25` (date-based, required)
+
+## Competitors (Deep Analysis)
+
+### @calcom/cli (8 stars)
+- **Repo:** https://github.com/calcom/companion (packages/cli/)
+- **Language:** TypeScript (98.6%)
+- **Commands:** 46 command categories (auto-generated from OpenAPI)
+- **Last commit:** February 2026
+- **Maintained:** Yes (active development)
+- **Notable features:** OAuth PKCE login, full API v2 coverage, openapi-ts code generation
+- **Weaknesses:** Pure API wrapper. No agenda view, no search, no analytics, no health checks. 8 stars despite Cal.com's 34k. Requires Node runtime.
+
+### gcalcli (3k+ stars) — Domain Reference
+- **Repo:** https://github.com/insanum/gcalcli
+- **Language:** Python
+- **Commands:** 11 (agenda, calw, calm, list, edit, add, quick, import, remind, updates, init)
+- **Maintained:** Yes
+- **Notable features:** Agenda view, week/month calendars, colored output, reminders, search
+- **Relevance:** Proves demand for calendar CLIs
+
+## User Pain Points
+> "Some API endpoints don't work properly... resorting to tRPC calls" — Issue #14706
+> "Workflows can only be created/edited through the UI" — Issue #25560
+> Calendar sync issues (Google #8376, Outlook #3546) are the #1 complaint
+
+## Auth Method
+- **Type:** Bearer token (API key prefix: `cal_live_`) or OAuth 2.0 PKCE
+- **Env var:** `CAL_COM_API_KEY`
+- **Rate limit:** 120 req/min
+
+## Strategic Justification
+@calcom/cli has 8 stars vs Cal.com's 34k — that's a vacuum, not competition. It's a pure API wrapper with no workflow intelligence. gcalcli (3k stars) proves calendar CLI demand. Our differentiators: SQLite data layer with FTS5, booking analytics, agenda view, Go single binary, agent-native flags.
+
+## Target
+- **Commands:** 40+ (15 CRUD + 7 workflows + 7 data layer + 11 supporting)
+- **Differentiator:** Local SQLite + FTS5 search + booking analytics + agenda
+- **Quality bar:** Grade A (80+/100)
diff --git a/docs/plans/2026-03-27-feat-calcom-cli-visionary-research.md b/docs/plans/2026-03-27-feat-calcom-cli-visionary-research.md
new file mode 100644
index 00000000..9465b4f9
--- /dev/null
+++ b/docs/plans/2026-03-27-feat-calcom-cli-visionary-research.md
@@ -0,0 +1,151 @@
+---
+title: "Visionary Research: Cal.com CLI"
+type: feat
+status: active
+date: 2026-03-27
+phase: "0"
+api: "cal.com"
+---
+
+# Visionary Research: Cal.com CLI
+
+## Overview
+
+Cal.com is open-source scheduling infrastructure ("the open-source Calendly alternative") with 34k+ GitHub stars. It serves businesses, freelancers, and developers who need scheduling automation. The API v2 has 181 paths / 285 operations covering bookings, event types, schedules, calendars, teams, organizations, webhooks, conferencing, slots, and more. The official @calcom/cli exists in the companion repo (8 stars, TypeScript, 46 command categories) but has near-zero adoption — it's an auto-generated API wrapper with no workflow intelligence. API v1 is deprecated and shuts down April 8, 2026 — making v2-native tooling timely.
+
+The strategic opportunity: build a CLI that makes scheduling management instant from the terminal — with a local data layer that enables offline booking search, availability analysis, schedule health monitoring, and team scheduling insights that the web UI makes tedious. gcalcli (3k+ stars for Google Calendar) proves developer demand for calendar CLIs exists.
+
+## API Identity
+
+- **Domain:** Scheduling / Calendar Management
+- **Primary users:** (1) Business owners managing their booking flow, (2) Engineering managers coordinating team availability, (3) Developers building scheduling integrations, (4) Ops/support staff handling booking changes
+- **Core entities:** Bookings, Event Types, Schedules, Calendars, Teams, Organizations, Webhooks, Slots, Attendees, Conferencing
+- **Base URL:** `https://api.cal.com`
+- **Auth:** Bearer token (API key prefixed `cal_live_`), OAuth 2.0 with PKCE
+- **Rate limit:** 120 req/min (API key), upgradeable to 200-800
+- **Versioning:** `cal-api-version` header (date-based, latest: `2026-02-25`)
+- **Pagination:** `take` + `skip` with envelope: `{ status, data, pagination: { totalItems, hasNextPage, ... } }`
+- **v1 deprecated:** Shutting down April 8, 2026
+- **Spec:** OpenAPI 3.0.0 at `docs/api-reference/v2/openapi.json` in repo
+
+### Data Profile
+
+| Dimension | Assessment |
+|-----------|-----------|
+| Write pattern | Mutable (bookings transition: upcoming -> past/cancelled/rescheduled; event types are editable) |
+| Volume | Medium (hundreds to low thousands of bookings per account, tens of event types) |
+| Real-time | Webhooks (outbound only — booking.created, booking.cancelled, etc.), NO WebSocket/SSE for clients |
+| Search need | HIGH — users need to find bookings by attendee, date range, status; find available slots |
+
+## Usage Patterns (Top 5 by Evidence)
+
+| # | Pattern | Evidence Score | What It Needs |
+|---|---------|---------------|---------------|
+| 1 | **Booking management** (create, cancel, reschedule, list upcoming) | 8/10 | CRUD + status filtering + date ranges |
+| 2 | **Calendar sync troubleshooting** (Google/Outlook integration issues) | 7/10 | Doctor command checking calendar connections + busy-time inspection |
+| 3 | **Availability/slot checking** (when am I free? when can someone book me?) | 7/10 | Slot queries with time range + timezone + event type |
+| 4 | **Schedule/availability configuration** (set working hours, block time, OOO) | 6/10 | Schedule CRUD + OOO management |
+| 5 | **Team scheduling management** (who's available, team event types) | 6/10 | Team queries, member schedules, team event types |
+
+**Evidence sources:**
+- Cal.com GitHub issues (#14706: missing endpoints, #25560: workflow API, #3546/#8376: sync issues)
+- n8n/Zapier Cal.com integrations (cross-platform evidence)
+- Official companion CLI structure (46 command categories)
+- Trustpilot reviews citing booking management and sync pain points
+- Cal.com docs featuring availability as core product value prop
+
+## Tool Landscape
+
+### Forge/Platform CLIs
+| Tool | Stars | Language | Type | Commands | Maintained |
+|------|-------|----------|------|----------|------------|
+| @calcom/cli (official, in calcom/companion) | 8 | TypeScript | API Wrapper | 46 categories | Yes (2026) |
+
+### Workflow Overlays
+None developer-native. n8n, Zapier, Make.com provide no-code automation but not CLI workflows.
+
+### Alternative UX (Calendar Domain)
+| Tool | Stars | Language | Relevance |
+|------|-------|----------|-----------|
+| gcalcli | 3k+ | Python | Google Calendar CLI — proves demand exists |
+| calcure | 500+ | Python | TUI calendar/task manager — generic, not API-connected |
+| calcurse | 1.1k+ | C | TUI calendar — local only |
+
+### Data Tools
+None. Zero tools sync Cal.com data locally for offline search/analysis.
+
+### Integration Tools
+- n8n Cal.com trigger (workflow automation platform)
+- Zapier Cal.com integration (no-code)
+- Make.com Cal.com app (visual workflow)
+- cal-pr-agent (5 stars, PR automation for Cal.com dev)
+
+**Key finding:** The Cal.com ecosystem has ZERO non-wrapper tools. No discrawl-equivalent. No offline search, no analytics dashboards, no backup tools. The entire data-tool and workflow-tool lanes are empty. gcalcli's 3k stars for Google Calendar proves developer appetite for scheduling CLIs.
+
+## Workflows
+
+### 1. Daily Agenda
+- **Steps:** GET /v2/bookings?status=upcoming&afterStart=today&beforeEnd=tomorrow → group by time → show attendees
+- **Frequency:** Daily
+- **Pain point:** Must open web UI every morning to see today's meetings
+- **Proposed:** `calcom-pp-cli agenda` — today's bookings with attendee info, times, event types
+
+### 2. Availability Finder
+- **Steps:** GET /v2/slots?username=X&eventSlug=Y&startTime=A&endTime=B → parse windows → format as time blocks
+- **Frequency:** Multiple times daily when coordinating
+- **Pain point:** Need to open Cal.com or share link just to see own availability
+- **Proposed:** `calcom-pp-cli free --days 7` — show free windows for next N days
+
+### 3. Schedule Health Check
+- **Steps:** GET /v2/schedules → GET /v2/bookings?status=upcoming → cross-reference → check for conflicts
+- **Frequency:** Weekly
+- **Pain point:** No way to audit schedule health; sync issues are #1 complaint
+- **Proposed:** `calcom-pp-cli health` — check calendar connections, find conflicts, report utilization
+
+### 4. Booking Analytics
+- **Steps:** Sync all bookings → aggregate by event type → compute show/cancel rates → identify trends
+- **Frequency:** Weekly/Monthly
+- **Pain point:** No built-in analytics; callytics web dashboard is the only option (0 stars)
+- **Proposed:** `calcom-pp-cli stats --days 30` — show rate, cancellation rate, busiest days
+
+### 5. Stale Event Type Cleanup
+- **Steps:** GET /v2/event-types → GET /v2/bookings?eventTypeId=X for each → flag unused
+- **Frequency:** Monthly
+- **Pain point:** Event types accumulate, no easy way to identify unused ones
+- **Proposed:** `calcom-pp-cli stale --days 90` — find event types with zero bookings in N days
+
+## Architecture Decisions
+
+| Decision Area | Need Level | Choice | Rationale |
+|---------------|-----------|--------|-----------|
+| **Persistence** | HIGH | SQLite with domain tables (bookings, event_types, schedules, attendees) | Bookings accumulate; local DB enables offline search, trend analysis, and analytics without API calls |
+| **Real-time** | LOW | REST polling with `afterUpdatedAt` cursor | No WebSocket/SSE for clients; API supports date-range filtering for incremental sync |
+| **Search** | HIGH | FTS5 on booking titles/descriptions, attendee names/emails, event type names | Users need to find bookings by attendee, keyword, date range |
+| **Bulk** | MEDIUM | Paginate with `take=100` + `skip`, incremental sync | 120 req/min rate limit; sync fetches all pages incrementally with cursor |
+| **Cache** | MEDIUM | SQLite IS the cache; read commands query local DB; `--sync` triggers refresh | Avoids rate limits; enables offline analytics |
+
+## Top 5 Features for the World
+
+| # | Feature | Evidence | Impact | Feasibility | Uniqueness | Composability | Data Fit | Maintain | Moat | **Total** |
+|---|---------|----------|--------|-------------|------------|---------------|----------|----------|------|-----------|
+| 1 | **Booking search** (FTS5 across all bookings) | 3 | 3 | 2 | 2 | 2 | 2 | 1 | 1 | **16/16** |
+| 2 | **Agenda** (today's bookings, formatted) | 2 | 3 | 2 | 2 | 2 | 2 | 1 | 0 | **14/16** |
+| 3 | **Schedule health** (gaps, conflicts, utilization) | 2 | 2 | 2 | 2 | 2 | 2 | 1 | 1 | **14/16** |
+| 4 | **Free windows** (show availability) | 2 | 3 | 1 | 2 | 1 | 1 | 1 | 1 | **12/16** |
+| 5 | **Stale finder** (unused event types) | 1 | 2 | 2 | 2 | 2 | 2 | 1 | 0 | **12/16** |
+
+All 5 features score >= 12 — all are must-haves.
+
+## Sources
+
+- [Cal.com GitHub](https://github.com/calcom/cal.com) — 34k+ stars
+- [Cal.com API v2 Docs](https://cal.com/docs/api-reference/v2/introduction) — 181 paths, 285 operations
+- [OpenAPI Spec](https://github.com/calcom/cal.com/blob/main/docs/api-reference/v2/openapi.json) — 1.1MB JSON
+- [Cal.com Companion/CLI](https://github.com/calcom/companion) — 8 stars, 46 command categories
+- [API v1→v2 Migration](https://cal.com/docs/api-reference/v2/v1-v2-differences) — v1 shutdown April 8, 2026
+- [GitHub Issue #14706](https://github.com/calcom/cal.com/issues/14706) — Missing API endpoints
+- [GitHub Issue #25560](https://github.com/calcom/cal.com/issues/25560) — Workflow API request
+- [GitHub Issues #3546, #8376](https://github.com/calcom/cal.com/issues/3546) — Calendar sync problems
+- [n8n Cal.com Integration](https://n8n.io/integrations/cal-trigger/) — Workflow automation
+- [gcalcli](https://github.com/insanum/gcalcli) — 3k+ stars, proves calendar CLI demand
+- [calcure TUI](https://github.com/anufrievroman/calcure) — Terminal calendar alternative
diff --git a/docs/plans/2026-03-27-fix-calcom-cli-audit.md b/docs/plans/2026-03-27-fix-calcom-cli-audit.md
new file mode 100644
index 00000000..84d162c3
--- /dev/null
+++ b/docs/plans/2026-03-27-fix-calcom-cli-audit.md
@@ -0,0 +1,45 @@
+---
+title: "Non-Obvious Insight Review: Cal.com CLI"
+type: fix
+status: active
+date: 2026-03-27
+phase: "3"
+api: "cal.com"
+---
+
+# Non-Obvious Insight Review: Cal.com CLI
+
+## Automated Scorecard Baseline: 55/100 (Grade C)
+
+| Dimension | Score | Gap | Fix |
+|-----------|-------|-----|-----|
+| Output Modes | 10/10 | — | Good |
+| Auth | 8/10 | Missing cal-api-version header | Add header to client.go |
+| Error Handling | 10/10 | — | Good |
+| Terminal UX | 9/10 | No color | Add color later |
+| README | 5/10 | No cookbook, no comparison | Add in Phase 4 P7 |
+| Doctor | 10/10 | — | Good |
+| Agent Native | 8/10 | — | Good |
+| Local Cache | 10/10 | — | Good |
+| Breadth | 8/10 | — | Good (222 commands) |
+| Vision | 8/10 | Generic store | Replace with domain tables |
+| Workflows | 2/10 | No domain workflows | Add 7 workflow commands |
+| Insight | 0/10 | No insight commands | Add stats, stale, conflicts |
+| Sync Correctness | 0/10 | Generic sync | Rewrite with afterUpdatedAt |
+| Dead Code | 0/5 | Dead code present | Audit in Phase 4.6 |
+
+## Critical Issues
+1. Missing `cal-api-version` header — API calls will 400
+2. Generic store — JSON blob, not domain columns
+3. No workflow commands — the product is missing
+4. Wrong binary name — cal-com-user-cli, not calcom-pp-cli
+5. Complex body fields skipped — booking create needs --stdin
+
+## GOAT Plan (Phase 4 priorities)
+- P0: Domain data layer (bookings, attendees, event_types tables + FTS5 + sync)
+- P1: Table stakes (cal-api-version header, CRUD verification)
+- P2: 7 workflow commands (agenda, search, stats, free, unconfirmed, conflicts, stale)
+- P3: Name normalization (calcom-pp-cli) + command name cleanup
+- P4: Scorecard fixes + dead code audit
+- P5: Tests
+- P6-7: Distribution + README polish

← 49f5d8b7 fix(scorecard): fix PassRate units, gate sync path-param cre  ·  back to Cli Printing Press  ·  fix(skill): enforce Phase 4.9 agent readiness review dispatc e3a07f7b →