| name | project-manager |
| description | Manage Espen's projects across the Dev folder and Obsidian vault. Use for project status checks, creating new projects, syncing between code repos and vault notes, archiving, and cross-project search. |
Project Manager
Manage projects spanning two systems:
- Code —
/Users/espen/Dev/ (git repos, code, configs)
- Knowledge — Obsidian vault at
/Users/espen/Library/CloudStorage/OneDrive-Espennilsen.net/2-Areas/Digital_Life/Obsidian/e9n (notes, tasks, dashboards)
⚠️ Safety
- Always confirm before modifying Obsidian vault files. The vault has Dataview queries, templates, and dashboards that depend on consistent structure.
- Read the vault's
AGENTS.md and relevant _Index.md files before creating or editing vault notes.
- Never force-push, delete branches, or reset git history without explicit confirmation.
Paths
DEV="/Users/espen/Dev"
VAULT="/Users/espen/Library/CloudStorage/OneDrive-Espennilsen.net/2-Areas/Digital_Life/Obsidian/e9n"
Known Projects
Active projects and their locations. Resolve project references against this list first.
| Project | Dev Path | Vault Path | Stack |
|---|
| pi (Hannah) | $DEV/pi | 1. Projects/AI Projects/Pi (Hannah) | Node/TypeScript, Pi agent |
| e9n.dev | $DEV/e9n.dev | 1. Projects/e9n Agency | Eleventy + Tailwind + Pagefind |
| Starheim | $DEV/Starheim | 1. Projects/Starheim | TanStack Start + React + Clerk + oRPC |
| x10s | $DEV/x10s | — | Node/TypeScript |
| x10s-pi | $DEV/x10s-pi | — | Monorepo, Docker + K8s |
| Hovdan Seil AS | $DEV/Hovdan Seil AS | — | Eleventy + Tailwind |
| hjernedal.no | $DEV/hjernedal.no | — | Next.js + Prisma + AI chatbot |
| SalesGPT | $DEV/SalesGPT | — | Autonomous sales agent |
| obsidian-agent | $DEV/obsidian-agent | — | Claude SDK + Obsidian |
| MCP-Bridge | $DEV/MCP-Bridge | — | OpenAI API → MCP bridge |
| stoic-tracker | $DEV/stoic-tracker | — | Monorepo, Docker |
| Sail La Vie | $DEV/Sail La Vie | — | TanStack React + Firebase |
| LocalBooks | $DEV/LocalBooks | — | React Native |
| comfyui-cheatsheet | $DEV/comfyui-cheatsheet | — | Vue.js |
| ClaudeCode | $DEV/ClaudeCode | — | Developer toolkit |
| CrewMap | — | 1. Projects/CrewMap | — |
| VibeBox | — | 1. Projects/VibeBox | — |
| Languages | — | 1. Projects/Languages | Thai + Spanish |
| Health | — | 1. Projects/Health | Bodybuilding, C25K, Weight Loss |
| Sales Coaching | — | 1. Projects/Sales Coaching | MEDDPICC |
| University Courses | — | 1. Projects/University Courses | Academic |
Operations
1. Project Status Overview
Get a quick status across all active projects:
(for d in $DEV/*/; do
[ -d "$d/.git" ] || continue
name=$(basename "$d")
ts=$(git -C "$d" log -1 --format='%ct' 2>/dev/null)
date=$(git -C "$d" log -1 --format='%ai' 2>/dev/null | cut -d' ' -f1)
ago=$(git -C "$d" log -1 --format='%ar' 2>/dev/null)
dirty=$(git -C "$d" status --porcelain 2>/dev/null | wc -l | tr -d ' ')
week=$(git -C "$d" log --oneline --since="7 days ago" --no-merges 2>/dev/null | wc -l | tr -d ' ')
flag=""
[ "$dirty" -gt 0 ] && flag=" ⚠️ ${dirty} dirty"
[ "$week" -gt 0 ] && flag="${flag} 📝 ${week} this week"
echo "${ts:-0}|${name}|${date:-never}|${ago:-never}${flag}"
done) | sort -t'|' -k1 -rn | cut -d'|' -f2-
cat "$VAULT/1. Projects/_Index.md"
2. Single Project Deep Dive
For a specific project, gather comprehensive status:
PROJECT="project-name"
git -C "$DEV/$PROJECT" status
git -C "$DEV/$PROJECT" log --oneline -10
git -C "$DEV/$PROJECT" diff --stat HEAD~5 2>/dev/null
ls "$DEV/$PROJECT/package.json" "$DEV/$PROJECT/Cargo.toml" "$DEV/$PROJECT/pyproject.toml" "$DEV/$PROJECT/go.mod" 2>/dev/null
cat "$DEV/$PROJECT/package.json" 2>/dev/null | head -20
cat "$DEV/$PROJECT/README.md" 2>/dev/null | head -50
grep -rn "TODO\|FIXME\|HACK\|XXX" "$DEV/$PROJECT/src/" --include="*.ts" --include="*.tsx" --include="*.js" 2>/dev/null | head -20
For the vault side:
find "$VAULT" -name "*.md" -path "*/Projects/*" | xargs grep -l "$PROJECT" 2>/dev/null
3. Create New Project
When starting a new project, set up both systems:
Dev side:
mkdir -p "$DEV/new-project"
cd "$DEV/new-project"
git init
Vault side (confirm with Espen first):
- Read the Project Template:
cat "$VAULT/Templates/Project Template.md"
- Create the project note in
1. Projects/ following the template
- Add correct frontmatter and tags per
🏷️ Tag Taxonomy.md
- Update
1. Projects/_Index.md if it's not auto-generated by Dataview
4. Archive a Project
Move a project to archived/inactive state:
Dev side:
git -C "$DEV/$PROJECT" status
mv "$DEV/$PROJECT" "$DEV/! Archive/"
Vault side (confirm first):
- Move the project folder from
1. Projects/ to 4. Archive/
- Update tags: change
#project/active to #project/completed or #project/archived
- Add completion date to frontmatter
5. Cross-Project Search
Search across all code repos and vault notes:
grep -rl "search term" $DEV/*/src/ --include="*.ts" --include="*.tsx" --include="*.py" 2>/dev/null | head -20
grep -rl "search term" "$VAULT" --include="*.md" 2>/dev/null | head -20
for d in $DEV/*/; do
[ -d "$d/.git" ] || continue
result=$(git -C "$d" log --all --oneline --grep="search term" 2>/dev/null | head -3)
[ -n "$result" ] && echo "=== $(basename "$d") ===" && echo "$result"
done
6. Sync Check
Verify Dev projects and Obsidian are in sync:
for d in $DEV/*/; do
[ -d "$d/.git" ] || continue
name=$(basename "$d")
recent=$(git -C "$d" log -1 --format='%ar' 2>/dev/null)
vault_match=$(find "$VAULT/1. Projects" "$VAULT/2. Areas" -name "*.md" 2>/dev/null | xargs grep -l "$name" 2>/dev/null | head -1)
if [ -z "$vault_match" ]; then
echo "⚠️ $name (last: $recent) — no vault note found"
fi
done
for d in "$VAULT/1. Projects/"*/; do
name=$(basename "$d")
dev_match=$(ls -d "$DEV/$name" 2>/dev/null || ls -d "$DEV/"*"$name"* 2>/dev/null | head -1)
if [ -z "$dev_match" ]; then
echo "📝 $name — vault-only (no Dev repo)"
fi
done
7. Task Management
Work with the Obsidian TaskNotes system:
find "$VAULT/Tasks/" -name "*.md" -exec grep -l "#status/active\|#status/in-progress" {} \; 2>/dev/null
grep -rl "$PROJECT" "$VAULT/Tasks/" --include="*.md" 2>/dev/null
8. Hannah Job Stats by Project
Query Hannah's DB for per-channel/project usage:
sqlite3 /Users/espen/Dev/pi/hannah.db "
SELECT channel, COUNT(*) as jobs,
printf('\$%.4f', SUM(cost_total)) as cost,
SUM(total_tokens) as tokens,
printf('%.1fs', AVG(duration_ms)/1000.0) as avg_dur
FROM jobs
WHERE created_at >= datetime('now', '-7 days')
GROUP BY channel
ORDER BY jobs DESC;
"
Output Format
When reporting project status, use this structure:
## Project Status: [name]
**Code:** [Dev path] | **Vault:** [vault path or "—"]
**Stack:** [tech stack]
**Last commit:** [relative time] | **Dirty:** [yes/no]
### Recent Activity
- [commit summaries or "No recent commits"]
### Open Items
- [TODOs, tasks, blockers]
### Vault Notes
- [Related notes or "No vault notes found"]
Conventions
- When Espen says a project name, resolve it against the Known Projects table first
- For ambiguous names, ask which project is meant
- Default time window for "recent" is 7 days
- Always show both Dev and Vault status when both exist
- Use relative paths in output (
~/Dev/project not full paths) for readability
- When creating vault notes, always use existing Templater templates