phoenixclaw
Passive journaling skill that scans daily conversations from ALL session paths (main, agents, cron) via cron to generate markdown journals using semantic und...
Passive journaling skill that scans daily conversations from ALL session paths (main, agents, cron) via cron to generate markdown journals using semantic und...
Real data. Real impact.
Emerging
Developers
Per week
Open source
Skills give you superpowers. Install in 30 seconds.
PhoenixClaw automatically distills daily conversations into meaningful reflections using semantic intelligence.
Automatically identifies journal-worthy moments, patterns, and growth opportunities.
[!critical] MANDATORY: Complete Workflow Execution This 9-step workflow MUST be executed in full regardless of invocation method:
- Cron execution (10 PM nightly)
- Manual invocation ("Show me my journal", "Generate today's journal", etc.)
- Regeneration requests ("Regenerate my journal", "Update today's entry")
Never skip steps. Partial execution causes:
- Missing images (session logs not scanned)
- Missing finance data (Ledger plugin not triggered)
- Incomplete journals (plugins not executed)
PhoenixClaw follows a structured pipeline to ensure consistency and depth:
~/.phoenixclaw/config.yaml. If missing, initiate the onboarding flow defined in references/user-config.md.memory/YYYY-MM-DD.md and memory/YYYY-MM-DD-*.md files for manually recorded daily reflections. These files contain personal thoughts, emotions, and context that users explicitly ask the AI to remember via commands like "记一下" (remember this). CRITICAL: Do not skip these files - they contain explicit user reflections that session logs may miss.memory_get for the current day's memory, then CRITICAL: Scan ALL raw session logs and filter by message timestamp. Session files are often split across multiple files. Do NOT classify images by session file mtime:
# Read all session logs from ALL known OpenClaw locations, then filter by per-message timestamp # Use timezone-aware epoch range to avoid UTC/local-day mismatches. TARGET_DAY="$(date +%Y-%m-%d)" TARGET_TZ="${TARGET_TZ:-Asia/Shanghai}" read START_EPOCH END_EPOCH < <( python3 - <<'PY' "$TARGET_DAY" "$TARGET_TZ"
from datetime import datetime, timedelta from zoneinfo import ZoneInfo import sys
day, tz = sys.argv[1], sys.argv[2] start = datetime.strptime(day, "%Y-%m-%d").replace(tzinfo=ZoneInfo(tz)) end = start + timedelta(days=1) print(int(start.timestamp()), int(end.timestamp())) PY )
# Recursively scan all session directories (multi-agent architecture support) for dir in "$HOME/.openclaw/sessions" \ "$HOME/.openclaw/agents" \ "$HOME/.openclaw/cron/runs" \ "$HOME/.agent/sessions"; do [ -d "$dir" ] || continue find "$dir" -type f -name "*.jsonl" -print0 done | xargs -0 jq -cr --argjson start "$START_EPOCH" --argjson end "$END_EPOCH" ' (.timestamp // .created_at // empty) as $ts | ($ts | split(".")[0] + "Z" | fromdateiso8601?) as $epoch | select($epoch != null and $epoch >= $start and $epoch < $end) ' ``` Read **all matching files** regardless of their numeric naming (e.g., file_22, file_23 may be earlier in name but still contain today's messages). - **EXTRACT IMAGES FROM SESSION LOGS**: Session logs contain `type: "image"` entries with file paths. You MUST: 1. Find all image entries (e.g., `"type":"image"`) 2. Keep only entries where message `timestamp` is in the target date range 3. Extract the `file_path` or `url` fields 4. Copy files into `assets/YYYY-MM-DD/` 5. Rename with descriptive names when possible - **Why session logs are mandatory**: `memory_get` returns **text only**. Image metadata, photo references, and media attachments are **only available in session logs**. Skipping session logs = missing all photos. - **Activity signal quality**: Do not treat heartbeat/cron system noise as user activity. Extract user/assistant conversational content and media events first, then classify moments. - **FILTER HEARTBEAT MESSAGES (CRITICAL)**: Session logs contain system heartbeat messages that MUST be excluded from journaling. When scanning messages, SKIP any message matching these criteria: 1. **User heartbeat prompts**: Messages containing "Read HEARTBEAT.md" AND "reply HEARTBEAT_OK" 2. **Assistant heartbeat responses**: Messages containing ONLY "HEARTBEAT_OK" (with optional leading/trailing whitespace) 3. **Cron system messages**: Messages with role "system" or "cron" containing job execution summaries (e.g., "Cron job completed", "A cron job")Example jq filter to exclude heartbeats:
# Exclude heartbeat messages | select( (.message.content? | type == "array" and (.message.content | map(.text?) | join("") | test("Read HEARTBEAT\.md"; "i") | not)) and (.message.content? | type == "array" and (.message.content | map(.text?) | join("") | test("^\\s*HEARTBEAT_OK\\s*$"; "i") | not)) )
Edge case - Midnight boundary: For late-night activity that spans midnight, expand the timestamp range to include spillover windows (for example, previous day 23:00-24:00) and still filter per-message by timestamp
.
memory_search (skip if embeddings unavailable)Moment Identification: Identify "journal-worthy" content: critical decisions, emotional shifts, milestones, or shared media. See
references/media-handling.md for photo processing. This step generates the moments data structure that plugins depend on.
Image Processing (CRITICAL):
Filter Finance Screenshots (NEW): Payment screenshots (WeChat Pay, Alipay, etc.) should NOT be included in the journal narrative. These are tool images, not life moments.
Detection criteria (check any):
Handling rules:
Mark as
finance_screenshot type
Route to Ledger plugin (if enabled) for transaction recording
EXCLUDE from journal main narrative unless explicitly described as part of a life moment (e.g., "今天请朋友吃饭" with payment screenshot)
Never include raw payment screenshots in daily journal images section
Match images to moments (e.g., breakfast photo → breakfast moment)
Store image metadata with moments for journal embedding
Pattern Recognition: Detect recurring themes, mood fluctuations, and energy levels. Map these to growth opportunities using
references/skill-recommendations.md.
Plugin Execution: Execute all registered plugins at their declared hook points. See
references/plugin-protocol.md for the complete plugin lifecycle:
pre-analysis → before conversation analysispost-moment-analysis → Ledger and other primary plugins execute herepost-pattern-analysis → after patterns detectedjournal-generation → plugins inject custom sectionspost-journal → after journal completeJournal Generation: Synthesize the day's events into a beautiful Markdown file using
assets/daily-template.md. Follow the visual guidelines in references/visual-design.md. Include all plugin-generated sections at their declared section_order positions.
references/media-handling.md with descriptive captions.../ or ../../): calculate dynamically from daily_file_path and image_path.image_124917_2.jpg, the link must reference that exact filename.Timeline Integration: If significant events occurred, append them to the master index in
timeline.md using the format from assets/timeline-template.md and references/obsidian-format.md.
Growth Mapping: Update
growth-map.md (based on assets/growth-map-template.md) if new behavioral patterns or skill interests are detected.
Profile Evolution: Update the long-term user profile (
profile.md) to reflect the latest observations on values, goals, and personality traits. See references/profile-evolution.md and assets/profile-template.md.
PhoenixClaw is designed to run without user intervention. It utilizes OpenClaw's built-in cron system to trigger its analysis daily at 10:00 PM local time (0 22 * * *).
references/cron-setup.md.To solve the 22:00-24:00 content loss issue, PhoenixClaw now supports a rolling journal window mechanism:
Problem: Fixed 24-hour window (00:00-22:00) misses content between 22:00-24:00 when journal is generated at 22:00.
Solution:
scripts/rolling-journal.js scans from last journal time → now instead of fixed daily boundaries.
Features:
~/.phoenixclaw/config.yaml)late-night-supplement.jsConfiguration (
~/.phoenixclaw/config.yaml):
schedule: hour: 22 # Journal generation time minute: 0 rolling_window: true # Enable rolling window (recommended)
Usage:
# Default: generate from last journal to now node scripts/rolling-journal.jsSpecific date
node scripts/rolling-journal.js 2026-02-12
While passive by design, users can interact with PhoenixClaw directly using these phrases:
[!warning] Manual Invocation = Full Pipeline When users request journal generation/regeneration, you MUST execute the complete 9-step Core Workflow above. This ensures:
- Photos are included (via session log scanning)
- Ledger plugin runs (via
hook)post-moment-analysis- All plugins execute (at their respective hook points)
Common mistakes to avoid:
- ❌ Only calling
(misses photos)memory_get- ❌ Skipping moment identification (plugins never trigger)
- ❌ Generating journal directly without plugin sections
references/)user-config.md: Initial onboarding and persistence settings.cron-setup.md: Technical configuration for nightly automation.plugin-protocol.md: Plugin architecture, hook points, and integration protocol.media-handling.md: Strategies for extracting meaning from photos and rich media.session-day-audit.js: Diagnostic utility for verifying target-day message coverage across session logs.visual-design.md: Layout principles for readability and aesthetics.obsidian-format.md: Ensuring compatibility with Obsidian and other PKM tools.profile-evolution.md: How the system maintains a long-term user identity.skill-recommendations.md: Logic for suggesting new skills based on journal insights.assets/)daily-template.md: The blueprint for daily journal entries.weekly-template.md: The blueprint for high-level weekly summaries.profile-template.md: Structure for the profile.md persistent identity file.timeline-template.md: Structure for the timeline.md chronological index.growth-map-template.md: Structure for the growth-map.md thematic index.No automatic installation available. Please visit the source repository for installation instructions.
View Installation Instructions1,500+ AI skills, agents & workflows. Install in 30 seconds. Part of the Torly.ai family.
© 2026 Torly.ai. All rights reserved.