Technical reference for the Cybos system
Cybos is a Claude Code-powered personal AI assistant for an individual user and an operations aid for their organization. It handles three core domains:
| Domain | Capability |
|---|---|
| Research | Company DD, technology deep-dives, market analysis, topic exploration |
| Browse | Discover trending topics from social feeds (Twitter) |
| Brief | Morning brief consolidating Telegram, emails, calendar, and GTD |
| Process Gmail for VC deal flow, draft replies, save attachments to deals | |
| Telegram | Process unread messages via GramJS MTProto, draft replies, save drafts |
| Content | Tweets, essays, images (following brand guidelines) |
| DD Memo | Investment memo generation from templates |
| GTD | Autonomous task execution from GTD.md with entity context |
| Summarize | Summarize transcripts (therapy sessions, meetings) into structured notes |
Key Design Principles:
- File-first: All state is markdown on disk or is accessible via MCP tools and scripts (Gmail, Telegram, Granola, Asana, etc)
- Scaffolding > prompting: Workflows + tools beat raw prompts
- Slash commands for execution
- Single-file logging after every workflow
- Context auto-loading: Deal context loads automatically when mentioned
- Single-user, no scheduled automation (MVP)
┌─────────────────────────────────────────────────────────┐
│ CYBOS │
│ (Claude Code + .claude folder) │
└─────────────────────────────────────────────────────────┘
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ SKILLS │ │ AGENTS │ │ HOOKS │
│ (Convention) │ │ (Task tool) │ │ ContextLoad │
│ Research │ │ Researchers │ │ ActionLog │
│ Browse │ │ Writers │ │ DBFreshness │
│ Telegram │ │ Analysts │ │ │
│ Content │ │ │ │ │
│ DDMemo │ │ │ │ │
│ GTD │ │ │ │ │
│ Summarize │ │ │ │ │
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
│ │ │
└───────────────────┼───────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ CONTEXT LAYER │
│ /context/* (identity, philosophy, brand, style)│
│ /context/entities/ (people, orgs - sparse files) │
│ /deals/* (per-company research + memos) │
│ /research/* (topic/market research) │
└─────────────────────────────────────────────────────────┘
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ MCP SERVERS │ │ SQLite │ │ OUTPUTS │
│ Perplexity │ │ (FTS5) │ │ /deals/ │
│ Exa / Parallel│ │ ─────────────│ │ /research/ │
│ Firecrawl │ │ entities │ │ /content/ │
│ Playwright │ │ interactions │ │ │
│ Notion │ │ extracted_ │ │ /.cybos/ │
│ Nano Banana │ │ items │ │ logs/ │
│ Typefully │ │ │ │ │
└───────────────┘ └───────────────┘ └───────────────┘
Starting with v2.1, Cybos uses a global configuration system that separates code from data.
~/.cybos/ # Global config directory
config.json # Main configuration file
~/CybosVault/ # User data vault (configurable path)
private/ # Local-only data
.cybos/
logs/ # All logs (activity, daemon, script)
db/cybos.sqlite # Context graph database
context/ # Core context files
deals/ # Deal folders
research/ # Topic/market research
projects/ # Multi-week initiatives
content/ # Generated content
shared/ # Team-shared data (optional)
cyberman/ # Application directory
vault -> ~/CybosVault # Symlink for IDE access (created by setup wizard)
The vault symlink allows editing vault files directly in your IDE:
- Open
cybermanfolder in VS Code or Cursor - Vault files appear as
vault/private/andvault/shared/in the sidebar - Run Claude Code from the same directory
- Ignored by git - Your data won't be committed
Location: ~/.cybos/config.json
{
"version": "2.1",
"vault_path": "~/CybosVault",
"app_path": "~/Work/cyberman",
"private": {
"git_enabled": false,
"repo_url": null
},
"shared": {
"enabled": false,
"repo_url": null
},
"user": {
"name": "Your Name",
"owner_name": "YourName",
"slug": "your-name",
"aliases": ["Me", "Your Name"]
},
"setup_completed": true,
"automations": {
"daily_reindex": true,
"daily_brief": true
}
}Notes:
app_pathpoints to where Cybos code is installed (set during setup). Skills use this to locate scripts.- API keys remain in
.envfile for security (not in config JSON).
| Script | Purpose |
|---|---|
scripts/config.ts |
Config loading, saving, validation, version migration |
scripts/paths.ts |
Centralized path resolution for vault and app locations |
All scripts should use scripts/paths.ts for file paths:
import { getDealsPath, getLogsPath, getDbPath } from './paths'
const deals = getDealsPath() // ~/CybosVault/private/deals
const logs = getLogsPath() // ~/CybosVault/private/.cybos/logs
const db = getDbPath() // ~/CybosVault/private/.cybos/db/cybos.sqliteDuring transition, the system supports legacy mode (no vault):
- If config doesn't exist and
context/,deals/exist in app root → legacy mode - Scripts use
isLegacyMode()to detect andgetPathWithLegacyFallback()for compatibility
| Script | Purpose | Usage |
|---|---|---|
scripts/vault-sync.sh |
Sync vault repos to GitHub | ./scripts/vault-sync.sh [private|shared|all] |
scripts/move-to-share.sh |
Move deal/research to shared vault | ./scripts/move-to-share.sh deal acme-corp |
Vault sync operations:
./scripts/vault-sync.sh private # Sync private vault only
./scripts/vault-sync.sh shared # Sync shared vault only
./scripts/vault-sync.sh # Sync both (default)
./scripts/vault-sync.sh --status # Show status of both repos
./scripts/vault-sync.sh --pull # Pull only (no push)Moving data to shared:
./scripts/move-to-share.sh deal acme-corp # Move deal
./scripts/move-to-share.sh research ai-market # Move researchGitignore templates:
config/vault-private.gitignore- Template for private vaultconfig/vault-shared.README.md- README template for shared vault
If config is missing when a command runs:
- Auto-start brief-server if not running
- Open browser to
http://localhost:3847/setup - Command exits with helpful message
Skills are a convention, not a Claude Code feature. The .claude/skills/ directory is an organizational pattern. Skill files are markdown documents that get loaded via:
@filereferences in slash commands- Explicit file reads during workflows
- Hook injection (for core identity only)
Claude Code doesn't have a native "skill loader" — we create this behavior through structured commands and workflows.
.claude/skills/
├── Research/
│ ├── workflows/ # orchestrator.md (universal workflow)
│ └── shared/ # agent-selection-matrix.md, investment-lens.md, etc.
├── Browse/
│ └── workflows/ # twitter-feed.md (discover topics from feeds)
├── Email/
│ └── workflows/ # process-gmail.md (via /cyber-email command)
├── Telegram/
│ └── workflows/ # process-messages.md (read, draft, save via GramJS)
├── Content/
│ └── workflows/ # telegram-post.md (primary), tweet.md, essay.md, image.md, schedule.md
├── DDMemo/
│ └── workflows/ # generate.md
├── GTD/
│ ├── SKILL.md # Main entry point with classification + routing
│ ├── workflows/ # outreach.md, call-prep.md, podcast.md, research.md
│ └── learnings.md # Action log for pattern analysis
├── Summarize/
│ └── workflows/ # therapy.md (therapy session transcripts)
├── Self-improve/
│ └── SKILL.md # Always-active napkin for tracking mistakes/patterns
└── baoyu-infographic/
├── SKILL.md # 20 layouts × 17 styles infographic generator
└── references/ # Layout definitions, style definitions, templates
Always active. Maintains .claude/napkin.md for tracking mistakes, corrections, and patterns.
Session behavior:
- Read napkin at session start (before doing anything)
- Apply learnings silently (don't announce)
- Update continuously as you work (not just at end)
Log when:
- You hit an error and figure out why
- User corrects you
- You catch your own mistake
- An approach fails or succeeds unexpectedly
Napkin structure:
# Napkin
## Corrections
| Date | Source | What Went Wrong | What To Do Instead |
## User Preferences
## Patterns That Work
## Patterns That Don't Work
## Domain NotesMaintenance: Consolidate every 5-10 sessions when >150 lines. Keep under 200 lines of high-signal content.
Research skill uses progressive disclosure pattern with shared reference files in .claude/skills/Research/shared/:
agent-selection-matrix.md- Dynamic agent selection based on research type + intensityinvestment-lens.md- organization investment philosophy and rubricmcp-strategy.md- MCP tool selection by intensity tiererror-handling.md- Error recovery and data quality handlingoutput-standards.md- Standardized emoji-based output formatsintensity-tiers.md- Complete 3-tier intensity system speclogging.md- Research debugging and MCP usage logging
Agents are spawned via Claude Code's Task tool. Multiple Task calls in the same response enable parallel execution.
| Agent | Model | Purpose |
|---|---|---|
company-researcher |
Haiku | Company-specific data gathering (business, product, traction) |
market-researcher |
Haiku | Market dynamics, TAM, competitive landscape, timing |
financial-researcher |
Haiku | Funding history, metrics, valuation, unit economics |
team-researcher |
Haiku | Founder backgrounds, team assessment, energy/speed |
tech-researcher |
Haiku | Technology deep-dives, moat analysis, maturity |
content-researcher |
Haiku | Topic research via academic papers, social media, first-principles (for content) |
investment-researcher |
Haiku | Topic research via market dynamics, opportunities, timing (for investment) |
quality-reviewer |
Sonnet | Gap analysis, contradiction detection, follow-up identification (deep mode only) |
content-writer |
Sonnet | Tweets, essays, drafts |
memo-analyst |
Opus | Strategic investment analysis |
memo-writer |
Sonnet | Memo generation from template |
synthesizer |
Sonnet | Consolidate parallel agent outputs |
Agent Output Format: All research agents use standardized emoji-based format:
- 🔍 Starting | 📊 Data | 💡 Insights | ✅ Strengths |
⚠️ Concerns | 🔗 Sources | 🎯 Completion
To run agents in parallel, issue multiple Task calls in the same response:
[Task: company-researcher] Research Acme Corp business model
[Task: market-researcher] Research Acme Corp's market
[Task: financial-researcher] Research Acme Corp funding
[Task: team-researcher] Research Acme Corp founders
Agent profiles are stored in .claude/agents/*.md.
| Context Type | Loading Method | When |
|---|---|---|
| Identity | SessionStart hook | Every session |
| Workflows | @file in slash commands |
Per-command |
| Deal-specific | Auto-pulled when deal mentioned | On-demand |
/deals/<company>/
├── .cybos/
│ ├── context.md # Deal metadata, status, key contacts
│ └── scratchpad/ # Temp agent working files
├── research/
│ └── MMDD-<slug>-YY.md # Research reports (load latest)
└── memo/
└── memo.md # Current memo
# Deal: [Company Name]
**Status:** [Sourced | Researching | DD | IC | Passed | Invested]
**Stage:** [Pre-seed | Seed | Series A | ...]
**First Contact:** MMDD-YY
**Lead:** [Partner name]
## Key Contacts
- Founder: [Name] ([email])
## Quick Facts
- Raising: $X at $Y valuation
- Sector: [AI Infra | Crypto | Robotics | ...]
- Thesis fit: [Notes on how this fits organization focus]
## Open Questions
- [Question 1]
## Notes
[Running notes from calls, research, etc.]Cybos extracts meeting transcripts and AI notes from Granola.
- Auto-extraction: SessionStart hook runs incremental extraction (only new calls)
- Manual trigger:
/cyber-save-callscommand - Data source:
~/Library/Application Support/Granola/cache-v3.json - Output:
/context/calls/[MMDD]-[title]-[YY]/with transcript.txt, notes.md, metadata.json - Database: Call interactions indexed in SQLite via
/cyber-reindex
/context/calls/
├── README.md # Usage documentation
└── MMDD-title-YY/ # Individual call folders
├── metadata.json
├── transcript.txt
└── notes.md
Cybos processes Telegram messages via GramJS MTProto client (not browser automation).
- Script-based:
scripts/telegram-gramjs.tsconnects directly to Telegram API - Per-person files: Each contact has persistent conversation file (
context/telegram/<slug>.md) - Entity integration: Looks up entities by telegram username via database
- Manual trigger:
/cyber-telegramcommand - Authentication: First run prompts for phone + code, session saved to
~/.cybos/telegram/ - Read-only by default: Never sends messages, only saves drafts
- Smart filtering: Skips archived and muted chats automatically
| Mode | Flag | Description |
|---|---|---|
| Unread (default) | --count N |
Process N unread conversations |
| User | --user "name" |
Find specific person by username/name (any read state) |
| Requests | --requests |
Process message requests folder (non-contacts who messaged you) |
# Unread mode (default)
/cyber-telegram # 1 unread dialog
/cyber-telegram --count 3 # 3 unread dialogs
# User mode (any read state)
/cyber-telegram --user "@username" # By Telegram username
/cyber-telegram --user "Name" # By name
# Requests mode (non-contacts)
/cyber-telegram --requests # Message requests folder
# Modifiers
/cyber-telegram --dry-run # Read only, no drafts saved
/cyber-telegram --no-mark-unread # Don't preserve unread state- Script fetches dialogs based on mode (unread, user search, or requests)
- Reads last 20 messages per dialog (both directions)
- Looks up entity by telegram username in SQLite database
- Gets/creates per-person file:
context/telegram/<slug>.md - Deduplicates: only appends messages with ID > lastMessageId
- Creates work file:
- Unread/requests:
content/work/MMDD-telegram-replies-YY.md - User mode:
content/work/MMDD-telegram-<user-slug>-YY.md
- Unread/requests:
- Marks conversations as unread (preserves state)
- AI generates draft replies
- User approves,
telegram-save-drafts.tssaves drafts to Telegram - Sent messages captured on next read
Draft saving script (scripts/telegram-save-drafts.ts):
- Parses work file to extract draft replies
- Matches dialogs using strict strategy:
- Dialog ID (primary, e.g.,
-1002178089244for groups) - Exact username match (e.g.,
@username) - Exact title match only (no fuzzy/substring matching)
- Dialog ID (primary, e.g.,
- Calls
messages.SaveDraftAPI for each dialog - Reports success/failure for each draft saved
# Anton Lobintsev
**Entity:** anton-lobintsev
**Username:** @lobintsev
**Type:** private
**First contact:** 2026-01-06
**Last updated:** 2026-01-06T14:45:00Z
**Last message ID:** 12345
---
## 2026-01-06
- [12:39] **Anton**: Message text...
- [14:45] **Me**: Reply text...
---Metadata fields:
Entity:- links to entity index slug (for cross-reference)Username:- Telegram handleType:- private/group/channelFirst contact:- when file was createdLast updated:- when last message was appendedLast message ID:- for deduplication
~/CybosVault/private/
├── context/telegram/
│ ├── README.md # Documentation
│ ├── anton-lobintsev.md # Per-person conversation log
│ ├── egor.md # Per-person conversation log
│ └── org-team.md # Group chats too
└── content/work/
└── 0106-telegram-replies-26.md # AI draft replies (GTD-style)
~/.cybos/telegram/
└── session.txt # Auth session (outside git)
# .env
TELEGRAM_API_ID=... # Get from https://my.telegram.org/apps
TELEGRAM_API_HASH=... # Get from https://my.telegram.org/apps
# Install dependency
bun add telegram- Drafts only:
messages.SaveDraftAPI saves draft text, user sends manually in Telegram - No read receipts: Conversations marked unread after processing
- No auto-send: AI drafts require user approval before saving
- Session local: Auth stored in
~/.cybos/telegram/, not in git - Deduplication: Messages never duplicated thanks to lastMessageId tracking
Cybos indexes emails from Gmail for context and morning brief.
- Manual trigger:
/cyber-email --synccommand - Data source: Gmail via
@gongrzhe/server-gmail-autoauth-mcp - Output:
/context/emails/YYYY-MM-DD_<from>-<subject>/with metadata.json, body.md - Database: Email interactions indexed in SQLite via
/cyber-reindex - Deduplication: Via
.state.jsontracking processedMessageIds
- Load
.state.jsonto get already-processed messageIds - Query Gmail:
(is:unread OR is:important) after:N_days_ago - Filter out already-processed emails
- For each new email: read content, generate summary, save to folder
- Update
.state.jsonwith new messageIds - Run
/cyber-reindexto index emails in database
/context/emails/
├── README.md # Documentation
├── .state.json # Dedup state (messageIds)
└── YYYY-MM-DD_from-subject/
├── metadata.json # Email metadata + AI summary
└── body.md # Email content (markdown)
| Date | From | Subject | Important | Summary | Path |
|------|------|---------|-----------|---------|------|
| 2026-01-07 | John Smith (john@acme.com) | Series A Update | ⭐ | Q4 metrics exceeded targets | [📁](./2026-01-07_john-smith-series-a/) |Default sync: (is:unread OR is:important) after:3_days_ago
- Prioritizes important emails (marked with ⭐ in index)
- Designed for headless morning brief automation
Visual morning brief with scheduled generation and browser display.
- Scheduled generation: launchd triggers
/cyber-briefdaily at 8am - HTTP server: Hono server on port 3847 serves API + React app
- Parser: Converts brief markdown to structured JSON
- Web UI: React + Tailwind app for visual brief display
scripts/
├── brief-parser.ts # Markdown → JSON parser
├── brief-server.ts # Hono HTTP server (port 3847)
├── morning-brief.sh # Orchestrator (generate + server + browser)
├── install-brief.sh # Installation script for launchd
├── db/query.ts # Database queries including getExplorerDashboard()
└── web-brief/ # React + Vite + Tailwind app
├── src/
│ ├── App.tsx # Main component with routing
│ ├── types.ts # TypeScript interfaces (Brief + Explorer)
│ ├── api.ts # API client
│ ├── components/
│ │ └── ItemCard.tsx # Reusable item display component
│ └── pages/
│ └── ExplorerPage.tsx # Context Explorer page
└── dist/ # Production build (served by Hono)
config/
├── leverage-rules.yaml # Strategic leverage scoring rules
└── launchd/
├── com.cybos.brief-server.plist.example # Server daemon template
└── com.cybos.morning-brief.plist.example # 8am daily trigger template
| Endpoint | Method | Description |
|---|---|---|
/api/brief/today |
GET | Today's brief as JSON |
/api/brief/yesterday |
GET | Yesterday's brief as JSON |
/api/brief/:date |
GET | Specific brief (MMDD-YY format) |
/api/briefs |
GET | List available briefs |
/api/explorer |
GET | Explorer dashboard (deals, entities, items) |
/api/health |
GET | Server health check |
/* |
GET | Static React app |
The Explorer page (?page=explorer) provides a dashboard view of extracted items from the context graph database:
Panels:
- Active Deals - Auto-detected from deal mentions, fuzzy-grouped by similar names
- Recent People - Entities with recent activity, showing promises and action items
- My Commitments - Pending promises/action items where I am the owner
- Metrics Overview - Metrics grouped by company
Features:
- Filter dropdown: All / Promises / Actions / Decisions / Metrics
- Expand/collapse cards for detailed items
- Provenance quotes from source transcripts
- Trust level indicators (high/medium/low)
- 14-day rolling window
Data flow:
SQLite (context graph) → getExplorerDashboard() → /api/explorer → ExplorerPage.tsx
The brief includes a "Strategic Leverage" section that scores items by:
- Urgency rules - Message age, meeting proximity, blocking keywords
- Leverage rules - Deal-related, founder/investor communication, intros
- Goal-alignment rules - Based on priorities from
context/who-am-i.md
Configuration: config/leverage-rules.yaml
# Full installation (build + launchd setup)
./scripts/install-brief.sh
# Check status
./scripts/install-brief.sh --status
# Uninstall
./scripts/install-brief.sh --uninstall# Start server manually
bun scripts/brief-server.ts
# Open browser (skip generation)
./scripts/morning-brief.sh --skip-gen
# Just ensure server running
./scripts/morning-brief.sh --server- Web UI: http://localhost:3847
- Today's brief: http://localhost:3847?day=today
- Yesterday's brief: http://localhost:3847?day=yesterday
- API Health: http://localhost:3847/api/health
Cybos queries Google Calendar via the unified Gmail MCP (which handles both email and calendar).
- MCP Server: Unified Gmail MCP (
gmail-mcp) with built-in OAuth credentials - Command:
/cyber-calendar- returns today+tomorrow meetings - Output: Markdown tables (ephemeral, not saved)
- Use case: Morning brief automation
- Auth: Same "Sign in with Google" flow as Gmail - one auth for both
## Today (2026-01-07, Tuesday)
| Time | Event | Attendees | Location |
|------|-------|-----------|----------|
| 09:00-10:00 | Team Standup | Sarah, Mike | https://zoom.us/... |
| 14:00-15:00 | Acme Corp DD Call | John Smith | Google Meet |mcp__gmail__list_calendar_events
- time_min: ISO 8601 start (optional, defaults to now)
- time_max: ISO 8601 end (optional)
- max_results: number (default: 10)
- query: free text search (optional)
mcp__gmail__create_calendar_event
- summary: event title
- start_time: ISO 8601 or natural language ("tomorrow 3pm")
- end_time: ISO 8601 (optional)
- description: event notes (optional)
- location: event location (optional)
- attendees: list of email addresses (optional)
Both email sync and calendar are designed for headless execution:
claude --headless "/cyber-email --sync"
claude --headless "/cyber-calendar"Cybos generates comprehensive morning briefs consolidating all data sources.
- Command:
/cyber-brief - Output:
/content/briefs/MMDD-YY.md(persistent) - Data sources: Telegram, Gmail, Calendar, GTD.md
- Script dependency:
scripts/telegram-gramjs.ts --all --summary-only
| Source | Method | Output |
|---|---|---|
| Telegram | bun telegram-gramjs.ts --all --summary-only |
JSON to stdout |
mcp__gmail__search_emails query: (is:unread OR is:important) after:YYYY/MM/DD |
Message list | |
| Calendar | mcp__gmail__list_calendar_events with time_min/time_max |
Event list |
| GTD | Read /GTD.md |
Task list |
# Morning Brief - YYYY-MM-DD
## Priority Actions
[Urgent items requiring immediate attention]
## Today's Schedule
| Time | Event | Attendees | Location |
[Calendar events in table format]
## Messages to Respond
### [Person Name] (@username)
[Full message history - not summaries]
## Email Highlights
| From | Subject | Date |
[Important/unread emails]
## Tasks (from GTD)
- [ ] Task 1
- [ ] Task 2
## Context Loaded
[Entity context, deal references, recent calls]- Full messages: Telegram messages included verbatim, not summarized
- History: Briefs are persistent in
/content/briefs/ - Priority scoring: Based on meeting urgency, response delay, deal relevance
- Entity enrichment: Auto-loads context for mentioned people/companies
claude --headless "/cyber-brief"Interactive focus/clarity ritual for breaking distraction loops and reconnecting with goals.
- Command:
/cyber-unstuck- Opens browser to web interface - Web UI:
localhost:3847/unstuck(React + progressive reveal flow) - Backend:
scripts/brief-server.ts(API endpoints)GET /api/unstuck/goals- Returns Active Priorities fromcontext/who-am-i.mdPOST /api/unstuck/log- Logs completed session to journal
- Frontend:
scripts/web-brief/src/pages/UnstuckPage.tsx - Journal:
/context/unstuck/journal.md(append-only log) - Goals source: Parses Active Priorities section from
context/who-am-i.md
1. PAUSE - What's happening?
- Predefined tags: scattered, avoiding, overwhelmed, bored, anxious, unclear, tired
- Or write custom state
2. FORK - Did naming it help?
→ Yes → show goals
→ No → dig deeper
→ Need rest → exit gracefully
3. DIG DEEPER (if needed) - Prompts from therapy/coaching:
- "What might I be protecting myself from?" (IFS)
- "Where do I feel this in my body?" (Somatic)
- "What would I do if this feeling wasn't in the way?" (ACT)
4. CONNECT - Show goals from who-am-i.md:
- What I'm Optimizing For
- Active Priorities
- Philosophical Foundation
- Pick what feels alive
5. CAPTURE - Brief note for pattern tracking
6. RELEASE - "You're clear. Go."
## 2026-01-07 14:32
**State:** avoiding
**Needed deeper dig:** Yes
**Deeper dig prompt:** protecting
**Response:** Fear of not being good enough at the research task
**Connected to:** Making ideas real
**Smallest step:** Open the document and write one sentence
**Note:** Realized I avoid research when I'm not sure where to start
---- Reconnection over productivity: Shows WHY layer (goals, values), not WHAT layer (specific tasks)
- Branching paths: Quick path when naming helps, deeper dig when it doesn't
- Permission for rest: Recognizes that sometimes you need a break, not motivation
- Self-knowledge over metrics: Tracks feelings and insights, not productivity stats
- 2-3 minutes max: Not a therapy session, just enough to reconnect
/context/unstuck/
├── journal.md # Append-only session log
└── (future: patterns.md for AI-generated insights)
Cybos uses these MCP servers with the following priority hierarchy:
Primary:
- exa: Web search, company research, URL content extraction (PRIMARY for research)
- perplexity: Fast search + deep research with citations
- parallel-task: Deep research tasks, report-style outputs
- nano-banana: Image generation (Gemini 3.0)
Fallback:
- parallel-search: Web search + content fetch (fallback for exa)
- firecrawl: Scraping and extraction (LAST RESORT ONLY)
Other:
- playwright: Browser automation
- notion: Document storage
- typefully: Social media scheduling (Twitter, LinkedIn) ✅
- gmail: Unified Gmail + Calendar MCP with built-in OAuth ✅
| Server | Purpose | Tools |
|---|---|---|
| perplexity | Fast search + deep research with citations | search, research |
| parallel-search | Web search + content fetch (fallback option) | web_search_preview, web_fetch |
| parallel-task | Deep research tasks, report-style outputs | createTask, getTask, listTasks |
| exa | Web search, company research, URL content extraction (PRIMARY) | search, findSimilar, getContents |
| firecrawl | Scrape, crawl, extract (LAST RESORT ONLY) | scrape, crawl, map, extract |
| playwright | Browser automation for hard-to-scrape sites | navigate, screenshot, click |
| notion | Notion pages + databases | createPage, updatePage, queryDatabase |
| nano-banana | Image generation (Gemini 3.0) | generate_image, edit_image, continue_editing |
| typefully | Social media scheduling (Twitter, LinkedIn) ✅ | create_draft, create_media_upload, get_media_status |
| gmail | Unified Email + Calendar MCP ✅ | search_emails, read_email, draft_email, send_email, list_calendar_events, create_calendar_event, authenticate |
| Level | Duration | Quality | Cost | Tools | Agents |
|---|---|---|---|---|---|
| Quick | 10-30s | Basic | $0.01-0.05 | Built-in only | None |
| Standard | 2-5m | Good | $0.10-0.30 | MCPs | 2-4 Haiku |
| Deep | 5-15m | Excellent | $0.50-2.00 | All MCPs + Opus | 4-6 mixed |
Quick: WebSearch + WebFetch only. Fast fact-checking.
Standard [DEFAULT]: Perplexity, Exa (search + getContents) + 2-4 parallel Haiku agents.
Deep: Perplexity Deep, Parallel Task Deep + 4-6 agents including Opus.
User Control: --quick, --standard, --deep flags or inferred from query.
1. FAST SEARCH (seconds)
└─ perplexity search OR exa search
└─ Fallback: parallel-search web_search_preview
└─ Good for: quick facts, validation
2. DEEP RESEARCH (1-5 minutes)
└─ parallel-task createDeepResearch → poll getResultMarkdown
└─ Fallback: perplexity research (deep)
└─ Good for: comprehensive reports
3. TARGETED EXTRACTION (as needed)
└─ exa getContents (PRIMARY)
└─ Fallback: parallel-search web_fetch
└─ Last resort: firecrawl scrape
4. HARD SCRAPING (last resort)
└─ playwright for JS-heavy sites
Fallback Chain:
- Web search: exa → parallel-search → WebSearch (built-in)
- URL content: exa getContents → parallel-search web_fetch → firecrawl (last resort) → WebFetch
- Deep research: parallel-task → perplexity (deep) → multiple agents
Parallel Task (Deep Research):
mcp__parallel-task__createTask
- prompt: string (research question)
- Returns: task_id
mcp__parallel-task__getTask
- task_id: string
- Returns: { status, result } (poll until complete)
Perplexity:
mcp__perplexity__search
- query: string
- Returns: search results with citations
mcp__perplexity__research
- query: string
- depth: "basic" | "deep"
Exa:
mcp__exa__search
- query: string
- numResults: number
mcp__exa__findSimilar
- url: string
Parallel Search (Fallback):
mcp__parallel-search__web_search_preview
- objective: string (search objective)
- search_queries: string[] (1-5 queries)
- Returns: LLM-friendly search results
mcp__parallel-search__web_fetch
- objective: string (optional, what to extract)
- urls: string[] (max 10 URLs)
- Returns: Extracted relevant content
Firecrawl (LAST RESORT ONLY - use when exa and parallel-search fail):
mcp__firecrawl__scrape
- url: string
- formats: ["markdown", "html"]
mcp__firecrawl__extract
- url: string
- schema: object (structured extraction)
Nano Banana (Images):
mcp__nano-banana__generate_image
- prompt: string (detailed image description)
mcp__nano-banana__edit_image
- imagePath: string (path to existing image)
- prompt: string (edit instructions)
mcp__nano-banana__continue_editing
- prompt: string (refinement instructions)
Typefully (Social Media Scheduling):
Preferred method: Use direct API v2 calls via curl (see
.claude/skills/Content/workflows/schedule.md) The MCP tools below may be outdated. Direct curl tohttps://api.typefully.com/v2/is more reliable.
# Direct API (preferred)
Authorization: Bearer $TYPEFULLY_API_KEY
GET /v2/me # Current user
GET /v2/social-sets # List accounts
POST /v2/social-sets/{id}/drafts # Create draft
POST /v2/social-sets/{id}/media # Upload media
GET /v2/social-sets/{id}/media/{mid} # Media status
# Available social sets (as of Jan 2026):
- 161806: @sgershuni (personal)
- 153901: @cyberFund_ (fund)
- 215751: @dAGIhouse
# MCP tools (may be outdated, use curl instead)
mcp__typefully__typefully_list_social_sets
mcp__typefully__typefully_get_social_set_details
mcp__typefully__typefully_create_draft
mcp__typefully__typefully_create_media_upload
mcp__typefully__typefully_get_media_status
Testing status: ✅ All core functionality validated via API v2
- Multi-platform posting (Twitter + LinkedIn): Tested
- Scheduled timing (ISO 8601): Tested
- Image upload with S3: Tested
- Draft-only mode: Tested
Gmail (Unified Email + Calendar MCP):
# Authentication (zero-config for new users)
mcp__gmail__authenticate
- Opens browser for Google OAuth sign-in
- Built-in OAuth credentials (no setup needed)
- Single auth grants both Gmail AND Calendar access
- Returns: { result: "Authentication process started..." }
mcp__gmail__check_auth_status
- Returns: { authenticated: bool, message: string }
# Email Tools
mcp__gmail__search_emails
- query: string (Gmail search syntax: from:, to:, subject:, after:, is:unread, etc.)
- maxResults: number (optional, default: 10)
- Returns: List of emails with sender, subject, date, message ID
mcp__gmail__list_emails
- max_results: number (default: 10)
- label: string (default: "INBOX")
- Returns: List of emails
mcp__gmail__get_email
- message_id: string
- Returns: Full email content
# Calendar Tools
mcp__gmail__list_calendar_events
- max_results: number (default: 10)
- time_min: string (ISO 8601, optional)
- time_max: string (ISO 8601, optional)
- query: string (optional, free text search)
- Returns: List of calendar events with times, attendees, links
mcp__gmail__create_calendar_event
- summary: string (event title)
- start_time: string (ISO 8601 or natural language like "tomorrow 3pm")
- end_time: string (optional)
- description: string (optional)
- location: string (optional)
- attendees: string[] (optional, email addresses)
- Returns: { success, event_id, event_link }
Configuration:
- Server: Custom Python MCP at ~/gmail-mcp/
- Auth: OAuth 2.0 with BUILT-IN credentials (zero config)
- Project: cybos-v2 (Gmail API + Calendar API enabled)
- Token storage: ~/cyberman/tokens.json (encrypted)
Zero-config setup for new users:
1. Run `mcp__gmail__authenticate`
2. Click "Sign in with Google" in browser
3. Done - both Gmail and Calendar work
Advanced users can override with:
- credentials.json file in ~/gmail-mcp/
- GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET env vars
Integration with /deals/:
- Auto-detects company from sender domain
- Loads context from /deals/<company>/index.md
- Saves attachments to /deals/<company>/materials/
Testing status: ✅ Fully operational
- Email: list, search, read
- Calendar: list events, create events
All research uses the orchestrator workflow (.claude/skills/Research/workflows/orchestrator.md):
1. INITIALIZE:
├─ Identify research type (Company | Tech | Market | Topic-Content | Topic-Investment)
├─ Determine intensity (Quick | Standard | Deep)
├─ Create workspace: /deals/<company>/research/MMDD-<slug>-YY/ OR /research/<topic>/MMDD-<slug>-YY/
└─ Select agents dynamically (see agent-selection-matrix.md)
2. GATHER (parallel agents - autonomous MCP calls):
├─ Spawn selected agents in parallel
├─ Each agent makes its own MCP calls (perplexity, exa, parallel-search)
├─ Each agent writes to: workspace/raw/agent-[name].md
└─ No MCP calls in main session (agents do everything)
3. REVIEW (Deep mode only):
├─ Spawn quality-reviewer agent
├─ Reads all agent outputs from workspace/raw/
├─ Identifies: completeness gaps, contradictions, shallow coverage
├─ If gaps found: re-spawn specific agents with refined prompts
└─ Max 1 iteration (no recursive quality reviews)
4. SYNTHESIZE:
├─ Spawn synthesizer agent
├─ Reads all agent outputs (including follow-ups)
├─ Applies appropriate lens (investment vs content)
└─ Writes to: workspace/report.md
5. OUTPUT:
├─ Final synthesis: workspace/report.md
├─ All agent outputs preserved in: workspace/raw/
└─ Log to: /.cybos/logs/MMDD-YY.md
Workspace Structure:
MMDD-<slug>-YY/
├── raw/
│ ├── agent-company-researcher.md
│ ├── agent-market-researcher.md
│ ├── agent-financial-researcher.md
│ ├── agent-quality-reviewer.md (deep only)
│ └── agent-[name]-followup.md (if quality loop triggered)
└── report.md (final synthesis)
Agent Selection Matrix:
- Company DD: company + market + financial (standard), +team +quality-reviewer (deep)
- Technology: tech + market (standard), +company +quality-reviewer (deep)
- Market: market + financial (standard), +company +quality-reviewer (deep)
- Topic-Content: content-researcher (standard), +quality-reviewer (deep)
- Topic-Investment: investment-researcher + market (standard), +financial +quality-reviewer (deep)
See .claude/skills/Research/shared/agent-selection-matrix.md for complete matrix.
Key Principles:
- Agents do ALL data gathering (autonomous MCP usage)
- No redundancy (main session doesn't pre-gather data)
- Dynamic selection based on type and intensity
- Quality loop ensures completeness (deep mode only)
Content creation follows a layered architecture:
COMMAND (cyber-essay, cyber-tweet, etc.)
│
▼
WORKFLOW (essay.md, tweet.md, telegram-post.md)
│
├─► LOADS: context/style/voice-identity.md (shared persona)
│
└─► LOADS: context/style/writing-style-[en|ru].md (language-specific)
Context Files:
| File | Purpose |
|---|---|
context/style/voice-identity.md |
Shared persona, tone, anti-patterns |
context/style/writing-style-en.md |
English: essay structure, tweet format |
context/style/writing-style-ru.md |
Russian: Telegram format, Russian rules |
Russian posts (@cryptoEssay) + English translations:
1. ASSESS
└─ Light research if data claims need verification
2. DRAFT (Russian)
└─ Load: context/style/voice-identity.md + writing-style-ru.md
└─ Strong hook, short paragraphs, no LLM phrases
└─ Plain text (no markdown for Telegram)
3. TRANSLATE (English)
└─ Load: context/style/writing-style-en.md for English rules
└─ Native English, not literal translation
4. OUTPUT
└─ Saved to /content/posts/MMDD-<slug>-YY.md
└─ Log to /.cybos/logs/MMDD-YY.md
Workflow: .claude/skills/Content/workflows/telegram-post.md
Long-form English content:
1. ASSESS
└─ Verify factual claims if needed
└─ Load source files (@ references)
2. DRAFT
└─ Load: context/style/voice-identity.md + writing-style-en.md
└─ Hook → Stakes → Mechanism → Turn → Landing
└─ 500-2500 words depending on complexity
3. REVIEW
└─ Present draft for user feedback
4. POLISH
└─ Apply feedback, maintain voice
5. OUTPUT
└─ Saved to /content/essays/MMDD-<slug>-YY.md
└─ Log to /.cybos/logs/MMDD-YY.md
Workflow: .claude/skills/Content/workflows/essay.md
English tweets and threads:
1. ASSESS
└─ Verify factual claims if needed
2. DRAFT
└─ Load: context/style/voice-identity.md + writing-style-en.md
└─ Hook patterns: "how to X", "why X doesn't work"
└─ One sentence per line, lists for structure
3. FORMAT
└─ Single tweet or thread (3-10 tweets)
└─ Engagement: question OR controversial stance
4. OUTPUT
└─ Saved to /content/tweets/MMDD-<slug>-YY.md
└─ Log to /.cybos/logs/MMDD-YY.md
Workflow: .claude/skills/Content/workflows/tweet.md
Schedule content to Twitter and/or LinkedIn via Typefully:
1. LOAD CONTENT
└─ Read existing content from /content/tweets|posts|essays/
└─ Extract appropriate section (Tweet Text, English translation, etc.)
2. SELECT PLATFORMS
└─ Ask user: Twitter / LinkedIn / Both
└─ Build platform config with enabled flags
3. SELECT TIMING
└─ Ask user: Now / Queue / Schedule
└─ Map to: "now" | "next-free-slot" | ISO-8601 timestamp
4. HANDLE MEDIA (optional) ✅ Validated
└─ If --image flag provided:
├─ Call: mcp__typefully__typefully_create_media_upload
├─ Upload to S3 via presigned URL (curl PUT, no Content-Type header)
├─ Poll: mcp__typefully__typefully_get_media_status until "ready"
└─ Capture media_id UUID for posts array
5. CREATE DRAFT
└─ Call: mcp__typefully__typefully_create_draft
└─ Social set: <social-set-id> (<account-name> @<username>)
└─ Platform config: { x/linkedin: { enabled, posts: [{text, media_ids}] } }
└─ Returns: draft ID, status, Typefully URL
6. CONFIRM & LOG
└─ Display: Platforms, timing, Typefully URL
└─ Log to /.cybos/logs/MMDD-<slug>-YY.md
└─ Local file remains unchanged (archive preserved)
Command: /cyber-schedule @content/file.md --image @content/image.png
Workflow: .claude/skills/Content/workflows/schedule.md
Status: ✅ Production ready (tested: multi-platform, scheduling, images)
Main session pipeline with automatic style inference:
1. INFER STYLE from request keywords:
- info: "infographic", "diagram", "process", "flow", "comparison"
- mural: "transformation", "sacred", "dissolution", "empire"
- cyberpunk: "future", "atmospheric", "liminal" (default)
2. EXTRACT core idea (one sentence)
3. CREATE visual approach:
- Info: diagram structure (icon, comparison, process, hierarchy)
- Artistic: visual metaphor (balanced, not too literal/abstract)
4. LOAD style files from context/img-styles/
5. BUILD prompt using template from _shared.md
6. GENERATE via mcp__nano-banana__generate_image
7. SAVE to /content/images/MMDD-<slug>-YY.png
Multiple images: Call MCP in parallel for independent images.
Style files (context/img-styles/):
_shared.md- Common rules, prompt template, universal avoidscyberpunk.md- Grounded futurism, Blade Runner aestheticmural.md- Sacred transformation, particle dissolutioninfo.md- Minimal infographics, handdrawn clarity
Adding new styles: Create context/img-styles/{name}.md with palette, elements, keywords.
Command: /cyber-image "concept" or /cyber-image @source.md "visualize"
Workflow: .claude/skills/Content/workflows/image.md
Info Style Concept Engineering (for diagrams/infographics):
- Workflow includes concept engineering step before generation
- Extracts core insight, identifies visual mechanism, self-critiques
- Post-generation critique with 5-point checklist (squint, text, background, contrast, usability)
- One regeneration allowed if critique fails
- Guide:
context/img-styles/info-concept-guide.md - Evals:
.claude/skills/Content/evals/info-style/(3 evals, all passing)
Professional infographic generator with 20 layouts × 17 styles. Analyzes content, recommends layout×style combinations, generates publication-ready infographics via nano-banana MCP.
1. SETUP: Load EXTEND.md preferences (project-level or ~/.baoyu-skills/)
2. ANALYZE: Content → analysis.md (topic, data type, complexity, audience)
3. STRUCTURE: Transform into structured-content.md (verbatim data, visual elements)
4. RECOMMEND: 3-5 layout×style combinations based on content analysis
5. CONFIRM: Single AskUserQuestion for combination + aspect + language
6. PROMPT: Combine layout def + style def + base template + structured content
7. GENERATE: via mcp__nano-banana__generate_image
8. OUTPUT: Save to vault with summary
Output:
~/CybosVault/private/content/infographics/{topic-slug}/
├── source-{slug}.{ext}
├── analysis.md
├── structured-content.md
├── prompts/infographic.md
└── infographic.png
Final image also copied to: ~/CybosVault/private/content/images/MMDD-{slug}-YY.png
Command: /baoyu-infographic path/to/content.md --layout hierarchical-layers --style technical-schematic
Skill: .claude/skills/baoyu-infographic/SKILL.md
1. GATHER
└─ Load: /deals/<company>/research/* (all research)
└─ Load: /deals/<company>/index.md
└─ Load: @context/investment-philosophy.md
└─ Load: @context/MEMO_template.md
2. ANALYZE (Opus)
└─ Deep strategic analysis
└─ Apply investment rubric
3. WRITE (Sonnet)
└─ Fill template structure
4. OUTPUT
└─ /deals/<company>/memo/memo.md
└─ Log action
Process GTD.md items autonomously with entity context:
1. PARSE
└─ Read GTD.md → extract items from # Next section
2. CLASSIFY (per item)
└─ Match patterns against routing table:
- "ask for call", "message", "email" → outreach workflow
- "call with", "meeting", "<> X" → call-prep workflow
- "podcast" → podcast workflow
- company name, "research" → research workflow
- unknown → best judgment
3. ENTITY LOOKUP
└─ Query database: `bun scripts/db/query.ts find-entity "<name>"`
└─ Load context: `bun scripts/db/query.ts entity <slug> --json`
└─ Extract contact info, previous interactions, pending items
4. PLAN (default behavior)
└─ Show plan for each item before executing
└─ Ask for approval: "Execute? [Y/n/select]"
5. EXECUTE
└─ Execute each task sequentially (one at a time)
└─ Agent follows selected workflow
└─ Staged execution: autonomous work + pending approvals
6. OUTPUT
└─ /content/work/MMDD-<slug>.md (one file per task)
└─ Format: context + draft + pending actions + log
└─ Log to learnings.md
Command: /cyber-gtd, /cyber-gtd --count 3, /cyber-gtd --execute
Workflow: .claude/skills/GTD/SKILL.md
Output File Format:
# Task: [Description]
**Status:** Pending Approval | Completed | Incomplete
**Created:** YYYY-MM-DD HH:MM
**Workflow:** [which workflow]
## Context
[Entity info, previous calls, deal context]
## Draft
[Message/agenda/questions]
## Pending Actions
- [ ] Send via Gmail to email@example.com
- [ ] Alternative: Telegram @handle
## Execution Log
- HH:MM - [action taken]The database indexer provides a unified SQLite-based context graph for all entities, interactions, and extracted items.
Sources: SQLite Database:
──────────────────────────────── ────────────────────────────────────
/deals/*/ ──┐
/context/calls/*/ ──┼──► entities (people, companies, products)
/context/entities/*.md (sparse) ──┤ interactions (calls, emails, telegram)
/context/telegram/*.md ──┤ extracted_items (promises, actions, decisions)
/context/emails/*/ ──┘ entity_aliases (for deduplication)
-- Core tables (5 tables, ~51 columns)
entities -- People, companies, products, groups
entity_aliases -- Name variations for deduplication
interactions -- Calls, emails, telegram messages
extracted_items -- Promises, action items, decisions, questions, metrics
batch_runs -- Indexer run logs
-- Key features
- Full-text search via FTS5 virtual table
- Fuzzy name matching via TypeScript Levenshtein distance
- Temporal queries via ISO-8601 timestamps
- JSON arrays for participant storage (json_each() for queries)
- WAL mode for performancescripts/db/
├── schema-sqlite.sql # SQLite schema with FTS5
├── client-sqlite.ts # SQLite client (bun:sqlite)
├── init.ts # Create database and tables
├── index.ts # Main batch indexer
├── extract-llm.ts # Claude Haiku extraction runner
├── entity-resolver.ts # TypeScript entity matching with Levenshtein
├── query.ts # Query interface + CLI
├── extractors/
│ ├── calls.ts # Parse /context/calls/
│ ├── emails.ts # Parse /context/emails/
│ ├── telegram.ts # Parse /context/telegram/
│ ├── entities.ts # Parse manual entity files
│ └── deals.ts # Parse /deals/ as company entities
└── prompts/
├── types.ts # Shared extraction types
├── call-extraction.ts # Call extraction prompt
├── email-extraction.ts # Email extraction prompt
└── telegram-extraction.ts # Telegram extraction prompt
TypeScript-based multi-stage matching using Levenshtein distance:
| Stage | Match Type | Confidence | Action |
|---|---|---|---|
| 0 | User identity (configured aliases) | 1.0 | Return user entity (configured slug) |
| 1 | Blocked name (Speaker, Unknown) | - | Skip (return _blocked_) |
| 2 | Email exact match | 1.0 | Return existing entity |
| 3 | Telegram handle match | 1.0 | Return existing entity |
| 4 | Fuzzy name match (>0.7 Levenshtein similarity) | 0.7-0.9 | Return existing, add alias |
| 5 | No match found | - | Create new candidate entity |
User Identity Handling (v1.1):
- Configured aliases (including "Me") → resolve to the user entity slug
- User identity is checked FIRST before any database queries
- Items with user as owner/target correctly link to user entity
- Prevents creating duplicate user entities
Blocked Entity Names (v1.1):
- Generic labels are blocked: "Speaker", "Unknown", "Participant", "Caller", etc.
- User identity names are also blocked from entity creation
- Returns
_blocked_slug which is filtered out of participants arrays - Prevents pollution of entity database with meaningless entities
Conservative Context Updates (v1.1):
- Company/role info is ONLY updated from EXACT matches (email, telegram, alias)
- Fuzzy matches do NOT update company/role (prevents entity conflation)
- Example: "Dima" fuzzy-matching to "Dima Khanarin" won't update Khanarin's company
Two-tier Entity System (v1.1):
- Confirmed entities:
is_candidate = FALSE(high confidence) - Candidate entities:
is_candidate = TRUE(extracted from calls/emails without match) - Query
list-candidatesto review and merge candidates - Prevents low-confidence entities from polluting the main database
Type normalization handles LLM variations:
org,organization,startup,fund→companychat,channel,community→groupservice,tool,platform,technology→product
Claude Haiku extracts structured items from interactions:
| Type | Description | Example |
|---|---|---|
promise |
Commitment to do something | "I'll send you the deck" |
action_item |
Task needing completion | "Follow up on pricing" |
decision |
Conclusion reached | "We agreed to proceed with X" |
question |
Open question | "Need to confirm timeline" |
metric |
Business numbers | "500K ARR, 10 employees" |
deal_mention |
Deal reference | "John introduced Acme Corp" |
entity_context |
What someone is building | "Working on AI agents" |
Provenance (v1.1): Each item includes:
source_quote- Verbatim quote from source (10-50 words)source_span- Line numbers (calls) or timestamp (telegram)trust_level- high/medium/low based on confidence + linkage
Type Validation (v1.1):
- Invalid types are automatically mapped:
info/context/note→entity_context task/todo→action_item,commitment→promise- Unknown types are skipped with warning
User Identity Handling (v1.1):
- LLM prompt instructs to use the configured owner name for user identity
- Extract-llm resolves owner/target names through user identity check
- User entity is auto-created if needed (prevents FK constraint errors)
Cost: ~$0.01/interaction using Claude 3.5 Haiku
# Entity lookup
bun scripts/db/query.ts entity john-smith --detailed
bun scripts/db/query.ts find-entity john@example.com
bun scripts/db/query.ts find-entity @johndoe
# Search
bun scripts/db/query.ts search-entities "john" --type person
bun scripts/db/query.ts search "AI infrastructure" --since 2026-01-01
# Deal attribution
bun scripts/db/query.ts who-shared acme-corp
# Temporal context
bun scripts/db/query.ts what-doing john-smith "3 months ago"
bun scripts/db/query.ts timeline john-smith
# Pending items
bun scripts/db/query.ts pending --owner me --type promise
# Database status
bun scripts/db/query.ts status
bun scripts/db/query.ts status --json| Command | Purpose |
|---|---|
/cyber-reindex |
Full database rebuild |
/cyber-reindex --status |
Show database status |
/cyber-reindex --extract |
Index + LLM extraction |
/cyber-reindex --extract-only |
Run extraction on indexed interactions |
SessionStart hook checks database freshness:
- Queries
batch_runstable for last run timestamp - If >24 hours old, warns user to run
/cyber-reindex - If database unavailable, shows warning to start PostgreSQL
Only create entity files when you need to add info not available elsewhere:
# Dan Meissler
**Type:** person
**Aliases:** Dan M, Meissler
## Contact
- Email: dan@example.com
- Telegram: @danmeissler
## Notes
[Context about this person]Location: /context/entities/people/ or /context/entities/orgs/
# Initialize SQLite database (no external server needed)
bun scripts/db/init.ts
# Reset and reinitialize
bun scripts/db/init.ts --reset
# Check status
bun scripts/db/init.ts --status
# Run indexer
bun scripts/db/index.ts
# Run with LLM extraction
bun scripts/db/index.ts --extract
# Environment variables (.env)
CYBOS_ANTHROPIC_KEY=sk-ant-... # For LLM extraction
CYBOS_USER_NAME=Your Name # For identity resolution
CYBOS_USER_OWNER_NAME=YourName # For owner/target labelingDatabase location: .cybos/cybos.sqlite (in app root for legacy mode) or ~/CybosVault/private/.cybos/db/cybos.sqlite (vault mode)
Projects are multi-week initiatives that need their own context, research, and artifacts. They differ from deals (investment opportunities) and are tracked in both GTD.md and optional /projects/ folders.
Projects are # headings in GTD.md (not ## headings). Tasks under a heading belong to that project.
# scheduler
- Task 1 for scheduler project
- Task 2 for scheduler project
# context-graph
- Task 1 for context graphReserved headings (not projects): # Next, # Someday, # IC, # Skip
| Scenario | GTD-only | Create /projects/ |
|---|---|---|
| Few tasks, clear scope | Yes | |
| Needs research artifacts | Yes | |
| Multiple collaborators | Yes | |
| External deliverables | Yes | |
| Spans 2+ months | Yes | |
| Has milestones/phases | Yes |
/projects/<slug>/
└── .cybos/
└── context.md # Required: goals, status, collaborators
Only .cybos/context.md is required. Organize the rest as needed for your project.
# Project: [Display Name]
**Slug:** [slug matching GTD # heading]
**Status:** [Planning | Active | On Hold | Completed | Archived]
**Type:** [Event | Accelerator | Product | Initiative]
**Started:** YYYY-MM-DD
**Target:** YYYY-MM-DD (optional)
**Lead:** [Person]
## Goal
[One paragraph: what does success look like?]
## Key Results
- [ ] KR1: Measurable outcome
## Collaborators
| Person | Role | Contact |
|--------|------|---------|
## Timeline / Milestones
| Milestone | Target | Status |
|-----------|--------|--------|
## Log
### YYYY-MM-DD
- [What happened]| Aspect | /deals | /projects |
|---|---|---|
| Purpose | Evaluate external investment | Execute internal initiative |
| Ownership | External founders | We own the project |
| Outcome | Invest / Pass decision | Deliverable completion |
| Primary artifacts | Research, memo | Content, decks, tools |
| Task source | Ad-hoc, call follow-ups | GTD.md # heading |
Rule: If it's about deciding to invest in external entity, it's a deal. Everything else is a project.
| Command | Purpose |
|---|---|
/cyber-init-project "Name" |
Create project folder with context template |
/cyber-project slug |
Show project status and tasks |
/cyber-projects |
List all projects |
/cyber-gtd --project slug |
Process tasks for specific project |
When user mentions a project:
- Check if
/projects/<slug>/exists (try kebab-case conversion) - If exists, read
/projects/<slug>/.cybos/context.md - Also check GTD.md for tasks under the
# <slug>heading - Incorporate context into response
project-root/
├── vault -> ~/CybosVault # Symlink to user data (gitignored, shows private/ and shared/)
├── .mcp.json # MCP server configuration (uses ${VAR} for env vars)
├── .claude/
│ ├── settings.json # Hook wiring, permissions
│ ├── napkin.md # Self-improvement log (mistakes, patterns, preferences)
│ ├── skills/ # Organized workflows (convention)
│ │ ├── Research/
│ │ │ ├── workflows/
│ │ │ ├── shared/
│ │ │ └── evals/
│ │ ├── Browse/
│ │ │ └── workflows/
│ │ ├── Content/
│ │ │ └── workflows/
│ │ ├── DDMemo/
│ │ │ └── workflows/
│ │ ├── GTD/
│ │ │ ├── SKILL.md
│ │ │ ├── workflows/
│ │ │ └── learnings.md
│ │ └── Self-improve/
│ │ └── SKILL.md # Always-active napkin for mistakes/patterns
│ ├── agents/ # Agent profiles for Task tool
│ ├── hooks/
│ │ └── load-context.ts # SessionStart hook
│ └── commands/ # Slash commands
├── context/ # Core context files (symlinked from vault)
│ ├── who-am-i.md
│ ├── organization.md
│ ├── investment-philosophy.md
│ ├── style/ # Writing style guides
│ │ ├── voice-identity.md # Shared persona, tone
│ │ ├── writing-style-en.md # English (essays, tweets)
│ │ └── writing-style-ru.md # Russian (Telegram)
│ ├── img-styles/ # Image style definitions
│ │ ├── _shared.md # Common rules for all styles
│ │ ├── cyberpunk.md # Grounded futurism (Blade Runner)
│ │ ├── mural.md # Sacred transformation
│ │ └── info.md # Minimal infographics
│ ├── MEMO_template.md
│ ├── calls/ # Granola call transcripts
│ │ ├── README.md
│ │ └── MMDD-title-YY/
│ ├── telegram/ # Per-person conversation logs (GramJS)
│ │ ├── README.md
│ │ ├── <person-slug>.md # Persistent conversation file
│ │ └── <group-slug>.md # Group chats too
│ ├── emails/ # Indexed emails for morning brief
│ │ ├── README.md
│ │ ├── .state.json # Dedup state (messageIds)
│ │ └── YYYY-MM-DD_from-subject/
│ │ ├── metadata.json # Email metadata + summary
│ │ └── body.md # Email content
│ └── entities/ # Entity context (indexed in SQLite)
│ ├── README.md
│ ├── people/ # Manual entity files (optional)
│ └── orgs/ # Manual entity files (optional)
├── deals/ # Deal folders
│ └── <company-slug>/
│ ├── index.md # DataView frontmatter + full deal context
│ ├── .cybos/
│ │ └── scratchpad/
│ ├── research/
│ │ ├── MMDD-<slug>-YY.md # Main synthesis
│ │ └── raw/ # Raw agent/MCP data
│ │ ├── agent-*.md
│ │ └── mcp-*.md
│ └── memo/
├── research/ # Topic/market/tech research
│ └── <topic-slug>/
│ ├── MMDD-<slug>-YY.md # Main synthesis
│ └── raw/ # Raw agent/MCP data
│ ├── agent-*.md
│ └── mcp-*.md
├── projects/ # Multi-week initiatives
│ ├── README.md
│ └── <project-slug>/
│ └── .cybos/
│ └── context.md # Goals, status, collaborators
├── content/ # Generated content
│ ├── posts/ # Telegram posts (RU) + Twitter (EN)
│ ├── tweets/ # Twitter-native threads (EN)
│ ├── essays/
│ ├── images/
│ ├── ideas/ # Browse-discovered topic ideas
│ ├── briefs/ # Morning briefs (MMDD-YY.md)
│ └── work/ # GTD task outputs (MMDD-<slug>.md)
├── config/ # Configuration files
│ ├── leverage-rules.yaml # Strategic leverage scoring rules
│ └── launchd/ # macOS scheduling plists (templates)
│ ├── com.cybos.brief-server.plist.example
│ └── com.cybos.morning-brief.plist.example
└── scripts/ # Utility scripts
├── extract-granola.ts
├── telegram-gramjs.ts # GramJS MTProto client for Telegram
├── telegram-save-drafts.ts # Save AI drafts to Telegram
├── brief-parser.ts # Markdown → JSON brief parser
├── brief-server.ts # Hono HTTP server (port 3847)
├── morning-brief.sh # Orchestrator script
├── install-brief.sh # Installation script
├── web-brief/ # React + Tailwind brief/explorer/unstuck UI
│ ├── src/
│ │ ├── App.tsx
│ │ ├── types.ts
│ │ └── api.ts
│ └── dist/ # Production build
└── db/ # SQLite database indexer
├── schema-sqlite.sql # SQLite schema with FTS5
├── client-sqlite.ts # SQLite client (bun:sqlite)
├── init.ts # Schema initialization
├── index.ts # Main batch indexer
├── extract-llm.ts # Claude Haiku extraction
├── entity-resolver.ts # TypeScript Levenshtein matching
├── query.ts # Query interface + CLI
├── extractors/ # Source-specific parsers
│ ├── calls.ts
│ ├── emails.ts
│ ├── telegram.ts
│ ├── entities.ts
│ └── deals.ts
└── prompts/ # LLM extraction prompts
├── types.ts
├── call-extraction.ts
├── email-extraction.ts
└── telegram-extraction.ts
# User Identity (required)
CYBOS_USER_NAME=Your Name
CYBOS_USER_OWNER_NAME=YourName
CYBOS_USER_SLUG=your-name
CYBOS_USER_ALIASES=Me,Your Name
# LLM Extraction (required for /cyber-reindex --extract)
CYBOS_ANTHROPIC_KEY=sk-ant-...
# Web Research (required)
PERPLEXITY_API_KEY=pplx-...
EXA_API_KEY=...
PARALLEL_API_KEY=...
# Extraction (required)
FIRECRAWL_API_KEY=fc-...
# Image Generation (required for content)
GEMINI_API_KEY=...
# Telegram (required for /cyber-telegram)
TELEGRAM_API_ID=... # Get from https://my.telegram.org/apps
TELEGRAM_API_HASH=... # Get from https://my.telegram.org/apps
# Documents (optional but recommended)
NOTION_TOKEN=secret_...| Hook | Event | Action |
|---|---|---|
load-context.ts |
SessionStart | Inject identity + deal-loading instructions + database freshness check |
The hook injects:
- User identity from
context/who-am-i.md - Organization context from
context/organization.md - Database freshness check (warns if >24 hours stale)
- Deal context auto-loading instructions
- Logging requirement reminder
Database Freshness Check:
- Queries
batch_runstable viabun scripts/db/query.ts status --json - If database available and last run >24h, shows warning to run
/cyber-reindex - If database not initialized, shows warning to run
/cyber-reindex
Configuration in .claude/settings.json:
{
"hooks": {
"SessionStart": [
{
"type": "command",
"command": "bun .claude/hooks/load-context.ts"
}
]
}
}Unified logging location: ~/CybosVault/private/.cybos/logs/
All logs are stored in the vault for portability and backup. Path resolved via scripts/paths.ts:getLogsPath().
| Pattern | Source | Purpose |
|---|---|---|
MMDD-YY.md |
Workflows, Claude | Daily activity logs (workflow completions, MCP calls) |
morning-brief.log |
morning-brief.sh | Brief generation run logs |
reindex.log |
reindex.sh | Database indexing run logs |
brief-server.out.log |
LaunchD | Brief server stdout |
brief-server.err.log |
LaunchD | Brief server stderr |
morning-brief.out.log |
LaunchD | Morning brief daemon stdout |
morning-brief.err.log |
LaunchD | Morning brief daemon stderr |
reindex.out.log |
LaunchD | Reindex daemon stdout |
reindex.err.log |
LaunchD | Reindex daemon stderr |
Shell scripts source scripts/get-log-path.sh which exports VAULT_LOG_DIR:
source "$SCRIPT_DIR/get-log-path.sh"
LOG_FILE="$VAULT_LOG_DIR/my-script.log"TypeScript scripts use scripts/paths.ts:
import { getLogsPath } from './paths'
const logDir = getLogsPath() // ~/CybosVault/private/.cybos/logsLaunchD plists use __VAULT_LOGS__ placeholder (substituted by install-brief.sh).
Workflow completion:
## HH:MM | category | type | subject
- Workflow: workflow-name
- Intensity: Quick | Standard | Deep (for research)
- Duration: Xm Ys
- Output: /path/to/output.md
- Agents: agent1, agent2, agent3 (X/Y success)
- MCPs used: perplexity, exa, exa-contents, parallel-search, etc.
- Confidence: High | Medium | Low (for research)
---MCP call:
## HH:MM | mcp | [server-name] | [operation]
- Query/URL: [request details]
- Status: Success | Failed
- Error: [if failed]
- Fallback: [if used]
- Duration: Xs
- Cost: $X.XX (estimate)
---Full logging specification: .claude/skills/Research/shared/logging.md