microsoft/shadow-frog-init
>- Initialize a shadow knowledge base for any codebase. Creates a .shadow/ directory that mirrors the source tree with markdown files for AI-discovered insights. Run this once per repo before using other shadow-frog skills. Refuses to overwrite an existing .shadow/ unless --reset is passed.
npx skills add https://github.com/microsoft/ShadowFrog --skill shadow-frog-init
Creates .shadow/ directory with symbol-organized shadow files for every
source file. Run once per repo. If .shadow/ exists, ask user to reset or skip.
The companion script shadow-init.py lives in the same directory as
this SKILL.md file. To find and run it:
# Project install (Copilot CLI):
python3 .github/skills/shadow-frog-init/shadow-init.py [options]
# Or for Claude Code:
python3 .claude/skills/shadow-frog-init/shadow-init.py [options]
IMPORTANT: Run from the repo/worktree root directory. The script
auto-detects the root via git rev-parse --show-toplevel, which returns
the correct root for regular repos AND worktrees. If auto-detection fails
(common when python is routed through Docker or the .git file points to
an inaccessible path), pass --root explicitly:
# If auto-detect fails, pass the root explicitly:
python3 .github/skills/shadow-frog-init/shadow-init.py --root "$(pwd)"
# In Docker wrapper scenarios (eval harness), git may not work inside
# the container. Use --root to bypass git detection:
python3 .github/skills/shadow-frog-init/shadow-init.py --root /testbed
| Flag | Effect |
|------|--------|
| --root DIR | Repository root (default: auto-detect via git) |
| --reset | Delete existing .shadow/ and recreate |
| --dry-run | Show what would be created without writing |
git ls-files.shadow/.shadowignore (gitignore syntax).md files with symbol headings_index.md, _prefs.md, _meta/state.json, .shadowignoreTell the user:
.shadow/.shadowignore to exclude files that shouldn't be shadowed"/shadow-frog-dream for autonomous exploration, or /shadow-frog-update after your next changes"Then decide the version-control mode (do not skip this — it is not handled
by the script). Ask the user: "Should .shadow/ be committed (shared
with your team via git) or gitignored (local to your machine only)?"
Make the trade-off explicit before they choose — see
Step 9: Handle .gitignore for the full committed vs
gitignored comparison. Key caveat: a gitignored .shadow/ disables
shadow-frog-dream (dreams move .shadow/ through git). If gitignored, add
.shadow/ to .gitignore.
If the Python script fails (wrong Python version, missing file, etc.),
follow these steps manually:
git rev-parse --is-inside-work-tree # must be a git repo
test -d .shadow && echo "exists" # if exists, ask user: reset or skip
git ls-files --cached --others --exclude-standard
Include patterns (auto-detect from repo contents):
*.py, *.js, *.ts, *.tsx, *.jsx, *.java, *.go, *.rs, *.rb,
*.cpp, *.c, *.h, *.cs, *.swift, *.kt, *.scala, *.php,
*.sh, *.bash, *.zsh, *.yaml, *.yml, *.toml, *.json,
Makefile, Dockerfile, docker-compose*.yml
Default excludes (always applied): node_modules/, vendor/, venv/,
.venv/, __pycache__/, *.min.js, *.min.css, *.map, *.lock,
dist/, build/, target/, out/, .shadow/, binary files
After discovering files, filter them through .shadow/.shadowignore
(if it exists). The ignore file uses .gitignore syntax.
mkdir -p .shadow/_cross .shadow/_meta .shadow/_dreams
# For each source file, create parent dirs: mkdir -p .shadow/<dir>/
.shadow/.shadowignoreUses .gitignore syntax. Seed with sensible defaults:
# Directories
node_modules/
vendor/
venv/
.venv/
__pycache__/
dist/
build/
target/
out/
# Generated / minified
*.min.js
*.min.css
*.map
*.lock
# Binary
*.png
*.jpg
*.gif
*.ico
*.woff
*.woff2
*.ttf
*.eot
*.pdf
*.zip
*.tar.gz
# The shadow itself
.shadow/
# ShadowFrog's own install artifacts (project install copies these here)
.github/skills/shadow-frog*/
.github/hooks/scripts/shadow-frog-*
.claude/skills/shadow-frog*/
.claude/hooks/scripts/shadow-frog-*
Tell the user: "Edit .shadow/.shadowignore to exclude files or
folders that shouldn't be shadowed (e.g., vendored code, generated
files, tool configs)."
_prefs.md# Preferences
_No preferences recorded yet._
This file stores project-wide user preferences and conventions that are
not tied to any specific file or symbol. It is populated by
/shadow-frog-update when the user shares general directives.
_meta/state.json{
"version": 1,
"initialized_at": "<ISO timestamp>",
"last_update_at": "<ISO timestamp>",
"last_commit": "<full 40-char HEAD SHA>",
"last_update_type": "init|auto|manual|dream|meditate",
"total_files": 0,
"total_symbols": 0,
"total_discoveries": 0,
"dream_cycles_completed": 0
}
For each source file, extract symbols and create a shadow with this structure:
# Shadow: <path/to/file.py>
**Language**: <lang> | **Lines**: <N> | **Last modified**: <date>
## File-Level
_No discoveries yet._
## `class <ClassName>`
### `<ClassName.method>`
_No discoveries yet._
## `<function_name>`
_No discoveries yet._
## Cross-References
_No cross-cutting discoveries yet._
Rules:
##/### heading## Cross-References section is always last## File-Level only; other skills fill in symbols later_index.md# Shadow Index
> Generated by shadow-frog-init on <date>
> Total files: N | Symbols: M | Discoveries: 0 | Cross-cutting: 0
| File | Language | Symbols | Discoveries |
|------|----------|---------|-------------|
| src/auth.py | Python | 5 (UserAuth, authenticate_user, ...) | 0 |
Ask the user: "Should .shadow/ be committed (shared with your team via
git) or gitignored (local to your machine only)?"
Before they decide, make the trade-off explicit:
Committed (shared) — full functionality:
shadow-frog-dream works — autonomous experiments commit .shadow/artifacts onto dream branches, push them, and reconcile merges them back.
shadow-frog-meditate and the viewer work normally.Gitignored (local only) — reduced functionality:
shadow-frog-init, shadow-frog-update, shadow-frog-meditate, and theviewer all still work (they operate on the local filesystem).
shadow-frog-dream will NOT work. Dreams move .shadow/ through git(commit → push → reconcile from the remote); a gitignored .shadow/ is
silently skipped by git add, so discoveries never reach the remote and
are lost. dream-setup.sh detects this and refuses to start with a clear
error rather than failing silently.
.shadow/ to .gitignore.Print: files discovered, languages detected, total symbols.
Suggest: /shadow-frog-update for deeper analysis, /shadow-frog-dream for autonomous exploration.
Take microsoft/shadow-frog-init from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.