Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
Sicherheitslücken (CVE)DSA-6527-1 rsync - security update(28.09.2026 um 02:00 Uhr)
•••••••
Sichere ProgrammierungChecking missing dates in a legal metadata CSV with Python(29.09.2026 um 01:54 Uhr)
•••
Sicherheitslücken (CVE)DSA-6527-1 rsync - security update(28.09.2026 um 02:00 Uhr)
•••••••
Sichere ProgrammierungChecking missing dates in a legal metadata CSV with Python(29.09.2026 um 01:54 Uhr)
•••
Intelligence View
⚡ tsecurity.de Intelligence

Auto-Generating a Mermaid Map of My Claude Code Setup Every Morning

This is a follow-up to my previous post on getting Claude Code to improve itself unattended. This time the topic is a different problem: a mechanism to stay aware of your environment as it balloons. Skills piled up under ~/.claude/,…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

This is a follow-up to my previous post on getting Claude Code to improve itself unattended. This time the topic is a different problem: a mechanism to stay aware of your environment as it balloons.



Skills piled up under ~/.claude/, launchd jobs multiplied, and once my project count crossed into the double digits, I could no longer answer off the top of my head "how many layers is the whole thing, and what's running right now?" Rather than typing ls every morning, I wanted a state where opening Obsidian gives me the bird's-eye view. So I wrote ~/.claude/scripts/env-map.sh.






The problem: as the environment grows, you lose the big picture



Here's the current snapshot.




  • Plugin bundle skills: 1,004

  • Self-generated skills (auto/): 77

  • launchd jobs (com.shun.*.plist): 24

  • Projects I'm tracking: 11



The last-modified times and git state of skills, jobs, and projects are all over the place, and the cost of going to check each one adds up every time. I wanted one place that could answer "what did today's autopilot do?" and "what branch is that project on?" on a single page.






Design: three-layer Mermaid + output to Obsidian



The diagram covers three layers.
























Layer What's collected
💻 PC environment macOS version, chip, RAM, free disk, key CLIs
🤖 Claude environment skill count, agent count, plugin count, hook event count, MCP connection count, launchd job count
📦 Project environment branch, last commit date, and uncommitted change count for known repos


The output destination is the Obsidian Vault (~/Documents/claude-obsidian/wiki/meta/environment-map.md). vault-auto-ingest (4:55) picks it up and auto-commits, so version control comes along for free.



The script's design intent is written in the comments.




# 何が起きても生成を完走させる(個別の収集失敗は "?" で degrade)。set -e は使わない。
set -uo pipefail






The key is not using set -e. Even if something partially fails, like an MCP connection check, it fills in ? and keeps producing output all the way to the end.






Working around launchd's minimal PATH



When launched from launchd, PATH is roughly only /usr/bin:/bin:/usr/sbin:/sbin. Neither node, nor claude, nor jq is found. So at the top of the script I explicitly assemble PATH.




NVM_BIN="$(ls -d "$HOME"/.nvm/versions/node/*/bin 2>/dev/null | sort -V | tail -1)"
export PATH="$HOME/.local/bin:/opt/homebrew/bin:/opt/homebrew/sbin:${NVM_BIN:+$NVM_BIN:}/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"






Because nvm's path changes when you bump the node version, sort -V | tail -1 resolves the latest version's bin dynamically. Hardcoding a fixed path breaks on the next version bump.



:::message

Getting stuck on launchd's minimal PATH affects "any CLI the user installed." Stacking fallbacks in the order ~/.local/bin (uv, claude, etc.) → Homebrew → nvm hits the mark across any environment configuration.

:::





What to put in the diagram so the overview actually helps





Collecting the Claude environment





AUTO_SKILLS="$(ls "$HOME/.claude/skills/auto/" 2>/dev/null | grep -vc README)"
AGENTS="$(find "$HOME/.claude/plugins" "$HOME/.claude/agents" -path '*/agents/*.md' \
-o -path "$HOME/.claude/agents/*.md" 2>/dev/null | wc -l | tr -d ' ')"
PLUGINS="$(jq -r '.enabledPlugins // {} | length' "$SETTINGS" 2>/dev/null || echo '?')"
HOOK_EVENTS="$(jq -r '.hooks // {} | keys | length' "$SETTINGS" 2>/dev/null || echo '?')"
LAUNCHD="$(ls "$HOME/Library/LaunchAgents/"com.shun.*.plist 2>/dev/null | wc -l | tr -d ' ')"





MCP is the one thing that needs care. claude mcp list attempts a live connection, so it's slow to start and can fail. I contain it with a timeout.




MCP_OK="?"
if have claude; then
_mcp="$(timeout 12 claude mcp list 2>/dev/null)"
[ -n "$_mcp" ] && MCP_OK="$(printf '%s' "$_mcp" | grep -c 'Connected')"
fi






With timeout 12, it gives up after 12 seconds and leaves ? in place. It doesn't halt generation.






Project state



For each repo, it fetches the branch, last commit date, and uncommitted change count, and reflects them in the node color.




proj_meta() {
local path="$1"
PROJ_EXISTS=0; PROJ_BRANCH="-"; PROJ_LAST="-"; PROJ_DIRTY=0
[ -d "$path" ] || return
PROJ_EXISTS=1
if git -C "$path" rev-parse --git-dir >/dev/null 2>&1; then
PROJ_BRANCH="$(git -C "$path" rev-parse --abbrev-ref HEAD 2>/dev/null || echo '-')"
PROJ_LAST="$(git -C "$path" log -1 --format=%cd --date=format:%Y-%m-%d 2>/dev/null || echo '-')"
PROJ_DIRTY="$(git -C "$path" status --porcelain 2>/dev/null | wc -l | tr -d ' ')"
fi
}






Projects with uncommitted changes show up in orange, and projects that don't exist on disk show up in red.




echo '  classDef dirty fill:#3a2a00,stroke:#e8a33d,color:#fff;'
echo ' classDef gone fill:#3a1a1a,stroke:#e06666,color:#fff;'






Just by opening Obsidian in the morning, the color tells me "which project has commits I forgot to make."






Sanitizing Mermaid labels



If a host name or chip name contains () or [], Mermaid's parsing breaks. I run every label through a sanitize function.




san() { printf '%s' "$1" | tr '"[]()#|<>' '        ' | tr '\n' ' ' | sed 's/  */ /g; s/ *$//'; }






Even a string like Apple M4 Pro (14-core) is output safely.






What the generated diagram looks like






graph LR
PC["💻 PC 環境<br/>MacBook · macOS 15.x"]
CC["🤖 Claude 環境<br/>plugins 14 · launchd 24"]
PJ["📦 プロジェクト環境<br/>11 repos"]
PC --> CC
CC -->|builds / runs| PJ
PC -.->|ローカル開発| PJ






The breakdown of the Claude environment looks like this (measured values).




graph TD
CC["🤖 Claude Code"]
SK["🧩 Skills"]
SK --> SKa["auto: 77"]
SK --> SKp["plugin: 1004"]
CC --> SK
CC --> AG["🎭 Agents"]
CC --> PL["🔌 Plugins enabled"]
CC --> HK["🪝 Hooks"]
CC --> MCP["🔗 MCP connected"]
CC --> AUTO["⚡ launchd 24 jobs"]









launchd configuration






<key>StartCalendarInterval</key>
<array>
<dict><key>Hour</key><integer>4</integer><key>Minute</key><integer>50</integer></dict>
<dict><key>Hour</key><integer>8</integer><key>Minute</key><integer>10</integer></dict>
</array>
<key>RunAtLoad</key><false/>






It fires at 4:50 in order to place the output before the 4:55 vault-auto-ingest. Since ingest commits it straight to Obsidian, no git operations are needed. The 8:10 run is a catch-up for cases where 4:50 was skipped due to overnight sleep. It's idempotent, so firing multiple times is harmless. RunAtLoad: false suppresses the immediate fire on plist load.



Logs are consolidated into a single file.




<key>StandardOutPath</key>
<string>~/.claude/logs/env-map.launchd.log</string>
<key>StandardErrorPath</key>
<string>~/.claude/logs/env-map.launchd.log</string>






If the last line shows generated (N lines), you're good.




[2026-06-20 04:50:03] environment-map.md generated (218 lines)









Pitfalls I hit





  • Adding set -e exits at the MCP timeout → set -uo pipefail only. Continue past MCP or git failures with ? or -


  • Writing a fixed NVM path broke it on a Node update → dynamically resolve the latest version's bin with sort -V | tail -1


  • A () in a Mermaid label causes a parse error in the diagram → run the san() function on every label. I got bitten by a chip name


  • Falling behind vault-ingest makes the artifact the previous day's → dual setup: fire early at 4:50, catch up at 8:10


  • Not noticing a project path change → visualize with a (not found) red node. Update the list when PROJECTS changes


  • It fails if the output directory doesn't exist → put mkdir -p "$(dirname "$OUT")" right before the mv


  • If the comma-joined node IDs are left with spaces, Mermaid breaks → clean them up with sed 's/ /,/g' before passing them to class






Wrap-up




  • Once skills, launchd, and projects cross into the double digits, prepare a single place to survey them with a Mermaid diagram


  • Assemble PATH explicitly at the top of the script for launchd's minimal PATH at startup. Resolve nvm dynamically, assuming version bumps

  • Wrap slow operations like MCP connection checks in timeout, and degrade failures to ? to prioritize completing the run

  • Placing the output before vault-ingest gets you version control and commits automatically


  • Visualizing projects' uncommitted changes by node color means just opening Obsidian in the morning tells you the action to take



Combining this with liveness monitoring (automation-health-check) gives you a morning snapshot on a single page of "what's running, what's broken, and what's left undone."






Written by **Lily* — I ship iOS apps and automate my content stack with Claude Code.

Follow along: Portfolio · X · GitHub*

2. Cyber Threat Intelligence & Forensik

CTI Threat Relationship Graph3 Knoten / 2 Relationen
CVE / Incident Software MITRE ATT&CK CWE Weakness IoC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Auto-Generating a Mermaid Map of My Claude Code Setup Every Morning

Thematisch verwandte Begriffe: AutoGenerating, Mermaid, Claude, Code · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-101916 | @grpc/grpc-js implements the core functionality of gRPC purely in JavaS…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag