pkm-mcp-server 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -1
- package/README.md +70 -3
- package/cli.js +26 -0
- package/hooks/README.md +125 -0
- package/hooks/capture-handler.sh +81 -0
- package/hooks/load-context.js +64 -0
- package/hooks/resolve-project.js +67 -0
- package/hooks/session-start.js +91 -0
- package/hooks/stop-sweep.sh +81 -0
- package/index.js +458 -451
- package/init.js +577 -0
- package/package.json +8 -6
- package/sample-project/CLAUDE.md +15 -0
- package/templates/note.md +7 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Stop hook: passive PKM capture sweep
|
|
3
|
+
# Runs async after each Claude response. Spawns claude -p with Haiku
|
|
4
|
+
# to analyze the transcript and capture decisions/tasks/findings.
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
LOG_DIR="${VAULT_PATH:?}/.obsidian/hook-logs"
|
|
9
|
+
mkdir -p "$LOG_DIR"
|
|
10
|
+
trap 'echo "stop-sweep: failed at line $LINENO" >> "$LOG_DIR/sweep-errors.log"' ERR
|
|
11
|
+
|
|
12
|
+
# Read hook input from stdin
|
|
13
|
+
INPUT=$(cat)
|
|
14
|
+
|
|
15
|
+
eval "$(echo "$INPUT" | node -e "
|
|
16
|
+
let b='';
|
|
17
|
+
process.stdin.on('data',c=>b+=c);
|
|
18
|
+
process.stdin.on('end',()=>{
|
|
19
|
+
const j=JSON.parse(b);
|
|
20
|
+
console.log('TRANSCRIPT_PATH='+JSON.stringify(j.transcript_path||''));
|
|
21
|
+
console.log('SESSION_ID='+JSON.stringify(j.session_id||''));
|
|
22
|
+
console.log('CWD='+JSON.stringify(j.cwd||''));
|
|
23
|
+
})
|
|
24
|
+
")"
|
|
25
|
+
|
|
26
|
+
# Skip if no transcript
|
|
27
|
+
if [ -z "$TRANSCRIPT_PATH" ] || [ ! -f "$TRANSCRIPT_PATH" ]; then
|
|
28
|
+
echo "stop-sweep: skipping - transcript_path empty or missing ('$TRANSCRIPT_PATH')" >&2
|
|
29
|
+
exit 0
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# MCP config for obsidian-pkm server
|
|
33
|
+
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd -P)
|
|
34
|
+
MCP_CONFIG=$(node -e "console.log(JSON.stringify({mcpServers:{'obsidian-pkm':{command:'node',args:[process.argv[1]],env:{VAULT_PATH:process.argv[2]}}}}))" "$SCRIPT_DIR/../index.js" "${VAULT_PATH:-$HOME/Documents/PKM}")
|
|
35
|
+
|
|
36
|
+
PROJECT_NAME=$(basename "$CWD")
|
|
37
|
+
SESSION_SHORT=$(echo "$SESSION_ID" | cut -c1-8)
|
|
38
|
+
TODAY=$(date +%Y-%m-%d)
|
|
39
|
+
NOW=$(date +%H:%M)
|
|
40
|
+
|
|
41
|
+
# Build the prompt
|
|
42
|
+
PROMPT="You are a PKM passive capture agent. Your job is to identify decisions, task changes, and research findings from the most recent conversation exchange and append them to the vault staging inbox.
|
|
43
|
+
|
|
44
|
+
## Transcript
|
|
45
|
+
|
|
46
|
+
Read the file at: $TRANSCRIPT_PATH
|
|
47
|
+
|
|
48
|
+
Find the LAST user message and LAST assistant message at the end of the file — these are the current exchange. One exchange = one contiguous user message + one contiguous assistant response (the last complete turn pair). All prior messages are historical context only. Do NOT capture anything from prior messages.
|
|
49
|
+
|
|
50
|
+
## What to Capture
|
|
51
|
+
|
|
52
|
+
1. **Decisions**: Technical or architectural choices that were AGREED upon (not proposed, not still being discussed)
|
|
53
|
+
2. **Task changes**: New tasks identified, tasks completed, priority changes, blockers discovered
|
|
54
|
+
3. **Research findings**: Patterns discovered, library behaviors documented, gotchas found
|
|
55
|
+
|
|
56
|
+
## Noise Suppression
|
|
57
|
+
|
|
58
|
+
Be conservative. Skip: trivial exchanges, clarification Q&A that hasn't resolved, implementation details obvious from code, anything restating existing project context. When in doubt, don't capture.
|
|
59
|
+
|
|
60
|
+
## Deduplication
|
|
61
|
+
|
|
62
|
+
If the assistant message in the current exchange contains a vault_capture tool call, the content of that capture is already being handled by the explicit capture agent. Do NOT also capture it in the staging inbox — skip it to avoid semantic duplication.
|
|
63
|
+
|
|
64
|
+
## Output
|
|
65
|
+
|
|
66
|
+
If you find PKM-worthy content, use vault_append to add entries to 00-Inbox/captures-${TODAY}.md. If the file doesn't exist, create it first with vault_write (template: fleeting-note, tags: [capture, auto]). Each entry format:
|
|
67
|
+
|
|
68
|
+
## ${NOW} — {Category}: {Title}
|
|
69
|
+
|
|
70
|
+
{1-3 sentence description}
|
|
71
|
+
|
|
72
|
+
**Source:** ${PROJECT_NAME}, session ${SESSION_SHORT}
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
If nothing is PKM-worthy, do nothing."
|
|
77
|
+
|
|
78
|
+
# Spawn claude -p in background with logging
|
|
79
|
+
echo "$PROMPT" | nohup claude -p --model haiku --mcp-config "$MCP_CONFIG" --max-turns 5 --allowedTools "mcp__obsidian-pkm__vault_write mcp__obsidian-pkm__vault_append mcp__obsidian-pkm__vault_read" >> "$LOG_DIR/sweep-$(date +%Y%m%d-%H%M%S).log" 2>&1 &
|
|
80
|
+
|
|
81
|
+
exit 0
|