11#! /bin/bash
22set -e
33
4- # PATH for systemd (claude, uv, npx in ~/.local/bin and node)
5- export PATH=" $HOME /.local/bin:/usr/local/bin:/usr/bin:/bin:$PATH "
6- export HOME=" /home/shima"
4+ # PATH for systemd (claude, uv, npx, node)
5+ export PATH=" $HOME /.local/bin:$HOME /.nvm/versions/node/$( ls " $HOME /.nvm/versions/node/" 2> /dev/null | tail -1) /bin:/usr/local/bin:/usr/bin:/bin:$PATH "
76
8- # Paths
9- PROJECT_DIR=" /home/shima/projects/agent-second-brain "
7+ # Paths — auto-detect from script location
8+ PROJECT_DIR=" $( cd " $( dirname " $0 " ) /.. " && pwd ) "
109VAULT_DIR=" $PROJECT_DIR /vault"
1110ENV_FILE=" $PROJECT_DIR /.env"
1211
@@ -21,33 +20,155 @@ if [ -z "$TELEGRAM_BOT_TOKEN" ]; then
2120 exit 1
2221fi
2322
24- # MCP timeout for stdio server (default 5 sec is too short)
25- export MCP_TIMEOUT=30000
26- export MAX_MCP_OUTPUT_TOKENS=50000
23+ # Timezone (configure in .env: TZ=Your/Timezone)
24+ export TZ=" ${TZ:- UTC} "
2725
2826# Date and chat_id
2927TODAY=$( date +%Y-%m-%d)
3028CHAT_ID=" ${ALLOWED_USER_IDS// [\[\]]/ } " # remove brackets from [123456]
3129
3230echo " === d-brain processing for $TODAY ==="
3331
34- # Run Claude from vault/ for context (reads vault/.claude/CLAUDE.md)
35- cd " $VAULT_DIR "
36- REPORT=$( claude --print --dangerously-skip-permissions \
37- --mcp-config " $PROJECT_DIR /mcp-config.json" \
38- -p " Today is $TODAY . Execute daily processing according to dbrain-processor skill.
32+ # ── ORIENT PHASE: pre-flight checks ──
33+ DAILY_FILE=" $VAULT_DIR /daily/$TODAY .md"
34+ HANDOFF_FILE=" $VAULT_DIR /.session/handoff.md"
35+ GRAPH_FILE=" $VAULT_DIR /.graph/vault-graph.json"
36+
37+ # Check daily file exists and has content
38+ if [ ! -f " $DAILY_FILE " ]; then
39+ echo " ORIENT: daily/$TODAY .md not found — creating empty file"
40+ echo " # $TODAY " > " $DAILY_FILE "
41+ fi
42+
43+ DAILY_SIZE=$( wc -c < " $DAILY_FILE " 2> /dev/null || echo " 0" )
44+ if [ " $DAILY_SIZE " -lt 50 ]; then
45+ echo " ORIENT: daily/$TODAY .md is empty ($DAILY_SIZE bytes) — skipping Claude processing"
46+ echo " ORIENT: Running graph rebuild only"
47+
48+ # Still rebuild graph and commit
49+ cd " $VAULT_DIR "
50+ uv run .claude/skills/graph-builder/scripts/analyze.py || echo " Graph rebuild failed (non-critical)"
51+ cd " $PROJECT_DIR "
52+
53+ git add -A
54+ git commit -m " chore: process daily $TODAY " || true
55+ git push || true
56+ echo " === Done (empty daily, graph-only) ==="
57+ exit 0
58+ fi
59+
60+ # Check handoff exists
61+ if [ ! -f " $HANDOFF_FILE " ]; then
62+ echo " ORIENT: handoff.md not found — creating stub"
63+ mkdir -p " $VAULT_DIR /.session"
64+ echo -e " ---\nupdated: $( date -Iseconds) \n---\n\n## Last Session\n(none)\n\n## Observations" > " $HANDOFF_FILE "
65+ fi
66+
67+ # Check graph freshness (warn if >7 days old)
68+ if [ -f " $GRAPH_FILE " ]; then
69+ GRAPH_AGE=$(( ($(date +% s) - $(stat - c % Y "$GRAPH_FILE " 2 >/ dev/ null || stat - f % m "$GRAPH_FILE " 2 >/ dev/ null || echo 0 )) / 86400 ))
70+ if [ " $GRAPH_AGE " -gt 7 ]; then
71+ echo " ORIENT: vault-graph.json is $GRAPH_AGE days old (>7)"
72+ fi
73+ fi
3974
40- CRITICAL: MCP loads in 10-30 seconds. You are NOT in subprocess — MCP IS running, just initializing.
75+ echo " ORIENT: daily=$DAILY_SIZE bytes, handoff=OK, graph=OK"
76+ # ── END ORIENT PHASE ──
4177
42- Algorithm:
43- 1. Call mcp__todoist__find-tasks-by-date
44- 2. Error? Wait 10 sec, read goals/, daily/ files
45- 3. Call again
46- 4. Error again? Wait 20 more sec
47- 5. Third call — GUARANTEED to work
78+ # MCP timeout for stdio server (default 5 sec is too short)
79+ export MCP_TIMEOUT=30000
80+ export MAX_MCP_OUTPUT_TOKENS=50000
81+
82+ # ── 3-PHASE PIPELINE ──
83+ # Phase 1: CAPTURE (classify entries → JSON)
84+ # Phase 2: EXECUTE (create tasks, save thoughts → JSON)
85+ # Phase 3: REFLECT (generate HTML report, update MEMORY)
86+ # Each phase = fresh Claude context for better quality.
87+
88+ SESSION_DIR=" $VAULT_DIR /.session"
89+ mkdir -p " $SESSION_DIR "
90+ CAPTURE_FILE=" $SESSION_DIR /capture.json"
91+ EXECUTE_FILE=" $SESSION_DIR /execute.json"
92+
93+ # Find yearly goals file (auto-detect year)
94+ YEARLY_GOALS=$( ls " $VAULT_DIR /goals/1-yearly-" * .md 2> /dev/null | tail -1)
95+ YEARLY_GOALS_NAME=$( basename " $YEARLY_GOALS " 2> /dev/null || echo " 1-yearly.md" )
96+
97+ # MCP config (needed for Phase 2)
98+ MCP_PROMPT=" CRITICAL: MCP loads in 10-30 seconds. You are NOT in subprocess.
99+ Algorithm: 1) Call. 2) Error? Wait 10 sec. 3) Call again. 4) Wait 20 sec. 5) Call — GUARANTEED to work.
100+ DO NOT say MCP unavailable. It is available. Just wait and call."
48101
49- DO NOT say MCP unavailable. It is available. Just wait and call." \
102+ cd " $VAULT_DIR "
103+
104+ # ── Phase 1: CAPTURE ──
105+ echo " === Phase 1: CAPTURE ==="
106+ CAPTURE=$( claude --print --dangerously-skip-permissions \
107+ -p " Today is $TODAY . Read .claude/skills/dbrain-processor/phases/capture.md and execute Phase 1.
108+ Read daily/$TODAY .md, goals/3-weekly.md, goals/2-monthly.md, goals/$YEARLY_GOALS_NAME .
109+ Classify each entry. Return ONLY JSON." \
50110 2>&1 ) || true
111+
112+ # Extract JSON from output (Claude may add text around it)
113+ echo " $CAPTURE " | grep -o ' {.*}' | python3 -c "
114+ import sys, json
115+ for line in sys.stdin:
116+ try:
117+ data = json.loads(line.strip())
118+ json.dump(data, sys.stdout, ensure_ascii=False, indent=2)
119+ sys.exit(0)
120+ except: pass
121+ # Fallback: save raw output
122+ sys.stdout.write('{\" error\" : \" failed to parse capture output\" , \" raw\" : \" see capture.log\" }')
123+ " > " $CAPTURE_FILE " 2> /dev/null || echo ' {"error": "capture failed"}' > " $CAPTURE_FILE "
124+
125+ echo " Capture saved: $( wc -c < " $CAPTURE_FILE " ) bytes"
126+
127+ # Check if capture produced valid entries
128+ if grep -q ' "error"' " $CAPTURE_FILE " ; then
129+ echo " WARN: Capture phase had issues, falling back to monolith mode"
130+ # Fallback to monolith processing
131+ REPORT=$( claude --print --dangerously-skip-permissions \
132+ --mcp-config " $PROJECT_DIR /mcp-config.json" \
133+ -p " Today is $TODAY . Execute daily processing according to dbrain-processor skill.
134+ $MCP_PROMPT " \
135+ 2>&1 ) || true
136+ else
137+ # ── Phase 2: EXECUTE ──
138+ echo " === Phase 2: EXECUTE ==="
139+ EXECUTE=$( claude --print --dangerously-skip-permissions \
140+ --mcp-config " $PROJECT_DIR /mcp-config.json" \
141+ -p " Today is $TODAY . Read .claude/skills/dbrain-processor/phases/execute.md and execute Phase 2.
142+ Read .session/capture.json for input data.
143+ Read business/_index.md and projects/_index.md for context.
144+ Create tasks in Todoist, save thoughts, update CRM. Return ONLY JSON.
145+ $MCP_PROMPT " \
146+ 2>&1 ) || true
147+
148+ echo " $EXECUTE " | grep -o ' {.*}' | python3 -c "
149+ import sys, json
150+ for line in sys.stdin:
151+ try:
152+ data = json.loads(line.strip())
153+ json.dump(data, sys.stdout, ensure_ascii=False, indent=2)
154+ sys.exit(0)
155+ except: pass
156+ sys.stdout.write('{\" error\" : \" failed to parse execute output\" }')
157+ " > " $EXECUTE_FILE " 2> /dev/null || echo ' {"error": "execute failed"}' > " $EXECUTE_FILE "
158+
159+ echo " Execute saved: $( wc -c < " $EXECUTE_FILE " ) bytes"
160+
161+ # ── Phase 3: REFLECT ──
162+ echo " === Phase 3: REFLECT ==="
163+ REPORT=$( claude --print --dangerously-skip-permissions \
164+ -p " Today is $TODAY . Read .claude/skills/dbrain-processor/phases/reflect.md and execute Phase 3.
165+ Read .session/capture.json and .session/execute.json for input data.
166+ Read MEMORY.md, .session/handoff.md, .graph/health-history.json.
167+ Generate HTML report, update MEMORY, record observations.
168+ Return ONLY RAW HTML (for Telegram)." \
169+ 2>&1 ) || true
170+ fi
171+
51172cd " $PROJECT_DIR "
52173
53174echo " === Claude output ==="
@@ -61,6 +182,10 @@ REPORT_CLEAN=$(echo "$REPORT" | sed '/<!--/,/-->/d')
61182echo " === Rebuilding vault graph ==="
62183cd " $VAULT_DIR "
63184uv run .claude/skills/graph-builder/scripts/analyze.py || echo " Graph rebuild failed (non-critical)"
185+
186+ # Memory decay (update relevance scores and tiers)
187+ echo " === Memory decay ==="
188+ uv run .claude/skills/agent-memory/scripts/memory-engine.py decay . || echo " Memory decay failed (non-critical)"
64189cd " $PROJECT_DIR "
65190
66191# Git commit
0 commit comments