Generates daily/weekly standup summaries across all projects from the Obsidian vault. Includes a Closed This Period section listing items checked off during the window, grouped by project. Use when: (1) /standup for today's summary, (2) /standup this week for weekly summary, (3) /standup <date range> for custom range.
Searches the Obsidian vault for session notes and insights within a date range, upgrades any unsummarized notes with AI summaries, groups findings by project, and generates a structured standup note.
Tools needed: Bash, Grep, Read, Write
Follow these steps exactly. Do not skip steps or reorder them.
Run:
cd "$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
python3 -c '
import sys, os
import glob; sys.path.insert(0, max(glob.glob(os.path.expanduser("~/.claude/plugins/cache/*/obsidian-brain/*/hooks")), default="hooks"))
from obsidian_utils import load_config
c = load_config()
if not c.get("vault_path"):
print("ERROR: vault_path not configured", file=sys.stderr)
sys.exit(1)
print("VAULT=" + c["vault_path"])
print("SESS=" + c.get("sessions_folder", "claude-sessions"))
print("INS=" + c.get("insights_folder", "claude-insights"))
'
Parse each output line as KEY=VALUE, splitting on the first =.
If the command exits non-zero or prints ERROR, tell the user:
Config not found. Run
/obsidian-setupfirst to configure your Obsidian vault.
Stop here if config is missing.
Run:
test -d "$VAULT_PATH/$SESSIONS_FOLDER" && test -d "$VAULT_PATH/$INSIGHTS_FOLDER" && echo "OK" || echo "FAIL"
If FAIL, tell the user:
The vault folders do not exist or are not accessible. Run
/obsidian-setupto fix this.
Stop here if FAIL.
Before date parsing, check if the argument string contains the word deep (case-insensitive). If found, set IS_DEEP = true and remove deep from the argument string before passing to date parsing. Otherwise IS_DEEP = false.
Inspect the argument passed after /standup. Calculate START_DATE and END_DATE as YYYY-MM-DD strings using bash date commands.
No argument (bare /standup): today only.
START_DATE=$(date +%Y-%m-%d)
END_DATE=$START_DATE
yesterday:
# macOS
START_DATE=$(date -v-1d +%Y-%m-%d)
END_DATE=$START_DATE
# Linux fallback
START_DATE=$(date -d "yesterday" +%Y-%m-%d)
END_DATE=$START_DATE
this week: Monday of the current week through today.
# macOS
DOW=$(date +%u) # 1=Mon … 7=Sun
DAYS_BACK=$((DOW - 1))
START_DATE=$(date -v-${DAYS_BACK}d +%Y-%m-%d)
END_DATE=$(date +%Y-%m-%d)
# Linux fallback
START_DATE=$(date -d "last Monday" +%Y-%m-%d 2>/dev/null || date -d "$(date +%Y-%m-%d) -$(date +%u)-1 days" +%Y-%m-%d)
END_DATE=$(date +%Y-%m-%d)
last week: Monday through Sunday of the previous week.
# macOS
DOW=$(date +%u)
START_DATE=$(date -v-${DOW}d -v-6d +%Y-%m-%d)
END_DATE=$(date -v-${DOW}d +%Y-%m-%d)
# Linux fallback
START_DATE=$(date -d "last week Monday" +%Y-%m-%d)
END_DATE=$(date -d "last week Sunday" +%Y-%m-%d)
YYYY-MM-DD to YYYY-MM-DD: use the two dates directly as START_DATE and END_DATE.
Store both dates. Also compute IS_RANGE = true if START_DATE != END_DATE, false otherwise. This controls the filename slug in Step 11.
Validate the parsed dates: Check that START_DATE and END_DATE are non-empty and match YYYY-MM-DD format. If either is empty or malformed, tell the user:
Could not parse the date range from your input. Supported formats:
/standup(today)/standup yesterday/standup this week/standup last week/standup 2026-03-25 to 2026-03-31
Stop here if validation fails.
Also verify that START_DATE <= END_DATE. If not, tell the user the start date must be before or equal to the end date.
Run two Grep searches in parallel to find notes whose date: frontmatter field falls within the range.
Search A — Sessions: