db-aeon/joshu-oss/ea-scheduling

Claude Code and agent skill by db-aeon/joshu-oss

Trust tier 1
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Meeting-mail scheduling. Kanban ea-sched-*; Calendly fallback.

Install

npx vskill@latest install db-aeon/joshu-oss/ea-scheduling

SKILL.md

EA Scheduling

Meeting negotiation on board `ea-scheduling`. Ingest no longer opens `ea-sched-ingress` — mail ingress workers file the email first, then spawn meeting tasks here via `scheduling_*` MCP.

Boardkind:Job
`ea-scheduling`meetingCheck live owner Google availability → book on owner Google Calendar (Composio) → kanban_block / kanban_complete
`ea-sched-ingress`ingressLegacy — no new ingest tasks. Existing cards: match/create on ea-scheduling → kanban_complete

Meeting workers never book from mail ingress alone — ingress filing + `scheduling_create_meeting_task` first.


Detect mode

kanban_show()

kind: meeting → Meeting. kind: ingress on `ea-sched-ingress` → Legacy ingress only.

jChat — meeting status / follow-up questions

When the owner asks in jChat (not a Kanban worker): "what meetings need follow-up?", "which threads are blocked?", "did we send yet?", "what's waiting on replies?" — you are answering scheduling status, not generic recall.

  1. `skill_view("ea-scheduling")` if not already loaded.
  2. `scheduling_list_meeting_tasks` — use `block_reason` and `recent_comments` on each task; do not infer from body alone.
  3. Before saying outreach was not sent, read source_paths and verify the mail thread (see Study the thread before sending).

Spawned from mail ingress (2026-06)

When `ea-mail-ingress` filing is done and the ingress task has `scheduling_eligible: true`:

  1. `coordination_list_active` with ingress thread_id + source_path — if open task on scope, handoff only (skip create).
  2. `scheduling_list_meeting_tasks` — match open/blocked meeting on `ea-scheduling` by thread_id / subject.
  3. Match → `scheduling_handoff_meeting_task` with neutral summary of this mail.
  4. No match → `scheduling_create_meeting_task` — always pass `threadId` + `provider` from the ingress body (Joshu dedupes: returns action: existing_thread if an open meeting already exists for that thread → then `scheduling_handoff_meeting_task` instead).
  5. For owner intro handoff ("Copying [companion] to suggest times") you may offer slots + nylas_send_message without a meeting task — see Owner self-introduction handoff. Study the thread first — Study the thread before sending.

Hard stop: If ingress has `agent_authorized: false` or `scheduling_eligible: false` — do not create meeting tasks, do not send mail. File-only mail is not your job on that card.

One booking per coordination scope: After a successful browser booking on a counterparty appointment link, `kanban_complete` immediately — never re-navigate the same URL in the same task. Preflight with `coordination_list_active` before create or book.

HITL defer at ingress: If the mail ingress worker chose path C (ea-playbook scheduling decision gate), there is no meeting task for you on this mail — owner review notes are in Projects/<slug>/. Do not create one retroactively unless the owner explicitly asks in jChat.

Call from `ea-mail-ingress` worker — Hermes kanban_create cannot cross to ea-scheduling; use `scheduling_*` MCP only.


Legacy ingress

Only for existing `ea-sched-ingress` cards — no new ingest tasks.

Why MCP, not kanban_create

Hermes pins ingress workers to `ea-sched-ingress`. Worker tools (kanban_create, kanban_list, kanban_comment on other ids) cannot create or list on `ea-scheduling`. CLI --board ea-scheduling from an ingress worker still creates on ingress (verified on a fleet box).

Use `mcp_joshu_connectors_scheduling_*` tools — Joshu writes to `ea-scheduling` via hermes-kanban-bridge.py.

Steps
  1. `kanban_show()` — read source_path, message_id, ingress_id, profile, workspace_path.
  1. `read_file` — <workspace_path>/<source_path> (under joshu's files).
  1. `scheduling_list_meeting_tasks` — open meetings on `ea-scheduling` (includes blocked).

Match on subject, participants, time hints — not thread_id alone. Prefer match, not a duplicate create.

  1. Match → `scheduling_handoff_meeting_task` — neutral summary of this mail only:
json
{
"taskId": "<matched meeting task_id>",
"sourcePath": "<source_path from ingress body>",
"messageId": "<message_id from ingress body>",
"from": "info@joshu.me",
"summary": "info@joshu.me replied: offered Thursday noon PT for in-person meet."
}

Do not judge whether waiting is over — the meeting worker decides. Then `kanban_complete` with metadata={"action":"matched","matched_meeting_task":"<id>"}.

  1. No match → `scheduling_create_meeting_task`:
json
{
"messageId": "<message_id from ingress body>",
"sourcePath": "<source_path>",
"subject": "Change tires",
"from": "the owner <owner work email>",
"timezone": "America/Los_Angeles"
}

Response includes task_id on board `ea-scheduling`. scheduling_comment_meeting_task to link ingress. kanban_complete(summary=…, metadata={"action":"new_meeting","new_meeting_task":"<task_id>"}).

Ingress — forbidden
  • kanban_create for meetings (lands on ingress)
  • kanban_list (orchestrator-only)
  • hermes kanban CLI / execute_code / SQLite
  • `terminal` / `nylas email send` (or any shell path to outbound mail — bypasses action guard; use MCP only)
  • nylas_send_message, nylas_list_events, any Nylas calendar write (nylas_create_event is hard-blocked)
  • Composio GMAIL_SEND_* / GMAIL_REPLY_* (use nylas_send_message for outbound mail)
  • scheduling_unblock_meeting_task
  • mark_scheduling_ingress_processed (legacy JSONL)
  • todo lists

Meeting

Job: check owner availability, book or negotiate.

Calendar source of truth
UseToolNotes
Owner busy/free`google_calendar_find_free_slots` (Joshu connectors MCP)Live FreeBusy API — omit items (default: primary + owner personal Gmail) or pass explicit calendar ids. Use `calendars.combined.free` for slot picking (union of busy across all queried calendars). Respects Google Show as free (transparent) events.
Event details (conflict explanation)google_calendar_list_eventsTitles + blocksAvailability / transparency only — never treat every event title as busy.
One event: guests, Meet linkgoogle_calendar_get_eventattendees with responseStatus, organizer, location, meetLink. Not the Composio Tool Router (GOOGLECALENDAR_EVENTS_GET there uses the wrong calendar account).
Agent ledger (read-only)nylas_list_eventsHistorical holds only — do not create on Nylas (hard-blocked)
Stale fallbackgbrain / connectors/calendar/google/ mirrorsOnly if live Composio fails — mirrors lag; owner may have edited calendar since sync

Owner can delete or move events on their real Google calendar. Never infer owner availability from Nylas alone, from agent calendar mirrors, or from event titles on list_events.

Wrong calendar scope: items: ["primary"] alone checks only the work calendar (owner work email). Owner meetings often live on a personal Gmail calendar — FreeBusy returns busy: [] on primary while the personal calendar is blocked. Omit `items` or include personal Gmail; always schedule from `calendars.combined.free`, not primary.free alone.

Transparent events: Google events marked Show as free (transparency: transparent, blocksAvailability: false) — e.g. some recurring Asteme blocks — do not appear in FreeBusy busy[]. A visible calendar title does not mean the owner is unavailable. Only google_calendar_find_free_slots determines bookable time (Composio GOOGLECALENDAR_FIND_FREE_SLOTS alone sees only one calendar account).

External attendees (not connected on this box): no calendar read — email + kanban_block.

Check availability (before proposing or booking)
  1. nylas_get_profile — timezone, primaryWorkEmail, personalEmail, working hours (default: 9 AM - 7 PM PT).
  2. `google_calendar_find_free_slots` — authoritative for busy/free. Prefer Joshu connectors MCP (wraps Composio GOOGLECALENDAR_FIND_FREE_SLOTS). Omit `items` so Joshu queries primary plus owner personal Gmail calendars (from profile + connected account). Or pass explicit ids, e.g. ["primary", "owner@gmail.com"]. Time window in owner timezone:
  • date + timezone for one local day, or timeMin / timeMax
  • time_min style when using Composio directly: 7 AM local on the first day; time_max midnight local after the last day (exclusive)
  • Response includes per-calendar busy[] / free[] and `calendars.combined` (union busy — schedule from `combined.free`). Free intervals filtered to minDurationMinutes (default 30). Pick slots within working hours.
  1. Optionally `google_calendar_list_events` same window only to name events on calendar — check blocksAvailability before mentioning a conflict:
json
{ "date": "2026-06-11", "timezone": "America/Los_Angeles" }

Responses include `timeAnchor` (owner-local now) and per-event `localDate` / `relativeDay` (today | tomorrow | yesterday | null). Use those — not UTC server time or Composio time_info — when saying today/tomorrow in summaries.

Temporal grounding (calendar summaries)
  • Authoritative now: each Joshu chat turn injects the owner's local date/time in a system message. Trust that over UTC timestamps in traces, Langfuse, or Composio meta tools.
  • Never label a day "today" because it is the first date in a query window (e.g. Wed when fetching "rest of this week" on Tuesday evening).
  • When warning about overlaps, name the weekday + date (Wed 6/17) and use relativeDay when present (tomorrow's wrap block, not today's if relativeDay is tomorrow).
  • Do not infer today from event ISO strings alone — convert to owner timezone and compare to timeAnchor.ownerLocalDate.
  1. Optionally nylas_list_events same window — see holds the companion already placed (avoid double-booking ledger).
  2. Pick slots that are free on live Google FreeBusy and fit working hours.
Workflow
  1. kanban_show() — source_paths, ingress_handoff, state, timezone, calendar_event_id.
  1. Verify task status against real data — never answer from memory alone. The task body may say "agent needs to send times" even though you already sent them in a prior session, cron run, or different thread. Before reporting a task as "not yet done," read every source_paths entry and check the thread for your sent replies (look for agent mailbox messages in Nylas threads, or agent from in Gmail threads). Also check whether a nylas_send_message was logged in the thread's message_ids. If multiple threads exist for the same contact, read both — don't assume they're the same conversation.
  1. read_file on every source_paths entry (and new paths from ingress_handoff).
Study the thread before sending

Do not pick recipients from the task title, subject line, or your memory of the thread. Read the mail carefully — message by message — before any nylas_send_message.

  1. Read the full thread in order — every message, not just the latest snippet. If the mirror truncates headers or bodies, fetch live metadata (nylas_get_message, or Composio GMAIL_FETCH_MESSAGE_BY_MESSAGE_ID with format: metadata) until you have complete To / CC / From for each message that matters.

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 90 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
5

Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/db-aeon/joshu-oss/ea-scheduling/badge)](https://verified-skill.com/skills/db-aeon/joshu-oss/ea-scheduling)

Something wrong with this skill or its page? Tell us.