getting-started
Skill509 starsChanged 3 months agoMITView on GitHub
Interactive post-onboarding tour that adapts to whatever data exists (calendar, Granola, or none). Use right after onboarding, or when the user says 'show me around', 'how do I start'. Also use proactively when the vault is < 7 days old. Not for the initial setup itself; use `setup`.
32 other projects use a version of this.
Adopted by
Most recently taken up by
- seayniclabs/homelab-infra-mcptheir own version, first seen Nov 8, 2026
- AnyOrgName/php-skillstheir own version, first seen Nov 8, 2026
- celigo/aitheir own version, first seen Nov 5, 2026
- orgiggly/claude-plugintheir own version, first seen Nov 2, 2026
- claude-world/director-mode-litetheir own version, first seen Nov 1, 2026
- seayniclabs/lathetheir own version, first seen Nov 1, 2026
Other versions32 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 32
- NVIDIA-NeMo/Curator★ 1.9ksame name
- aivrar/portable-hermes-agent★ 239same name
- GoogleCloudPlatform/race-condition★ 232same name
- taskade/mcp★ 170same name
- claude-world/director-mode-lite★ 80same name
- dylantarre/design-system-skills★ 50same name
- crewAIInc/skills★ 45same name
- aks129/HealthClawGuardrails★ 33same name
- ayrshare/ayrshare-social-media-api-claude-plugin★ 19same name
- CheehooLabs/SpureeSkills★ 18same name
22 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository153 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .claude/plugins/compound-engineering/CLAUDE.mdCLAUDE.md
- .cursor/rules/search-routing.mdcCursor rule
- anthropic-algorithmic-artSkill
- anthropic-brand-guidelinesSkill
- anthropic-doc-coauthoringSkill
- anthropic-docxSkill
- anthropic-frontend-designSkill
- anthropic-internal-commsSkill
- anthropic-mcp-builderSkill
- anthropic-pptxSkill
- anthropic-slack-gif-creatorSkill
- anthropic-theme-factorySkill
- anthropic-webapp-testingSkill
- anthropic-web-artifacts-builderSkill
- anthropic-xlsxSkill
- atlassian-setupSkill
- backup-nowSkill
- backup-restoreSkill
- backup-setupSkill
- calendar-setupSkill
- commitmentsSkill
- create-mcpSkill
- daily-planSkill
- daily-reviewSkill
- decision-logSkill
- delegate-checkSkill
- dex-backlogSkill
- dex-doctorSkill
- dex-improveSkill
- dex-obsidian-setupSkill
- dex-rollbackSkill
- dex-updateSkill
- dex-whats-newSkill
- diff-profileSkill
- enable-semantic-searchSkill
- goal-backlogSkill
- google-workspace-setupSkill
- granola-setupSkill
- identity-snapshotSkill
- industry-truthsSkill
- initiative-kickoffSkill
- integrate-mcpSkill
- journalSkill
- manage-capabilitiesSkill
- meeting-closeoutSkill
- meeting-prepSkill
- ms-teams-setupSkill
- pipedrive-setupSkill
- pipeline-syncSkill
- process-meetingsSkill
- product-briefSkill
- project-healthSkill
- prompt-improverSkill
- relationship-radarSkill
- reviewSkill
- save-insightSkill
- scrapeSkill
- skill-scoreSkill
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
28 rules. 0 are common, 20 are distinctive, and 8 are very specific to this project.
0
Common
Most of the 32 edited versions we read keep these.
20
Distinctive
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 16
After onboarding completion (Step 11)
- Very specific: line 23
Call check_onboarding_complete() from onboarding-mcp to verify vault status.
- Distinctive: line 29
Check what data sources are available:
- Distinctive: line 56
If more data exists, ask if they want to see full extent
- Distinctive: line 132
Use prompt_user tool. If prompt_user is not available, prompt in CLI with the same numbered options and capture the selection:
- Distinctive: line 153
If user selects "custom", ask for granular preferences:
- Distinctive: line 345
Update a marker file to remember this choice
- Distinctive: line 433
Use the same prompt_user and processing logic as Flow A (or CLI fallback).
- Distinctive: line 468
When user provides tool name/URL:
- Very specific: line 512
Follow /create-mcp skill flow:
- Distinctive: line 543
If user wants to connect Gmail/Calendar:
- Distinctive: line 562
Add Gmail MCP if they want
- Distinctive: line 567
If user mentions newsletters, RSS, or content consumption:
- Distinctive: line 635
After a few file edits, offer:
- Distinctive: line 655
After 3-4 accept prompts shown
- Distinctive: line 661
Trigger: Run this check if the vault is < 7 days old AND few or no integrations are connected.
- Distinctive: line 665
After completing the main pathway flow (A, B, or C) but before showing the completion message:
- Very specific: line 667
Read System/integrations/config.yaml (if it exists)
- Distinctive: line 669
If connected integrations <= 1 AND vault age < 7 days, run the concierge
- Distinctive: line 704
Only mention high_value items (score >= 5) — skip moderate and available
- Very specific: line 705
If the user says yes, run the setup skill (its setup field, e.g.
- Very specific: line 706
If the user says no/skip/later, move on without pressure
- Very specific: line 707
Don't show this section if the user already went through integration setup during onboarding Step 10 — check the .onboarding-complete …
- Distinctive: line 713
After any pathway completes:
- Very specific: line 748
Before showing suggestions, check System/usage_log.md:
- Distinctive: line 769
Don't show features they've already tried - focus on gaps.
- Distinctive: line 801
Before presenting choices, discover how much Granola data is available:
- Very specific: line 956
Call track_event with event_name getting_started_completed and properties:
“Common” is measured: kept by at least 6 in 10 of the 32 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
<!-- Generated from `.claude/skills/getting-started/SKILL.md` by `scripts/generate-agents-skills.py`. Do not edit. -->Purpose
Transform the post-onboarding experience from "blank chat window" to guided value delivery. Adaptive based on what data sources are available (calendar, Granola, or neither).
When to Run
- Automatically suggested at session start if vault < 7 days old
- User types
/getting-started - After onboarding completion (Step 11)
- User says they're not sure what to do next
Entry Point
Step 1: Verify Onboarding
Call check_onboarding_complete() from onboarding-mcp to verify vault status.
The first-week reveal already ran during onboarding. Do not repeat the first-week statistics or present them as a new discovery, even if an older completion marker suggests analysis was deferred. /getting-started is now the deeper tour.
Step 2: Environment Check
Check what data sources are available:
- Calendar: Try calling calendar MCP (if fails, not available)
- Granola: Call
granola_check_available()from granola-mcp
Based on results, route to appropriate flow.
Flow A: Has Calendar + Granola
The Deeper History Flow
Historical Data Discovery
👋 **Welcome back, [Name]!**
You have already seen this week's calendar snapshot, so I won't repeat it. Let's look at the deeper meeting history you can turn into useful context.
**Calendar:** ✅ Connected
**Granola:** ✅ Connected
I'll check how much Granola history is available before suggesting what to process.Then execute:
- Analyze Granola data extent using helper function (6 months by default)
- If more data exists, ask if they want to see full extent
- Present the historical summary
📊 **Your Granola history:**
**Granola data (last 6 months):**
• [N] meetings captured
• Going back [days_back] days (to [oldest_date])
• [M] unique people detected ([I] internal, [E] external)
• [K] external companies identifiedIf has_more_data is True, ask:
💡 **I see there are meetings beyond 6 months.**
Want me to check how much more history you have?
This will take a few more seconds.
→ Yes - show me the full extent
→ No - 6 months is plentyIf user says "Yes", refetch with extended=True and update:
📊 **Updated - Full data extent:**
• [N_total] meetings captured (found [N_new] older meetings)
• Going back [total_days] days (to [oldest_date])
• [M_total] unique people detected
• [K_total] external companies identified
---
Here's what I can create from your Granola history:
**📇 People & Company Pages** (Recommended: All history)
✅ Builds context for relationships
✅ Low overhead - just reference pages
✅ Helps you see interaction history
**📝 Meeting Notes** (Recommended: Last 30 days)
✅ Searchable record of discussions
⚠️ Medium overhead - lots of reading material
✅ Good for finding past decisions
**✅ Action Items / Todos** (Recommended: Last 7 days)
✅ Actionable recent tasks
⚠️ Can be overwhelming if too many
⚠️ Old todos often outdated or already done
**What would you like me to do?**
1️⃣ Smart default (Recommended)
• People/companies: All [days_back] days
• Meeting notes: Last 30 days (~[est_30d] meetings)
• Todos: Last 7 days (~[est_7d] meetings)
2️⃣ Recent only (Conservative)
• Everything: Last 7 days only
3️⃣ Full history (Comprehensive)
• Everything: All [days_back] days
4️⃣ Custom (You choose)
• Pick different time ranges for each type
5️⃣ Just going forward
• Start fresh from today
6️⃣ Skip for nowUser Chooses Processing Strategy
Use prompt_user tool. If prompt_user is not available, prompt in CLI with the same numbered options and capture the selection:
{
"questions": [{
"id": "granola_strategy",
"prompt": "How would you like to process your Granola data?",
"allow_multiple": false,
"options": [
{"id": "smart", "label": "1️⃣ Smart default - People/companies (all) + Notes (30d) + Todos (7d)"},
{"id": "recent", "label": "2️⃣ Recent only - Everything from last 7 days"},
{"id": "full", "label": "3️⃣ Full history - Everything from all available data"},
{"id": "custom", "label": "4️⃣ Custom - I'll choose time ranges for each type"},
{"id": "forward", "label": "5️⃣ Just going forward - Start fresh from today"},
{"id": "skip", "label": "6️⃣ Skip for now"}
]
}]
}Custom Mode Flow
If user selects "custom", ask for granular preferences:
{
"title": "Choose time ranges for historical data",
"questions": [
{
"id": "people_range",
"prompt": "People & Company Pages: How far back?",
"allow_multiple": false,
"options": [
{"id": "7d", "label": "Last 7 days"},
{"id": "30d", "label": "Last 30 days"},
{"id": "90d", "label": "Last 90 days"},
{"id": "all", "label": "All [days_back] days (recommended)"},
{"id": "none", "label": "Skip - don't create"}
]
},
{
"id": "notes_range",
"prompt": "Meeting Notes: How far back?",
"allow_multiple": false,
"options": [
{"id": "7d", "label": "Last 7 days"},
{"id": "30d", "label": "Last 30 days (recommended)"},
{"id": "90d", "label": "Last 90 days"},
{"id": "all", "label": "All [days_back] days"},
{"id": "none", "label": "Skip - don't create"}
]
},
{
"id": "todos_range",
"prompt": "Action Items / Todos: How far back?",
"allow_multiple": false,
"options": [
{"id": "7d", "label": "Last 7 days (recommended)"},
{"id": "30d", "label": "Last 30 days"},
{"id": "90d", "label": "Last 90 days"},
{"id": "all", "label": "All [days_back] days"},
{"id": "none", "label": "Skip - don't create"}
]
}
]
}Map responses to days:
- "7d" → 7
- "30d" → 30
- "90d" → 90
- "all" → [days_back from extent analysis]
- "none" → 0 (skip)
Process Based on Selection
Map strategy to time ranges:
def map_strategy_to_ranges(strategy: str, extent: dict) -> dict:
"""Convert user strategy choice to specific time ranges"""
if strategy == "smart":
return {
'people_days': extent['days_back'], # All history
'notes_days': min(30, extent['days_back']), # Last 30 days or all if less
'todos_days': min(7, extent['days_back']) # Last 7 days or all if less
}
elif strategy == "recent":
return {
'people_days': 7,
'notes_days': 7,
'todos_days': 7
}
elif strategy == "full":
return {
'people_days': extent['days_back'],
'notes_days': extent['days_back'],
'todos_days': extent['days_back']
}
elif strategy == "forward":
return {
'people_days': 0,
'notes_days': 0,
'todos_days': 0
}
elif strategy == "skip":
return None
# For "custom", ranges come from separate prompt_user responses (or CLI fallback)Show confirmation before processing:
**Here's what I'll do:**
📇 People/Company Pages: Last [people_days] days
→ ~[est_people] people pages, ~[est_companies] company pages
📝 Meeting Notes: Last [notes_days] days
→ ~[est_notes] meeting notes
✅ Todos: Last [todos_days] days
→ Estimated [est_todos] action items
**This will take about 2-3 minutes. Ready?**Processing phases:
- Fetch meetings by maximum range needed:
max_days = max(people_days, notes_days, todos_days) all_meetings = granola_get_recent_meetings(days_back=max_days, limit=1000) - Phase 1: People & Companies (if people_days > 0):
# Filter meetings for people processing people_meetings = [m for m in all_meetings if days_ago(m['date']) <= people_days] # For each unique person: # - Extract from all meetings in range # - Create person page with meeting history # - Route to Internal/ or External/ # - Create/update company pages for external domains # Use /process-meetings --people-only --days-back={people_days} logic - Phase 2: Meeting Notes (if notes_days > 0):
# Filter meetings for note creation notes_meetings = [m for m in all_meetings if days_ago(m['date']) <= notes_days] # For each meeting: # - Create detailed meeting note # - Extract key points and decisions # - Link to person/company pages # - BUT don't extract todos yet # Use /process-meetings --no-todos --days-back={notes_days} logic - Phase 3: Todos (if todos_days > 0):
# Filter meetings for todo extraction todo_meetings = [m for m in all_meetings if days_ago(m['date']) <= todos_days] # For meetings that have notes: # - Extract action items # - Create tasks in 03-Tasks/Tasks.md # - Add task IDs to meeting notes # For meetings in todo range but not notes range: # - Still extract todos but note they came from unprocessed meetings - Show completion summary:
## Processing Complete ✅ **People & Companies:** • Created [X] person pages ([I] internal, [E] external) • Created [Y] company pages • Processed [P] days of history **Meeting Notes:** • Created [N] detailed meeting notes • From last [notes_days] days **Action Items:** • Extracted [T] todos • From last [todos_days] days • Added to 03-Tasks/Tasks.md **Your vault now has:** • Rich context from [people_days] days of meetings • Searchable notes from [notes_days] days • Actionable todos from [todos_days] days Want to explore what was created?
If "skip" selected:
- Show: "No problem! You can always run
/process-meetingslater when you're ready." - Move to completion flow
If "forward" selected:
- Show: "Got it - starting fresh from today. I won't backfill historical data."
- Update a marker file to remember this choice
- Future meetings will be processed normally
Flow B: Has Calendar OR Granola (Not Both)
The "Let Me Help You Complete The Picture" Flow
If Only Calendar:
👋 **Welcome back, [Name]!**
You already saw this week's calendar snapshot during onboarding, so I won't repeat those numbers. I can now show you how to use that context for daily planning, meeting prep, and relationship notes.
**But I notice Granola isn't connected** - that's how I process meeting transcripts into action items and insights.
Want help with:
1. Connecting Granola — run `/granola-setup` to add your Granola API key (needs a Granola Business plan) for automatic meeting intelligence
2. Connecting another meeting tool
3. Or tell me what other tools you use - I'll build integrations
What sounds useful?If Only Granola:
Same discovery flow as Flow A, but calendar-less:
👋 **Welcome back, [Name]!**
I can see Granola is connected. Let me check what's available...
[Analyze Granola data extent - 6 months by default]
📊 **Granola data (last 6 months):**
• [N] meetings captured
• Going back [days_back] days (to [oldest_date])
• [M] unique people detected ([I] internal, [E] external)
• [K] external companies identifiedIf has_more_data is True:
💡 **I see there are meetings beyond 6 months.**
Want me to check how much more history you have?
→ Yes - show me the full extent
→ No - 6 months is plentyThen continue:
---
Here's what I can create from your Granola history:
**📇 People & Company Pages** (Recommended: All history)
✅ Builds context for relationships
✅ Low overhead - just reference pages
**📝 Meeting Notes** (Recommended: Last 30 days)
✅ Searchable record of discussions
⚠️ Medium overhead
**✅ Action Items / Todos** (Recommended: Last 7 days)
✅ Actionable recent tasks
⚠️ Can be overwhelming if too many
**What would you like me to do?**
1️⃣ Smart default - People/companies (all) + Notes (30d) + Todos (7d)
2️⃣ Recent only - Everything from last 7 days
3️⃣ Full history - Everything from all available data
4️⃣ Custom - I'll choose time ranges for each type
5️⃣ Just going forward - Start fresh from today
6️⃣ Skip for now
**I also notice your calendar isn't connected.** After processing, want to:
• Connect Google Calendar (even if work is restricted)
• Connect Apple Calendar
• Or skip - I can work with just GranolaUse the same prompt_user and processing logic as Flow A (or CLI fallback).
Flow C: Neither Calendar Nor Granola
The "Let's Connect Your Tools" Flow
👋 **Welcome back, [Name]!**
Your workspace is set up, but you don't have calendar or meeting tools connected yet.
**Let's get you integrated with the tools you actually use.**
What tools do you use most? Examples:
• Notion, Linear, Jira
• Slack, Discord
• GitHub, GitLab
• Your company's internal tools
• Newsletters, RSS feeds
**Give me names or URLs** (URLs are better - just the root domain like "notion.so" or "linear.app")
Once you tell me, I'll:
1. Check for API documentation
2. Analyze what's possible
3. Generate working MCP code
4. Get you integrated in ~2 minutes
What's your most important tool?Tool Integration Flow
When user provides tool name/URL:
Step 1: Find API docs
if url_provided:
# Fetch directly
base_url = normalize_url(user_input)
doc_content = web_fetch(base_url)
else:
# Search for docs
search_patterns = [
f"{tool_name} API documentation",
f"{tool_name} developer docs",
f"{tool_name} API reference"
]
# Try WebSearch or direct fetch of common patterns
doc_url = find_api_docs(tool_name)
doc_content = web_fetch(doc_url)Step 2: Analyze capabilities
"Hold on - reading [Tool]'s API documentation..."
[Analyze doc_content for:]
- Authentication methods
- Available endpoints
- Common operations
- Rate limits
"Got it! I just read [Tool]'s API. Here's what we can build:
**Possible integrations:**
• [Capability 1] - [Dex use case]
• [Capability 2] - [Dex use case]
• [Capability 3] - [Dex use case]
Based on your role ([role]), I'd focus on [specific capabilities].
Ready to build this? Takes about 2 minutes."Step 3: Generate MCP
Follow /create-mcp skill flow:
- Design tools based on API analysis
- Generate server code
- Configure authentication
- Test connection
- Update documentation
Step 4: The Magic Moment
"Your [Tool] integration is live! ✅
Test it right now:
'[Natural language query about that tool]'
See? Real data, not AI guessing. That's what MCP does."Step 5: Offer More
"Want to connect another tool? Or explore what else Dex can do?"
[If yes, repeat]
[If no, show quick reference guide]Additional Pathways (Available in Any Flow)
Google Workspace Setup
If user wants to connect Gmail/Calendar:
"Let's connect your Google account.
This works even if your work account has restrictions - we can use your personal Google if needed.
**What we'll set up:**
• Calendar sync (see meetings in Dex)
• Gmail access (summarize newsletters, find emails)
• Optional: Create daily digest
I'll guide you through OAuth step-by-step.
Ready?"Then:
- Guide through OAuth flow for Google Calendar MCP
- Add Gmail MCP if they want
- Offer to set up newsletter digest
Information Diet Setup
If user mentions newsletters, RSS, or content consumption:
"Want me to create a daily digest for you?
I can pull from:
• Newsletters (via Gmail)
• YouTube channels you follow
• RSS feeds from blogs
• Specific websites you check regularly
Each morning, you'd get:
• Summaries of new content
• Key points extracted
• Novel insights highlighted
• All in one place
What sources matter most to you?"Then build appropriate scrapers/integrations.
Smithery.ai Discovery
Anytime during tool discussion:
"By the way - there are 100+ pre-built MCP servers at **Smithery.ai**
Browse there for:
• GitHub, Linear, Jira
• Notion, Airtable, Sheets
• Slack, Discord, Email
• Databases, monitoring tools
• And way more...
Find something interesting? Just paste the URL here and I'll integrate it.
Or we can build custom if you don't find what you need."Setting Expectations
Throughout ANY flow, include:
"**Fair warning:** I can't promise everything will work perfectly.
Company restrictions, API limitations, weird auth flows -
lots can go wrong in the real world.
**But here's what's cool:** Even when it doesn't work, you learn:
• How to use Claude to debug APIs
• How to build integrations yourself
• How MCP servers work
• How to read API documentation
It's educational even when it fails.
Still want to try?"Cursor UX Tip (If Running in Cursor)
After a few file edits, offer:
"**Quick Cursor tip:**
You're seeing 'Accept' prompts for each change I make. That's Cursor asking permission.
**Useful at first** - you see what's happening
**Annoying later** - slows things down
If you want to auto-accept:
1. Settings (Cmd+,)
2. Search "always allow tool use"
3. Enable it
Your choice - some prefer control, others prefer speed."Only show if:
- Detected running in Cursor (check environment)
- After 3-4 accept prompts shown
Integration Discovery (Contextual)
Trigger: Run this check if the vault is < 7 days old AND few or no integrations are connected.
When to Check
After completing the main pathway flow (A, B, or C) but before showing the completion message:
- Read
System/integrations/config.yaml(if it exists) - Count how many integrations have
enabled: true(excludeslacksince it's a default) - If connected integrations <= 1 AND vault age < 7 days, run the concierge
How to Run
Execute the integration concierge — it scans the vault for signals (mentions, links, email domains) of tools the user already works with and ranks them:
Use the harness's MCP integration flow if available; otherwise continue without optional integrations.Parse the JSON output for the high_value and moderate_value tiers. Each entry includes shortName, reason (a ready-to-use plain-English signal — "installed on your Mac", "3 mentions in your notes", "already set up as a connector but not switched on yet"), value, setupTime, and setup (the setup skill to run). Prefer reason verbatim — it already names the strongest evidence (an installed app or configured connector outranks a passing mention).
Presenting Recommendations
Only surface high_value items (keep it light — this isn't onboarding, it's a nudge).
For each high_value integration found:
By the way — **[shortName]** ([reason]).
Connecting it would give you: [value proposition]
Setup takes [setupTime]. Want to connect it now?If multiple high_value items:
I also spotted signals for **[shortName2]** and **[shortName3]** in your notes.
Want to connect any of these? Or run `/integrate-mcp` anytime later.Rules:
- Maximum 2 integration suggestions (don't overwhelm)
- Only mention high_value items (score >= 5) — skip moderate and available
- If the user says yes, run the setup skill (its
setupfield, e.g./trello-setup) inline, then return to the getting-started completion - If the user says no/skip/later, move on without pressure
- Don't show this section if the user already went through integration setup during onboarding Step 10 — check the
.onboarding-completemarker for anintegrations_offeredflag and skip if present
Completion & Next Steps
After any pathway completes:
"**You're set up!**
**Daily workflow:**
• Run `/daily-plan` each morning
• Use `/meeting-prep [person]` before meetings
• Tell me about meetings - I'll extract action items
**Discovery:**
• `/dex-level-up` - Find features you haven't tried
• `/integrate-mcp` - Add more tools anytime
• `/dex-doctor` - Anytime checkup: finds what's wrong, fixes what it can on its own, guides you through the rest: https://heydex.ai/help/updating-troubleshooting.html#health-dex-doctor
• `/feedback` - Something misbehaving? Just say so in your own words — Dex writes the bug report for you and tells you when it's fixed. What a report can and can't contain: https://heydex.ai/help/feedback.html
• Smithery.ai - Browse MCP marketplace
**Come back anytime:**
• `/getting-started` - Run this tour again
• Just ask in natural language - I'll figure out what you need
What would you like to work on first?"Update marker file:
marker_data['phase2_completed'] = True
marker_data['phase2_completed_at'] = datetime.now().isoformat()
marker_data['pathways_completed'] = selected_pathwaysUsage Log Integration
Before showing suggestions, check System/usage_log.md:
usage = read_usage_log()
tried_features = [f for f, checked in usage.items() if checked]
# Adaptive suggestions based on what they've used
if len(tried_features) < 3:
# New user - basics
suggest = ["daily-plan", "meeting-prep"]
elif "meeting-prep" not in tried_features and has_calendar:
# Have meetings but haven't prepped
suggest = ["meeting-prep"]
elif "process-meetings" not in tried_features and has_granola:
# Have Granola but haven't processed
suggest = ["process-meetings"]
else:
# Power user - advanced features
suggest = get_advanced_features(usage, role)Don't show features they've already tried - focus on gaps.
Escape Hatches
At EVERY major decision point:
- "This is a lot - want to pause and come back later?"
- "No pressure - you can always run
/getting-startedagain" - "Want to explore on your own first? That's cool"
After full tour:
- "Remember - invoke
/dex-level-upto discover more" - "Or
/integrate-mcpto add tools as you need them" - "The system grows with you"
Success Metric
The moment they think: "How did it know to do that?"
Different magic for different situations:
- With data: Analyzed calendar/Granola intelligently, offered smart actions
- Without data: Built working integration in 2 minutes from just a name
- Either way: They see value immediately and know where to go next
Helper: Analyze Granola Data Extent
Before presenting choices, discover how much Granola data is available:
def analyze_granola_extent(user_email_domain: str, extended: bool = False) -> dict:
"""
Discover how much Granola data is available
Args:
user_email_domain: User's company email domain for internal/external classification
extended: If True, fetch up to 2 years. If False, fetch 6 months (default)
Returns:
Dictionary with extent analysis or None if no data
"""
from datetime import datetime
# Default to 6 months for speed, optionally extend to 2 years
days_to_fetch = 365 * 2 if extended else 180
result = granola_get_recent_meetings(days_back=days_to_fetch, limit=1000)
if not result.get('success') or not result.get('meetings'):
return {
'meetings_count': 0,
'days_back': 0,
'has_data': False
}
meetings = result['meetings']
# Find oldest and newest dates
dates = [m['date'] for m in meetings if m.get('date')]
if not dates:
return {'meetings_count': 0, 'days_back': 0, 'has_data': False}
oldest = min(dates)
newest = max(dates)
# Calculate days back
oldest_dt = datetime.fromisoformat(oldest)
newest_dt = datetime.fromisoformat(newest)
days_back = (newest_dt - oldest_dt).days + 1 # +1 to include both days
# Extract unique people and companies
people = set()
internal_people = set()
external_people = set()
companies = set()
# Normalize user domain for comparison
user_domains = [d.strip().lower() for d in user_email_domain.split(',')]
for meeting in meetings:
for participant in meeting.get('participants', []):
name = participant.get('name')
email = participant.get('email')
if name:
people.add(name)
if email:
domain = email.split('@')[1].lower() if '@' in email else None
# Classify as internal or external
if domain and any(d in domain or domain in d for d in user_domains):
internal_people.add(name)
else:
external_people.add(name)
if domain:
companies.add(domain)
else:
# No email provided - default to external
external_people.add(name)
# Calculate meetings in different time ranges for estimation
now = datetime.now()
meetings_7d = sum(1 for m in meetings if m.get('date') and
(now - datetime.fromisoformat(m['date'])).days <= 7)
meetings_30d = sum(1 for m in meetings if m.get('date') and
(now - datetime.fromisoformat(m['date'])).days <= 30)
meetings_90d = sum(1 for m in meetings if m.get('date') and
(now - datetime.fromisoformat(m['date'])).days <= 90)
# Check if there might be more data beyond what we fetched
has_more = False
if not extended and len(meetings) >= 900: # Close to limit, likely more data
has_more = True
# Check if oldest meeting is exactly at the boundary (suggests more data)
if not extended and days_back >= 175: # Close to 180 days
has_more = True
return {
'has_data': True,
'meetings_count': len(meetings),
'days_back': days_back,
'oldest_date': oldest,
'newest_date': newest,
'unique_people': len(people),
'internal_people': len(internal_people),
'external_people': len(external_people),
'unique_companies': len(companies),
'people_sample': list(people)[:10],
'companies_list': list(companies),
'meetings_7d': meetings_7d,
'meetings_30d': meetings_30d,
'meetings_90d': meetings_90d,
'has_more_data': has_more,
'fetched_range_days': days_to_fetch
}Usage in Flow A:
# After detecting Granola is available
user_profile = read_user_profile()
email_domain = user_profile.get('email_domain', '')
# Fetch initial 6 months
extent = analyze_granola_extent(email_domain)
if not extent['has_data']:
# Handle no data case
pass
else:
# Check if there's more data beyond 6 months
if extent['has_more_data']:
# Ask if they want to fetch more
response = prompt_user({
"questions": [{
"id": "fetch_more",
"prompt": f"I found {extent['meetings_count']} meetings going back {extent['days_back']} days. There appears to be more data beyond that. Want me to check how much more?",
"allow_multiple": false,
"options": [
{"id": "yes", "label": "Yes - show me the full extent"},
{"id": "no", "label": "No - 6 months is enough"}
]
}]
})
if response['fetch_more'] == 'yes':
# Fetch extended range (2 years)
extent = analyze_granola_extent(email_domain, extended=True)
# Show discovery summary and choice framework
passTrack Usage (Silent)
Call the mark_feature_used tool on the dex-analytics MCP server with getting-started. This ticks the feature's box in System/usage_log.md, which is what /dex-level-up reads to recommend features that have not been tried. It writes locally and sends nothing, so it runs whether or not analytics is enabled.
Analytics (Silent):
Call track_event with event_name getting_started_completed and properties:
- calendar_connected
- granola_connected
- artifacts_created
This only fires if the user has opted into analytics. No action needed if it returns "analytics_disabled".
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

