From projectz
Git-based markdown project tracker for managing personal projects across multiple computers. Use when tracking projects, managing tasks, checking project status, adding tasks, syncing work across machines, or when user mentions "my projects", "project tracker", or "projectz".
How this skill is triggered — by the user, by Claude, or both
Slash command
/projectz:projectzThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Manage personal projects across multiple computers using Git and Markdown.
Manage personal projects across multiple computers using Git and Markdown.
| Command | Description |
|---|---|
/projectz | Show status of all projects |
/projectz init <repo-url> | Clone projectz repo and register this computer |
/projectz new <name> | Create a new project |
/projectz show <project> | Show project details |
/projectz task <project> <title> | Add a task to a project |
/projectz done <project> <task-id> | Mark a task as done |
/projectz note <project> <text> | Add a note to a project |
/projectz status <project> <status> | Update project status |
/projectz link <project> <local-path> | Link project to local checkout on this computer |
/projectz sync | Pull latest, commit changes, push |
/projectz discover [path] | Scan for local git repos, create/update projects |
/projectz scan | Re-scan all projects: update status, detect role (owner/fork/contributor/user), count commits |
| Status | Description | Auto-infer criteria |
|---|---|---|
draft | Just created, not started | No commits yet or only initial commit |
active | Currently being worked on | Commits within last 14 days |
backlog | Paused, will resume later | No commits in 14-90 days |
review | In review/testing phase | Manually set |
done | Completed | Manually set |
archived | No longer maintained | No commits in 90+ days, or manually set |
When running /projectz scan or /projectz discover, auto-infer status:
if last_commit < 14 days ago:
status = "active"
elif last_commit < 90 days ago:
status = "backlog"
else:
status = "archived" (suggest, don't auto-set)
Never auto-change done or review - those are manually set.
Always report inferred changes and let user confirm before updating.
Track your relationship with each project:
| Role | Description | Detection |
|---|---|---|
owner | You created it, it's yours | Remote URL has your username + first commits are yours |
fork | You forked someone else's repo | Your username in URL + has upstream remote or first commits aren't yours |
contributor | You contribute to others' repo | Not your URL + you have commits in the repo |
user | Just cloned to use it | Not your URL + no commits from you |
# Get configured git username/email
MY_EMAIL=$(git config user.email)
MY_USERNAME=$(cat ~/.projectz.yaml | grep github_username | cut -d: -f2 | tr -d ' ')
# Check if remote URL contains your username
ORIGIN=$(git remote get-url origin 2>/dev/null)
IS_MINE=$(echo "$ORIGIN" | grep -qi "$MY_USERNAME" && echo "yes" || echo "no")
# Check for upstream remote (indicates fork)
HAS_UPSTREAM=$(git remote | grep -q upstream && echo "yes" || echo "no")
# Get first commit author
FIRST_AUTHOR=$(git log --reverse --format="%ae" 2>/dev/null | head -1)
# Count commits by me vs total
MY_COMMITS=$(git shortlog -sne --all | grep -i "$MY_EMAIL" | awk '{sum+=$1} END {print sum+0}')
TOTAL_COMMITS=$(git rev-list --all --count 2>/dev/null || echo 0)
# Determine role
if [ "$IS_MINE" = "yes" ]; then
if [ "$HAS_UPSTREAM" = "yes" ] || [ "$FIRST_AUTHOR" != "$MY_EMAIL" ]; then
ROLE="fork"
else
ROLE="owner"
fi
else
if [ "$MY_COMMITS" -gt 0 ]; then
ROLE="contributor"
else
ROLE="user"
fi
fi
When showing projects, can filter by role:
/projectz - show all/projectz --mine - show only owner + fork/projectz --contributing - show contributor/projectz --using - show user~/.projectz.yaml)computer_id: a1b2c3d4e5f6 # MAC address (no colons)
computer_name: macbook-pro # Friendly name
projectz_repo: ~/projectz # Local clone path
github_username: csabakecskemeti # For role detection
git_email: [email protected] # For commit attribution detection
The computer ID must be derived from a network interface MAC address for uniqueness:
macOS:
ifconfig en0 | grep ether | awk '{print $2}' | tr -d ':'
Linux:
cat /sys/class/net/eth0/address | tr -d ':'
Windows (PowerShell):
(Get-NetAdapter | Where-Object Status -eq 'Up' | Select-Object -First 1).MacAddress -replace '-',''
Store the result (lowercase, no separators) as computer_id. The same MAC must appear in the computer's registration file for identity verification.
projectz/
├── README.md # Repo overview
├── AGENTS.md # Instructions for AI agents
├── INDEX.md # Auto-maintained project index
├── computers/ # Registered computers
│ └── <computer-id>.md # Computer info + MAC addresses + local paths
└── projects/
└── <project-slug>/
├── README.md # Project description (what it is)
├── MAP.md # Project hub: status, links to docs
└── tasks/
└── 001-<slug>.md
| Field | Required | Description |
|---|---|---|
slug | yes | URL-friendly project identifier |
status | yes | draft, active, backlog, review, done, archived |
role | no | owner, fork, contributor, user (auto-detected) |
has_git | no | true/false - is project under version control |
repo | no | Remote repository URL |
upstream | no | Original repo URL if this is a fork |
tags | no | List of tags for categorization |
created | yes | Creation date (YYYY-MM-DD) |
updated | yes | Last update date (YYYY-MM-DD) |
last_commit | no | Date of last git commit (auto-updated by scan) |
last_activity | no | Date of last file modification (auto-updated by scan) |
my_commits | no | Number of commits by you (auto-updated by scan) |
total_commits | no | Total commits in repo (auto-updated by scan) |
| Section | Purpose |
|---|---|
| Repository | Git status, remote URL, branch info |
| Files > Temporary | Safe to delete: builds, caches, logs |
| Files > Private | Don't share: .env, secrets, local configs |
| Files > Core | Important: source, docs, tests |
| Quick Links | Links to tasks/, notes/, howto/ |
| Recent Notes | Latest notes with links |
| Related Documents | Links to docs, guides, decisions |
# My Project
Brief description of what this project is.
## Overview
More details about the project goals and scope.
See [MAP.md](./MAP.md) for status, tasks, and related documents.
---
slug: my-project
status: active
role: owner
repo: https://github.com/user/my-project
has_git: true
tags: [python, web]
created: 2024-01-15
updated: 2024-01-20
last_commit: 2024-01-20
my_commits: 47
total_commits: 52
---
# My Project - Map
## Status
Current: **active** | Role: **owner**
## Quick Links
- [Tasks](./tasks/)
- [Notes](./notes/)
- [How-To Guides](./howto/)
## Repository
- **Git**: yes, initialized
- **Remote**: https://github.com/user/my-project
- **Default branch**: main
## Files
### Temporary (safe to delete)
- `build/`, `dist/` - build outputs
- `*.log` - log files
- `.cache/`, `__pycache__/` - caches
- `node_modules/` - dependencies (reinstallable)
### Private (don't share publicly)
- `.env`, `.env.local` - environment secrets
- `config.local.yaml` - local overrides
- `secrets/` - API keys, credentials
- `*.pem`, `*.key` - certificates/keys
### Core (important, back up)
- `src/` - source code
- `docs/` - documentation
- `tests/` - test files
## Recent Notes
- [2024-01-20 - Auth Research](./notes/2024-01-20-auth-research.md)
- [2024-01-15 - Initial Setup](./notes/2024-01-15-initial-setup.md)
## Related Documents
- [Architecture Decision](./docs/architecture.md)
- [Deployment Guide](./howto/deploy.md)
---
id: "001"
title: Set up project structure
status: active
priority: high
created: 2024-01-15
---
# Set up project structure
Create the initial directory structure and configuration files.
## Acceptance Criteria
- [ ] Directory structure created
- [ ] Config files in place
---
id: a1b2c3d4e5f6
name: macbook-pro
mac_addresses:
- a1b2c3d4e5f6
- f6e5d4c3b2a1
registered: 2024-01-15
---
# macbook-pro
## Local Project Paths
| Project | Local Path | Last Commit |
|---------|------------|-------------|
| my-project | ~/code/my-project | abc1234 |
/projectz init <repo-url>~/projectz (or ask user for location)csabakecskemeti from github.com/csabakecskemeti/projectz)git config user.email~/.projectz.yaml with:
computer_id: MAC addresscomputer_name: hostnameprojectz_repo: local pathgithub_username: extracted from repo URLgit_email: from git configcomputers/<mac-id>.md with all local MAC addresses/projectz new <name>projects/<slug>/README.md with description templateprojects/<slug>/MAP.md with status and linksprojects/<slug>/tasks/ directoryINDEX.md/projectz task <project> <title>projects/<project>/tasks/<num>-<slug>.md/projectz done <project> <task-id>001-*.md)status: donecompleted: <date> to frontmatter/projectz note <project> <text>projects/<project>/notes/ if not exists<date>-<slug>.md with the note content/projectz syncgit add -Agit commit -m "projectz: <summary of changes>" (skip if nothing to commit)git pull --rebasegit push/projectz link <project> <local-path>git -C <local-path> rev-parse --short HEAD to record commit/projectz discover [path]~/, ~/code/, ~/projects/, ~/Documents/workspace/).git/configgit log -1 --format=%ci/projectz scanThis command exists and must be followed exactly.
For each project in ~/projectz/projects/*/MAP.md:
Read config: Load ~/.projectz.yaml to get github_username and git_email
Find local path: Check ~/projectz/computers/<computer-id>.md for local path of this project
If local path exists, cd there and collect:
# Last commit date
LAST_COMMIT=$(git log -1 --format=%Y-%m-%d 2>/dev/null || echo "")
# Days since last commit
DAYS_AGO=$(git log -1 --format=%ct 2>/dev/null | xargs -I {} bash -c 'echo $(( ($(date +%s) - {}) / 86400 ))')
# Commit counts
MY_EMAIL=$(git config user.email)
MY_COMMITS=$(git shortlog -sne --all 2>/dev/null | grep -i "$MY_EMAIL" | awk '{sum+=$1} END {print sum+0}')
TOTAL_COMMITS=$(git rev-list --all --count 2>/dev/null || echo 0)
# Role detection
MY_USERNAME=$(cat ~/.projectz.yaml | grep github_username | cut -d: -f2 | tr -d ' ')
ORIGIN=$(git remote get-url origin 2>/dev/null)
IS_MINE=$(echo "$ORIGIN" | grep -qi "$MY_USERNAME" && echo "yes" || echo "no")
HAS_UPSTREAM=$(git remote | grep -q upstream && echo "yes" || echo "no")
FIRST_AUTHOR=$(git log --reverse --format=%ae 2>/dev/null | head -1)
if [ "$IS_MINE" = "yes" ]; then
if [ "$HAS_UPSTREAM" = "yes" ] || [ "$FIRST_AUTHOR" != "$MY_EMAIL" ]; then
ROLE="fork"
else
ROLE="owner"
fi
else
if [ "$MY_COMMITS" -gt 0 ]; then
ROLE="contributor"
else
ROLE="user"
fi
fi
Infer status from days_ago:
< 14 days → active14-90 days → backlog> 90 days → suggest archived (don't auto-set)done or review automaticallyUpdate MAP.md frontmatter with:
last_commit: YYYY-MM-DDrole: owner|fork|contributor|usermy_commits: Ntotal_commits: Nstatus: active|backlog (if changed, ask user first)Report summary:
project-x: role=owner, status=active, 47/52 commits
project-y: role=fork, status=backlog (45 days), 12/89 commits
project-z: role=contributor, status=active, 5/200 commits
Commit and push changes to projectz repo
Get last commit date (cross-platform):
git log -1 --format=%ci 2>/dev/null || echo "no commits"
Get days since last commit:
git log -1 --format=%ct | xargs -I {} bash -c 'echo $(( ($(date +%s) - {}) / 86400 )) days'
Check if repo has uncommitted changes:
git status --porcelain | head -1
git pull/pushCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub csabakecskemeti/skill-vault --plugin projectz