Install
$ agentstack add skill-netanel-abergel-pa-skills-chat-history-local ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Chat History Skill
Search past WhatsApp messages stored in the audit log DB (messages table), with file-based fallback when DB is unavailable.
Minimum Model
Any model. Operations are lookup/query based.
Step 1: Detect PADBURL availability
import os, sys
def get_db_conn():
url = os.environ.get('PA_DB_URL') or os.environ.get('HELENI_DB_URL')
if not url:
return None
try:
import psycopg2
conn = psycopg2.connect(url)
return conn
except Exception:
return None
conn = get_db_conn()
DB_AVAILABLE = conn is not None
DB Mode (PADBURL available)
All queries against the messages table. Output format: timestamp | sender | chat | body.
Full-text search
import os, psycopg2
url = os.environ.get('PA_DB_URL') or os.environ.get('HELENI_DB_URL')
conn = psycopg2.connect(url)
cur = conn.cursor()
search_term = "budget" # replace with actual term
cur.execute("""
SELECT ts, sender_name, chat_name, body
FROM messages
WHERE body ILIKE %s
ORDER BY ts DESC
LIMIT 20
""", (f'%{search_term}%',))
for ts, sender, chat, body in cur.fetchall():
print(f"{ts} | {sender} | {chat} | {body[:100]}")
conn.close()
Search by contact name or phone
cur.execute("""
SELECT ts, sender_name, chat_name, body
FROM messages
WHERE sender_name ILIKE %s OR sender_phone ILIKE %s OR chat_name ILIKE %s
ORDER BY ts DESC
LIMIT 20
""", (f'%{contact}%', f'%{contact}%', f'%{contact}%'))
Search by date range
cur.execute("""
SELECT ts, sender_name, chat_name, body
FROM messages
WHERE ts BETWEEN %s AND %s
ORDER BY ts ASC
LIMIT 100
""", ('2026-04-01', '2026-04-07'))
Find recent unanswered messages (last 24h)
cur.execute("""
SELECT chat_id, chat_name, MAX(ts) as last_msg, COUNT(*) as msg_count
FROM messages
WHERE is_from_me = false
AND ts > NOW() - INTERVAL '24 hours'
AND chat_id NOT IN (
SELECT DISTINCT chat_id FROM messages
WHERE is_from_me = true
AND ts > NOW() - INTERVAL '24 hours'
)
GROUP BY chat_id, chat_name
ORDER BY last_msg DESC
""")
for chat_id, chat_name, last_msg, count in cur.fetchall():
print(f"{last_msg} | {chat_name or chat_id} | {count} unanswered")
DB stats (quick overview)
cur.execute("""
SELECT
COUNT(*) as total,
COUNT(*) FILTER (WHERE ts > NOW() - INTERVAL '1 day') as today,
MIN(ts) as first_msg,
MAX(ts) as last_msg
FROM messages
""")
row = cur.fetchone()
print(f"Total: {row[0]} | Today: {row[1]} | Range: {row[2]} → {row[3]}")
File Fallback (no DB)
When PA_DB_URL is not set or DB is unreachable, search the file-based context files.
Search context files with grep
SEARCH_TERM="budget"
WHATSAPP_DIR="/path/to/workspace/memory/whatsapp"
grep -r --include="*.md" -l "$SEARCH_TERM" "$WHATSAPP_DIR" | while read file; do
echo "=== $file ==="
grep -n "$SEARCH_TERM" "$file" | head -5
done
Search by contact/group name
CONTACT="John" # replace with actual contact name
find "$WHATSAPP_DIR" -name "meta.json" | xargs grep -l "$CONTACT" | while read meta; do
dir=$(dirname "$meta")
echo "=== $(cat $meta | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d.get(\"name\",\"unknown\"))') ==="
cat "$dir/context.md" | tail -20
done
Output Format
Always present results as:
[2026-04-06 18:32] Daniel (Core Team) → "Can we review the budget today?"
[2026-04-06 18:45] Heleni (Core Team) → "Sure, I'll set it up"
If no results found → say "No messages found matching that query."
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: netanel-abergel
- Source: netanel-abergel/pa-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.