Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,20 @@ pip install cli-mem
pip install "cli-mem[ai]"
```

Then activate the shell hook:
Then activate the shell hook for your shell:

```bash
# zsh
echo 'eval "$(mem init zsh)"' >> ~/.zshrc
source ~/.zshrc

# bash
echo 'eval "$(mem init bash)"' >> ~/.bashrc
source ~/.bashrc

# fish
echo 'mem init fish | source' >> ~/.config/fish/config.fish
source ~/.config/fish/config.fish
```

That's it. Every command you type is now silently captured with full context (directory, git repo, exit code, duration).
Expand Down Expand Up @@ -142,6 +151,8 @@ mem export k8s # copy JSON to clipboard
mem export k8s --format markdown # copy as markdown
mem export k8s --stdout # print instead of clipboard

mem import # import from clipboard (auto-detect format + group name)
mem import -g renamed # import from clipboard with custom group name
mem import runbook.json -g ops # import from file (auto-detects format)
mem import runbook.md -g ops # markdown works too
```
Expand Down Expand Up @@ -248,7 +259,7 @@ mem stats # top commands, repos, totals
mem stats --json # machine-readable stats
mem forget "API_KEY=sk-..." # permanently delete matching commands
mem forget "password" --yes # skip confirmation
mem init zsh # print shell hook code
mem init zsh # print shell hook code (also: bash, fish)
```

---
Expand Down Expand Up @@ -350,7 +361,7 @@ brew uninstall mem # or: pip uninstall cli-mem
rm -rf ~/.mem # remove all captured data
```

Remove the `eval "$(mem init zsh)"` line from `~/.zshrc`.
Remove the shell hook line from your shell config (`~/.zshrc`, `~/.bashrc`, or `~/.config/fish/config.fish`).

---

Expand Down
31 changes: 31 additions & 0 deletions command-groups/databases/postgres-debug.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"postgres-debug": {
"description": "PostgreSQL troubleshooting -- connections, locks, slow queries",
"commands": [
{
"cmd": "psql -h $PGHOST -U $PGUSER -d $PGDATABASE -c \"SELECT count(*), state FROM pg_stat_activity GROUP BY state ORDER BY count DESC;\"",
"comment": "connection count by state -- idle in transaction is a red flag"
},
{
"cmd": "psql -h $PGHOST -U $PGUSER -d $PGDATABASE -c \"SELECT pid, now() - pg_stat_activity.query_start AS duration, query FROM pg_stat_activity WHERE state = 'active' AND query NOT LIKE '%pg_stat_activity%' ORDER BY duration DESC LIMIT 10;\"",
"comment": "currently running queries sorted by duration"
},
{
"cmd": "psql -h $PGHOST -U $PGUSER -d $PGDATABASE -c \"SELECT blocked.pid AS blocked_pid, blocked.query AS blocked_query, blocking.pid AS blocking_pid, blocking.query AS blocking_query FROM pg_stat_activity blocked JOIN pg_locks bl ON bl.pid = blocked.pid JOIN pg_locks bk ON bk.locktype = bl.locktype AND bk.relation = bl.relation AND bk.pid != bl.pid JOIN pg_stat_activity blocking ON bk.pid = blocking.pid WHERE NOT bl.granted;\"",
"comment": "blocking lock chains -- who's waiting on whom"
},
{
"cmd": "psql -h $PGHOST -U $PGUSER -d $PGDATABASE -c \"SELECT schemaname, relname, n_tup_ins, n_tup_upd, n_tup_del, n_live_tup, n_dead_tup, last_autovacuum FROM pg_stat_user_tables ORDER BY n_dead_tup DESC LIMIT 10;\"",
"comment": "tables with most dead tuples -- needs vacuum"
},
{
"cmd": "psql -h $PGHOST -U $PGUSER -d $PGDATABASE -c \"SELECT relname, pg_size_pretty(pg_total_relation_size(relid)) AS total, pg_size_pretty(pg_indexes_size(relid)) AS indexes FROM pg_catalog.pg_statio_user_tables ORDER BY pg_total_relation_size(relid) DESC LIMIT 10;\"",
"comment": "largest tables with index size -- where's the disk going"
},
{
"cmd": "psql -h $PGHOST -U $PGUSER -d $PGDATABASE -c \"SELECT indexrelname, idx_scan, pg_size_pretty(pg_relation_size(indexrelid)) AS size FROM pg_stat_user_indexes WHERE idx_scan = 0 ORDER BY pg_relation_size(indexrelid) DESC LIMIT 10;\"",
"comment": "unused indexes -- wasting disk and slowing writes"
}
]
}
}
31 changes: 31 additions & 0 deletions command-groups/databases/redis-ops.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"redis-ops": {
"description": "Redis operational checks -- memory, slow queries, key analysis",
"commands": [
{
"cmd": "redis-cli -h $REDIS_HOST -a $REDIS_PASSWORD INFO memory | grep -E 'used_memory_human|maxmemory_human|mem_fragmentation_ratio'",
"comment": "memory usage and fragmentation -- ratio > 1.5 means wasted RAM"
},
{
"cmd": "redis-cli -h $REDIS_HOST -a $REDIS_PASSWORD INFO clients | grep -E 'connected_clients|blocked_clients'",
"comment": "client connections -- blocked_clients > 0 means something is stuck"
},
{
"cmd": "redis-cli -h $REDIS_HOST -a $REDIS_PASSWORD SLOWLOG GET 10",
"comment": "recent slow commands -- KEYS * in production is the usual suspect"
},
{
"cmd": "redis-cli -h $REDIS_HOST -a $REDIS_PASSWORD INFO keyspace",
"comment": "key count and expiry stats per database"
},
{
"cmd": "redis-cli -h $REDIS_HOST -a $REDIS_PASSWORD --bigkeys --no-auth-warning 2>/dev/null",
"comment": "find the largest keys -- memory hogs that might need restructuring"
},
{
"cmd": "redis-cli -h $REDIS_HOST -a $REDIS_PASSWORD INFO replication | grep -E 'role|connected_slaves|master_link_status'",
"comment": "replication health -- master_link_status should be 'up'"
}
]
}
}
31 changes: 31 additions & 0 deletions command-groups/devops/docker-cleanup.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"docker-cleanup": {
"description": "Docker system maintenance -- recover disk space without nuking active workloads",
"commands": [
{
"cmd": "docker system df",
"comment": "disk usage breakdown by images, containers, volumes"
},
{
"cmd": "docker ps -a --filter status=exited --format 'table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Size}}'",
"comment": "stopped containers still eating disk"
},
{
"cmd": "docker images --format 'table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.CreatedSince}}' | sort -k3 -h -r | head -20",
"comment": "largest images -- candidates for cleanup"
},
{
"cmd": "docker images -f dangling=true -q | xargs -r docker rmi",
"comment": "remove dangling images (untagged layers from rebuilds)"
},
{
"cmd": "docker volume ls -f dangling=true -q | xargs -r docker volume rm",
"comment": "remove orphaned volumes -- check before running"
},
{
"cmd": "docker builder prune --filter until=72h -f",
"comment": "clear build cache older than 3 days"
}
]
}
}
31 changes: 31 additions & 0 deletions command-groups/devops/incident-response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"incident-response": {
"description": "First 5 minutes of a production incident -- gather signal fast",
"commands": [
{
"cmd": "kubectl get pods -n $NAMESPACE | grep -vE 'Running|Completed'",
"comment": "unhealthy pods right now"
},
{
"cmd": "kubectl logs -l app=$SERVICE -n $NAMESPACE --tail=50 --since=5m | grep -iE 'error|fatal|panic|exception'",
"comment": "recent errors across all pods of the service"
},
{
"cmd": "kubectl top pods -n $NAMESPACE --sort-by=cpu | head -5",
"comment": "CPU spikes -- runaway processes or hot loops"
},
{
"cmd": "kubectl rollout history deployment/$SERVICE -n $NAMESPACE | tail -5",
"comment": "recent deploys -- was something just shipped?"
},
{
"cmd": "kubectl get endpoints $SERVICE -n $NAMESPACE -o yaml | grep -c 'ip:'",
"comment": "how many pods are actually receiving traffic"
},
{
"cmd": "kubectl describe ingress -n $NAMESPACE | grep -A2 $SERVICE",
"comment": "ingress rules -- is traffic even reaching the right service?"
}
]
}
}
35 changes: 35 additions & 0 deletions command-groups/devops/k8s-debug.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"k8s-debug": {
"description": "Kubernetes troubleshooting -- from symptom to root cause",
"commands": [
{
"cmd": "kubectl get pods -n $NAMESPACE --field-selector status.phase!=Running",
"comment": "pods not in Running state -- the starting point"
},
{
"cmd": "kubectl describe pod $POD -n $NAMESPACE | tail -30",
"comment": "events section -- scheduling failures, image pulls, OOMs"
},
{
"cmd": "kubectl logs $POD -n $NAMESPACE --tail=100 --previous",
"comment": "logs from the previous crashed container"
},
{
"cmd": "kubectl top pods -n $NAMESPACE --sort-by=memory | head -10",
"comment": "memory hogs -- approaching limits means OOMKill incoming"
},
{
"cmd": "kubectl get events -n $NAMESPACE --sort-by='.lastTimestamp' | tail -20",
"comment": "recent cluster events -- often reveals the actual problem"
},
{
"cmd": "kubectl get hpa -n $NAMESPACE",
"comment": "autoscaler status -- is it maxed out or thrashing?"
},
{
"cmd": "kubectl exec -it $POD -n $NAMESPACE -- sh -c 'wget -qO- http://localhost:$PORT/health || curl -sf http://localhost:$PORT/health'",
"comment": "health check from inside the pod -- bypasses ingress/service"
}
]
}
}
31 changes: 31 additions & 0 deletions command-groups/git/cleanup.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"git-cleanup": {
"description": "Branch and repo cleanup -- keep the repo lean",
"commands": [
{
"cmd": "git branch --merged main | grep -v 'main\\|master\\|\\*' | xargs -r git branch -d",
"comment": "delete local branches already merged to main"
},
{
"cmd": "git remote prune origin --dry-run",
"comment": "preview stale remote-tracking branches (remove --dry-run to prune)"
},
{
"cmd": "git branch -vv | grep ': gone]' | awk '{print $1}'",
"comment": "local branches whose remote was deleted -- safe to remove"
},
{
"cmd": "git reflog expire --expire=30.days --all && git gc --prune=now --aggressive",
"comment": "aggressive gc -- reclaims space from rewritten history"
},
{
"cmd": "git stash list",
"comment": "forgotten stashes -- review before they become mysteries"
},
{
"cmd": "git log --oneline --all --graph --decorate | head -30",
"comment": "visual branch topology -- understand what needs merging"
}
]
}
}
35 changes: 35 additions & 0 deletions command-groups/git/forensics.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"git-forensics": {
"description": "Git archaeology -- find secrets, trace bugs, understand history",
"commands": [
{
"cmd": "git log --all --oneline -S '$SEARCH_STRING' -- '*.py' '*.js' '*.go' '*.yaml' '*.yml' '*.json' '*.env'",
"comment": "find every commit that added or removed a string (pickaxe search)"
},
{
"cmd": "git log --all --diff-filter=D --name-only --pretty=format:'%h %s' | head -40",
"comment": "deleted files -- credentials often get 'removed' but live in history"
},
{
"cmd": "git log --all --oneline --grep='$SEARCH_STRING' -i",
"comment": "search commit messages -- find when a fix or feature was introduced"
},
{
"cmd": "git log --format='%H' --all | xargs git grep -l '$SEARCH_STRING' 2>/dev/null | sort -u",
"comment": "brute-force search across all history -- finds buried secrets"
},
{
"cmd": "git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | awk '/^blob/ {print $3,$4}' | sort -rn | head -20",
"comment": "largest blobs ever committed -- binaries, data dumps, vendor dirs"
},
{
"cmd": "git shortlog -sn --all --no-merges | head -10",
"comment": "top contributors by commit count -- who knows this code best"
},
{
"cmd": "git log --oneline --all --after='$AFTER_DATE' --before='$BEFORE_DATE' --format='%h %ai %an: %s'",
"comment": "timeline of changes in a date range -- incident correlation"
}
]
}
}
35 changes: 35 additions & 0 deletions command-groups/networking/dns-debug.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"dns-debug": {
"description": "DNS troubleshooting -- when resolution is the problem",
"commands": [
{
"cmd": "dig $DOMAIN A +noall +answer && dig $DOMAIN AAAA +noall +answer",
"comment": "A and AAAA records -- what IPs does this resolve to?"
},
{
"cmd": "dig $DOMAIN NS +short",
"comment": "authoritative nameservers -- wrong NS = wrong answers"
},
{
"cmd": "dig @8.8.8.8 $DOMAIN A +short && dig @1.1.1.1 $DOMAIN A +short",
"comment": "compare Google vs Cloudflare DNS -- catches propagation issues"
},
{
"cmd": "dig $DOMAIN SOA +short",
"comment": "SOA record -- serial number reveals if zone was updated"
},
{
"cmd": "dig $DOMAIN ANY +noall +answer 2>/dev/null || echo 'ANY queries blocked (RFC 8482)'",
"comment": "all records at once -- some resolvers block this"
},
{
"cmd": "dig +trace +nodnssec $DOMAIN",
"comment": "walk the full delegation chain from root -- finds broken links"
},
{
"cmd": "dig $DOMAIN CAA +short",
"comment": "CAA records -- which CAs can issue certs for this domain"
}
]
}
}
31 changes: 31 additions & 0 deletions command-groups/networking/network-debug.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"network-debug": {
"description": "Network connectivity troubleshooting -- layer by layer",
"commands": [
{
"cmd": "curl -sS -o /dev/null -w 'dns: %{time_namelookup}s\\nconnect: %{time_connect}s\\ntls: %{time_appconnect}s\\nttfb: %{time_starttransfer}s\\ntotal: %{time_total}s\\ncode: %{http_code}\\n' https://$HOST",
"comment": "request timing breakdown -- pinpoints where latency lives"
},
{
"cmd": "dig +trace $HOST",
"comment": "full DNS resolution path -- find where delegation breaks"
},
{
"cmd": "traceroute -n -w 2 -q 1 $HOST",
"comment": "network path -- identify the hop where packets die"
},
{
"cmd": "nc -zv $HOST $PORT -w 5 2>&1",
"comment": "TCP port reachability -- is the port open or firewalled?"
},
{
"cmd": "curl -sS --resolve $HOST:443:$IP https://$HOST -o /dev/null -w '%{http_code}\\n'",
"comment": "bypass DNS and hit a specific IP -- test individual backends"
},
{
"cmd": "mtr -n -c 10 --report $HOST",
"comment": "combined ping/traceroute -- shows packet loss per hop"
}
]
}
}
35 changes: 35 additions & 0 deletions command-groups/performance/system-profile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"system-profile": {
"description": "System performance profiling -- find the bottleneck",
"commands": [
{
"cmd": "uptime && sysctl -n hw.ncpu 2>/dev/null || nproc",
"comment": "load average vs CPU count -- load > ncpu means saturation"
},
{
"cmd": "top -l 1 -n 10 -o cpu -stats pid,command,cpu,mem,time 2>/dev/null || top -bn1 | head -17",
"comment": "top processes by CPU right now"
},
{
"cmd": "vm_stat 2>/dev/null | awk '/Pages (free|active|inactive|speculative|wired)/' || free -h",
"comment": "memory pressure -- pageouts mean real trouble"
},
{
"cmd": "df -h / /tmp /var 2>/dev/null | grep -v '^Filesystem'",
"comment": "disk space on critical mounts -- 90%+ needs attention"
},
{
"cmd": "iostat -d 2 3 2>/dev/null || echo 'iostat not available'",
"comment": "disk I/O throughput -- high wait% means disk-bound"
},
{
"cmd": "lsof -iTCP -sTCP:LISTEN -n -P | sort -t: -k2 -n",
"comment": "all listening TCP ports -- what's actually running"
},
{
"cmd": "netstat -an | awk '/^tcp/ {print $6}' | sort | uniq -c | sort -rn",
"comment": "TCP connection states -- too many TIME_WAIT or CLOSE_WAIT is a leak"
}
]
}
}
Loading
Loading