--- name: evening-reflection description: > Use when setting up or running xTiles Evening Reflection — an end-of-day synthesis written to the Daily planner page as a "Day Characteristic" tile with a seed for tomorrow. Only Daily period is supported. Setup triggers: "set up evening reflection", "personalize my evening review", "connect reflection to tools", "onboard me into evening reflection". Run triggers: "reflect on my day", "characterize my day", "evening review", "wrap up my day", "what did I get done today". Also runs on schedule. Environment: this is the Claude / Cowork variant — it renders `show_widget` and `AskUserQuestion`. In ChatGPT Work, where every form is an inline `ask_user_input` / `genui` surface and `show_widget` does not exist, use `evening-reflection-with-gpt` instead. Environment triggers: "Evening Reflection in Claude", "the Claude version", "Claude Evening Reflection". allowed-tools: > mcp__xtiles__xtiles_get_current_user, mcp__xtiles__xtiles_get_user_timezone, mcp__xtiles__xtiles_get_planner_content, mcp__xtiles__xtiles_list_tasks, mcp__xtiles__xtiles_create_tasks, mcp__xtiles__xtiles_update_task, mcp__xtiles__xtiles_create_tiles_from_markdown_in_my_planner, mcp__xtiles__xtiles_get_page_layout, mcp__xtiles__xtiles_set_page_layout, mcp__xtiles__xtiles_get_workflow, mcp__claude_ai_Slack__slack_search_channels, mcp__claude_ai_Slack__slack_search_public_and_private, mcp__claude_ai_Slack__slack_read_channel, mcp__claude_ai_Slack__slack_read_thread, mcp__claude_ai_Gmail__search_threads, mcp__claude_ai_Gmail__get_thread, recent_chats, conversation_search, mcp__mcp-registry__suggest_connectors, AskUserQuestion, anthropic-skills:schedule, mcp__scheduled-tasks__create-scheduled-tasks --- # xTiles Evening Reflection — Setup & Daily Wrap-Up The evening bookend to the morning Daily Brief. Where the morning brief points forward at signals to act on, the evening reflection looks back: it synthesizes what actually happened today, optionally logs it as completed tasks, and seeds tomorrow. ## Three principles 1. **Survey first, write to xTiles last.** On setup and on the first manual run, nothing is created until the user has seen a preview and approved it. Only scheduled runs (with an approved config) act autonomously. 2. **Real data, not placeholders.** Always pull from the user's own past Claude chats via `recent_chats` (no connector needed) and from any connected tools before preview so the user sees live content. Never invent names, meetings, or messages — and never reconstruct the day from this session's context instead of reading it. 3. **Match the user's language** throughout the entire flow — match the language of the user's first message and adapt if they switch. On a **scheduled run** there is no user message: use the language of the scheduled-task config prompt, and if that is ambiguous, the language of the fetched content. Default to English when still unclear. **Every template, label, and example in this file is written in English as a placeholder** — translate them into the detected language, and never emit a label in a language the user has not used. 4. **Every write to the planner is immediately followed by a layout pass — automatically, no exceptions.** The instant the reflection tile is added in step 7, re-lay-out only that new tile into a justified grid (step 7's layout pass, via the shared `tile-layout` workflow) *before* anything else — before the CTA button, before the schedule widget, before any message to the user. This never waits for the user to ask, is never skipped as "not needed this time," and is never left for a later run. --- ## Algorithm **Period is always Daily.** At the start of setup, tell the user: "I'll set up your **Evening Reflection** — a short end-of-day synthesis written to your Daily planner page." Never ask which period to set up. If the user asks for Weekly or Monthly, say only the Daily reflection is currently supported. **Run mode — detect before step 1:** - **Scheduled run**: the incoming message contains `role:`, `tools:`, `evening_content:`, `tone:`, and `autolog:` (config injected by the `schedule` skill). Do not show the survey. Extract the config from the message. If a connector from the config is not detected — offer to walk the user through connecting it before continuing. Then jump to **step 4 (Silent data fetch)**. A scheduled run executes autonomously through to the written tile — but it still respects the `autolog` flag (only auto-creates tasks if it was approved at setup). - **Fast-track or fresh manual run**: proceed to step 1. --- ### 1. Fast-track If the user is specific ("reflect on my day using Slack and calendar") — skip the full survey. Minimum needed: which connectors to pull from — infer from the message, then check the detection table (step 2) to confirm availability. If a required connector is not detected — offer to walk the user through connecting it (see **How to connect connectors**); wait for confirmation. Pull only from connectors that are both mentioned and confirmed available. Jump to **step 4**. If the request is general — run the full flow. --- ### 2. Detect what's connected — silently, don't ask **Never ask the user what they have connected.** Detect it yourself by checking which MCP tools are present in this session, and treat that as the source of truth. The survey (step 3) is only about *preferences*, never about connection status. | Connector | Identifying MCP tools | |-----------|-----------------------------------------------------------------------------------------------------------------| | **Claude (past chats)** | `recent_chats`, `conversation_search` — **not a connector**: present by default, nothing to connect, and never offered in a connect flow | | xTiles | `mcp__xtiles__xtiles_create_tiles_from_markdown_in_my_planner`, `mcp__xtiles__xtiles_list_tasks` | | Slack | `mcp__claude_ai_Slack__slack_search_channels`, `mcp__claude_ai_Slack__slack_read_channel` | | Gmail | `mcp__claude_ai_Gmail__search_threads`, `mcp__claude_ai_Gmail__get_thread` | | Calendar | the available calendar/events MCP tool, if any | | Linear | `mcp__claude_ai_Linear__list_issues` | Build the **detected set** from this. Connecting is only ever raised in two cases: - **xTiles is the only hard requirement.** If xTiles is not detected — stop and walk the user through connecting it (see **How to connect connectors**). Wait for confirmation before continuing. - **The user explicitly wants a source that isn't detected** (e.g. picks "add another tool" in the survey, or names one). Then *offer* to connect it via `mcp__mcp-registry__suggest_connectors`. If they decline — just skip that source and continue. Never block the flow on an optional connector, and never prompt to connect something that is already detected. These connectors are external and optional — they are not shipped with this plugin. --- ### 3. Reflection preferences Reconcile the survey's source picks against the **detected set** from step 2: pre-check the tools that are already connected, pull only from detected sources, and treat an "Other…" / not-detected pick as the *only* trigger to offer connecting. Never re-prompt to connect something already detected. Ask three things (folded into the survey widget; inline in Claude Code): **3.1 What to reflect on each evening.** Options — include only those relevant to connected tools: - Slack threads you were active in *(only if Slack connected)* - Emails you sent / that needed action *(only if Gmail connected)* - Meetings & calls (from calendar/notes) *(if calendar/Granola connected)* - Tasks you completed today *(xTiles — on by default)* - Other (describe in next message) **3.2 Tone.** Single select: - **Honest coach** — direct, names weak days plainly, anti-fluff (default) - **Gentle** — supportive and encouraging - **Neutral** — plain factual summary, no editorializing **3.3 Auto-log completed tasks.** Single select: - **Yes, with a preview first** — show me the tasks before creating them, then do it automatically on scheduled runs (recommended default) - **Yes, automatically** — just create and complete them, no preview - **No** — don't auto-create tasks, only write the reflection tile **If Slack is selected and the user has not named channels:** call `mcp__claude_ai_Slack__slack_search_channels` with query `general`, show up to 6 channel names. Ask via `AskUserQuestion` (multi allowed): "Which channels reflect your real work? Pick all that matter." Include found channels plus a fixed **"Other — I'll type the names"** option. Add typed names as-is. **Ignored Slack noise (configurable).** By default, ignore automated/bot channels and alert streams (Sentry/error bots, build/deploy notifications, health/status channels). Do **not** hardcode specific company channel names — derive the filter from channel metadata (bot-posted, app-integration) and let the user add or remove channels. If the user names channels to always ignore, store them in the config. **General rule:** if the user writes something custom — add it as-is. Don't reshape it into a predefined option. --- ### 4. Silent data fetch **Silently, without messaging the user**, pull today's data. First resolve context: - `mcp__xtiles__xtiles_get_user_timezone` — the user's IANA timezone and current local datetime. Use it to define "today" (00:00–23:59 local) and to resolve dates. - `mcp__xtiles__xtiles_get_current_user` — the user's name, email, and xTiles user id. Do **not** rely on injected template variables for identity. Then pull from selected connectors: - **xTiles tasks (PRIMARY SOURCE)**: `mcp__xtiles__xtiles_list_tasks` with `completed: "true"`, `due_date_after`: today, `due_date_before`: tomorrow, `per_page: 50`. Repeat with `completed: "false"` for open tasks due today. Also `mcp__xtiles__xtiles_get_planner_content` with `period: "day"` and today's date for full day context. - **Slack**: `slack_search_public_and_private` with `on:[today] from:[user]` to find where the user was active, then `slack_read_thread` on the important threads. Apply the ignore filter from step 3. - **Gmail**: `mcp__claude_ai_Gmail__search_threads` for mail sent today and important received mail that needed action (`newer_than:1d`), then `get_thread` for sender/subject/threadId. - **Calendar / meeting notes** *(if connected)*: today's events; separate meetings-with-others (attendees > 1) from solo work blocks. - **Claude chat history (today)** — **always run, no connector needed**: call `recent_chats` with `after` = today 00:00 and `before` = now, both ISO-8601 in the user's timezone from `xtiles_get_user_timezone` (never UTC — an evening run in a +2 zone would otherwise pull the wrong day), `sort_order: "desc"`, ~10 chats. Page back with `before` set to the oldest chat you got while the results still fall inside today; stop at the first one that doesn't. Extract concrete *outcomes* — what was actually built, solved, decided, or shipped (e.g. "wrote the launch email", "fixed the auth bug", "researched competitors"). Ignore abandoned or purely exploratory threads. These outcomes feed both the reflection and the auto-log. - Use `conversation_search` only to close a specific gap — a thread that clearly continues earlier work, or a task from the xTiles list you suspect was finished in a chat and want to confirm before auto-logging it. One query per gap, `max_results: 5`, and keep only hits from today. Never sweep the archive. - **Exclude this workflow's own chats** — the reflection run itself, the morning `daily-brief` run, and any setup/survey conversation are machinery, not outcomes. "Ran my evening reflection" is never an achievement. - Keep each outcome's conversation URL as returned by the tool — it is what lets the reflection link back to where the work happened. Never build a chat URL by hand. - **If `recent_chats` is unavailable or errors** — treat it exactly like a failed connector below: drop the source, say so explicitly, and build the reflection from xTiles tasks and the remaining connectors. Never fall back to this session's own context, and never invent a day. Use only real data from connectors. If a connector call fails (error, timeout, 401) — record the failure and surface it explicitly later as "Could not fetch [connector] — connector error" (never silently write "No data"). --- ### 5. Auto-log preview & write (respect the autolog setting) Compare today's real activity — including outcomes pulled from Claude chat history — against the existing xTiles task list, and decide per activity: - **Close existing** — if the activity matches an **open** task due today (same work, even if worded differently), just mark that task complete with `mcp__xtiles__xtiles_update_task` (`completed: true`). Do **not** create a duplicate. - **Create + close** — if the activity has no matching task, create it with `mcp__xtiles__xtiles_create_tasks` and immediately mark it complete. - **Skip** — if a completed task for it already exists. Match generously on meaning, not exact wording (e.g. a Claude chat "wrote the launch email" closes an open task "Draft launch email"). **What counts as an activity** (derive categories from the data and the user's role — do not force a fixed founder/PM template): - 📞 Meetings & calls - 💬 Interviews / CustDev / user or partner conversations - 📝 Content created (posts, emails, docs, significant Slack messages) - 🤝 Partnership or relationship moves — new contacts, agreements, follow-ups - 🔧 Support / access granted - 🔬 Research, analysis, deep dives - 🛠 Materials prepared (decks, webinars) - 🗺 Strategic decisions or priority shifts **Behavior by `autolog` setting:** - **Yes, with a preview first** (and on the first manual run regardless): show the proposed list in chat, marking each as **new** or **closing an existing task** — `✅ [emoji] short specific title` for new, `☑️ closes: "[existing task]"` for matches — and ask via `AskUserQuestion`: "Log these for today?" → Apply all / Edit the list / Skip. Only after approval, apply them. - **Yes, automatically**: create without preview. - **No**: skip task creation entirely; go straight to the reflection tile. To create: `mcp__xtiles__xtiles_create_tasks` with `assignee_email` (from `get_current_user`), `due_date`: today (yyyy-MM-dd), `title`: short specific name with an emoji category prefix. Then mark each completed: `mcp__xtiles__xtiles_update_task` with `completed: true`. Avoid duplicates — never recreate a task that already exists for today. --- ### 6. Compose the reflection & preview in chat **Derive themes dynamically from ALL collected data — never from a template.** Determine: the main themes of the day; what actually moved something forward vs pure operations; opportunities (new contacts, ideas, competitive intel, insights); promises & follow-ups (what was promised, who needs a message). Apply the chosen **tone**. If the day was quiet, say so honestly — don't stretch it. Optional sections appear only if there is something genuinely valuable. Show the preview in chat with real content (not headings with "TBD"): ``` Here's your reflection for [actual date]: --- ✨ DAY CHARACTERISTIC — DD.MM.YYYY [1–2 sharp sentences — the tone and essence of the day, not a task list] 🎯 RESULTS - [What was done] - ... [If no strategic movement: "Operational day — little strategic progress"] 🌟 OPPORTUNITIES (only if non-trivial) - [Specific finds: partnerships, leads, competitor intel, ideas] → TOMORROW - [ ] Specific action with names — "Message X about Y", not "continue X" - [ ] max 3 items --- ``` After the preview, ask via `AskUserQuestion`: **Looks good — write it** / **Change something** / **Cancel**. On scheduled runs, skip approval and write directly. --- ### 7. Write to xTiles **Only after approval (or on a scheduled run).** Tool: `mcp__xtiles__xtiles_create_tiles_from_markdown_in_my_planner` - `period`: "day" - `date`: today in ISO 8601 - `markdown`: all sections in a **single call** — never split per section. **Append, don't clobber.** The evening reflection writes to the same Daily page the morning brief uses. First call `mcp__xtiles__xtiles_get_planner_content` for today; compare existing `###` headers; append only sections whose headers don't exist yet. If everything already exists, ask: replace, append anyway, or cancel. **One single tile.** The whole reflection is **one** `###` tile titled `✨ Day Characteristic — DD.MM.YYYY` — not separate tiles per section. The color annotations sit on the **two lines directly below the title** (no blank line between the title and the annotations): ``` ### ✨ Day Characteristic — DD.MM.YYYY @colorSize: LIGHTER @color: SAIL **[1–2 sharp sentences — the tone and essence of the day]** --- **🎯 Results** - [What was done] --- **🌟 Opportunities** - [Specific finds] --- **→ Tomorrow** - [ ] [Specific action with names — "Message X about Y", not "continue X"] - [ ] [max 3 items total] ⚠️ [unavailable connectors, only if some failed] ``` - `@colorSize` is always `LIGHTER`; `@color` is always `SAIL` for this tile. (Do **not** use plain names like "purple" — they will not render.) - Sections inside the tile are **bold subheaders** (`**🎯 Results**`), separated by `---` dividers — never separate `###` tiles. - Drop any optional section (Opportunities) entirely if there's nothing genuinely valuable — don't leave an empty header. **Content formatting inside the tile:** - Separate each item with a blank line — never a continuous block. - Slack/email entries that have a URL are Markdown hyperlinks with the priority emoji BEFORE the `[`, never inside the brackets. An outcome that came from a chat follows the same rule, linked to the conversation URL `recent_chats` returned — the chat title is the link text. If the tool returned no URL, write the title as plain text; never fabricate a `claude.ai` link. - Tomorrow's actions as task blocks (`- [ ] Task name`), one empty line between each — never a numbered list. - Append the final `⚠️ [unavailable connectors]` line only if a connector failed. **After a successful write — run these steps in order, no exceptions. Step 2 (the layout pass) is not optional and is never deferred, asked about, or judgment-called away — it runs automatically, immediately after every single write, before step 3's CTA button is even composed:** 1. Write `✅ Evening reflection saved.` 2. **Layout pass — mandatory, silent, automatic, every single run (scheduled runs included, fast-track included, any tile count included).** Using the `view_id` and `tile_ids` returned by the write call above (`tile_ids` is ordered to match the `###` sections you just wrote — here a single reflection tile), apply the shared justified-grid layout rules: call `mcp__xtiles__xtiles_get_workflow` with id `tile-layout` and follow it exactly — treat the tiles in `tile_ids` as its "added tiles" and the markdown you just composed as their content. **Layout hints for this workflow:** always exactly 1 tile (the reflection) · give it a generous width — max_width, or the largest free band next to existing tiles. Do not message the user about this pass, do not ask for confirmation, and never skip it — not even for a single tile or a scheduled run. (You may fetch `tile-layout` once per session and reuse it on later runs.) 3. Call `mcp__xtiles__xtiles_get_planner_content` for the same date/period, extract `view_id`. Call `show_widget` with the **CTA widget HTML** (see below), replacing `{VIEW_URL}` with `https://xtiles.app/{view_id}`. Translate the button label into the user's language. Never output a markdown link instead of the widget — the button must render every time. 4. Immediately continue to **step 8 (Schedule)** — do not skip, do not ask first. On error, say briefly what went wrong and offer to retry. --- ### 8. Schedule (optional) **After every successful manual write — show the schedule widget** (see below), regardless of survey answers. In Claude Code, ask inline: "Want me to run this every evening automatically? What time? (default: 9:00 PM)". - If the user schedules it — invoke `anthropic-skills:schedule`, then `mcp__scheduled-tasks__create-scheduled-tasks`. Pass to both: - **`prompt`**: full config assembled from setup — ``` Run evening reflection — role: {role} · tools: {tools} · evening_content: {content} · tone: {tone} · autolog: {on/preview/off} · schedule: daily-9pm ``` Replace all placeholders with real values. - **`schedule`**: cron derived from the widget. The widget sends `cron: HH:MM days:1-5` (weekdays) or `cron: HH:MM days:*` (every day) — parse both values and build: `M H * * 1-5` for weekdays, `M H * * *` for every day. Default `0 21 * * 1-5` (9:00 PM on weekdays) if not found. - **`timezone`**: from `mcp__xtiles__xtiles_get_user_timezone`. This prompt fires each evening and triggers `evening-reflection` in scheduled-run mode — the full config must be embedded so the survey is skipped. Confirm: "Done — your reflection will write to xTiles every [weekday evening / evening] at [time]." (say "weekday evening" if `days:1-5`, "every evening" if `days:*`) - If the user declines — acknowledge briefly. Either way, continue to **step 9 (Related workflows)** — do not stop here. --- ### 9. Related workflows **After every manual run, once step 8 is resolved** (scheduled or declined) — offer related workflows. Skip this on scheduled runs, which end silently after step 7. Ask via `AskUserQuestion` (single select): "Want to set up anything else on xTiles?" - 🌅 Daily Brief — a live morning brief from your connected tools - 📰 Today News — a daily news digest on topics you care about - 📊 Weekly Review — a weekly summary of what moved forward this week - Nothing else, thanks **Never list these as plain text requiring the user to retype a choice — always use the interactive question.** On selection, send the exact matching phrase to hand off to that skill (do not attempt to run it yourself): - Daily Brief → `Set workflow of Daily Brief (daily-brief) on xTiles MCP` - Today News → `Set workflow of Today News (today-news) on xTiles MCP` - Weekly Review → `Set workflow of Weekly Review (weekly-review) on xTiles MCP` - "Nothing else" — acknowledge briefly and stop. --- ## How to connect connectors Do not send the user to settings manually and do not give a URL to follow. Call `mcp__mcp-registry__suggest_connectors` — it renders interactive connect buttons directly in the Cowork UI. **Flow:** 1. Call `mcp__mcp-registry__suggest_connectors` with the names of missing connectors. 2. Show the **Done widget** (below) directly under the connector form. 3. The user clicks the connect buttons; auth runs natively. When finished, they click **"Done"**. 4. Confirm: "Connected. Continuing…" and resume from where the flow paused. --- ## Done widget HTML Show via `show_widget` immediately after calling `mcp__mcp-registry__suggest_connectors`. ```html ``` --- ## Survey widget HTML Show via `show_widget` at the start of setup in Cowork. After Submit, the user sends a string of answers to chat — process it and continue. ```html
I'll synthesize your day and write it to xTiles automatically — no need to ask each time.