Skip to content

Commit 039d753

Browse files
committed
Merge branch 'v2' — agent-memory, vault-health, 3-phase pipeline
2 parents 21cf0ad + 53fa102 commit 039d753

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+6257
-1684
lines changed

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,14 @@ node_modules/
2424
# OS
2525
.DS_Store
2626
Thumbs.db
27+
28+
# Vault personal data (never commit these)
29+
vault/daily/
30+
vault/contacts/
31+
vault/finances/
32+
vault/attachments/
33+
vault/.session/
34+
vault/.graph/
35+
vault/business/
36+
vault/projects/
37+
vault/thoughts/

README.md

Lines changed: 157 additions & 1053 deletions
Large diffs are not rendered by default.

README.ru.md

Lines changed: 367 additions & 0 deletions
Large diffs are not rendered by default.

scripts/process.sh

Lines changed: 146 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
#!/bin/bash
22
set -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)"
109
VAULT_DIR="$PROJECT_DIR/vault"
1110
ENV_FILE="$PROJECT_DIR/.env"
1211

@@ -21,33 +20,155 @@ if [ -z "$TELEGRAM_BOT_TOKEN" ]; then
2120
exit 1
2221
fi
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
2927
TODAY=$(date +%Y-%m-%d)
3028
CHAT_ID="${ALLOWED_USER_IDS//[\[\]]/}" # remove brackets from [123456]
3129

3230
echo "=== 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+
51172
cd "$PROJECT_DIR"
52173

53174
echo "=== Claude output ==="
@@ -61,6 +182,10 @@ REPORT_CLEAN=$(echo "$REPORT" | sed '/<!--/,/-->/d')
61182
echo "=== Rebuilding vault graph ==="
62183
cd "$VAULT_DIR"
63184
uv 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)"
64189
cd "$PROJECT_DIR"
65190

66191
# Git commit

vault/.claude-plugin/plugin.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
"version": "2.0.0",
44
"description": "Voice-first personal assistant for capturing thoughts and tasks via Telegram, with goal tracking and Obsidian integration",
55
"author": {
6-
"name": "Shima",
7-
"url": "https://github.com/shima"
6+
"name": "[Your Name]",
7+
"url": "https://github.com/[yourusername]"
88
},
99
"license": "MIT",
1010
"capabilities": {

0 commit comments

Comments
 (0)