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.mdand relevant_Index.mdfiles 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:
# All git repos sorted by last commit (most recent first)
# Shows: project name, last commit timestamp, dirty file count
(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-
# Obsidian project status
cat "$VAULT/1. Projects/_Index.md"
2. Single Project Deep Dive
For a specific project, gather comprehensive status:
PROJECT="project-name"
# Git status
git -C "$DEV/$PROJECT" status
git -C "$DEV/$PROJECT" log --oneline -10
# Recent changes
git -C "$DEV/$PROJECT" diff --stat HEAD~5 2>/dev/null
# Tech stack detection
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
# README / docs
cat "$DEV/$PROJECT/README.md" 2>/dev/null | head -50
# Open issues (if using GitHub)
# Check for TODO/FIXME/HACK
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 related vault notes
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
# ... scaffold based on stack
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.mdif it's not auto-generated by Dataview
4. Archive a Project
Move a project to archived/inactive state:
Dev side:
# Ensure clean state
git -C "$DEV/$PROJECT" status
# Confirm no uncommitted work, then optionally:
mv "$DEV/$PROJECT" "$DEV/! Archive/"
Vault side (confirm first):
- Move the project folder from
1. Projects/to4. Archive/ - Update tags: change
#project/activeto#project/completedor#project/archived - Add completion date to frontmatter
5. Cross-Project Search
Search across all code repos and vault notes:
# Search code
grep -rl "search term" $DEV/*/src/ --include="*.ts" --include="*.tsx" --include="*.py" 2>/dev/null | head -20
# Search vault
grep -rl "search term" "$VAULT" --include="*.md" 2>/dev/null | head -20
# Search git history across projects
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:
# Projects in Dev that might need vault notes
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
# Vault projects that might not have Dev repos
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:
# Open tasks across all projects
find "$VAULT/Tasks/" -name "*.md" -exec grep -l "#status/active\|#status/in-progress" {} \; 2>/dev/null
# Tasks for a specific project
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/projectnot full paths) for readability - When creating vault notes, always use existing Templater templates