Skip to content

Instantly share code, notes, and snippets.

@Nadiar
Created October 14, 2025 09:02
Show Gist options
  • Select an option

  • Save Nadiar/9aaf71e788144bb6d3925b84b0d881d4 to your computer and use it in GitHub Desktop.

Select an option

Save Nadiar/9aaf71e788144bb6d3925b84b0d881d4 to your computer and use it in GitHub Desktop.
Drop these in your workspace root in .claude. I use a multi-root project layout where inside of my main workspace I have projects in their own folder.

Bootstrapping the Context System

This guide shows how to implement the two-tier context system (workspace + projects) in a new multi-root workspace.

Quick Overview

The context system consists of:

  • Machine-optimized context maps - Auto-generated, compressed memory files
  • SessionStart hooks - Automatically regenerate context on every session
  • Two-tier structure - Workspace-wide + project-specific contexts

Step-by-Step Setup

1. Create Directory Structure

# In workspace root
mkdir -p .claude

# For each project
mkdir -p PROJECT_NAME/.claude

2. Create Workspace Context Generator

Create .claude/generate-context-map.sh:

#!/bin/bash
OUTPUT_FILE=".claude/context-map.md"

cat > $OUTPUT_FILE << 'HEADER'
# WORKSPACE_MEMORY v1.0
🧠 Multi-root workspace context. Machine-optimized format.
Each project is a separate Git repository.
HEADER

echo "" >> $OUTPUT_FILE

echo "## [NOW]" >> $OUTPUT_FILE
echo "DATE:$(date '+%Y-%m-%d.%A')" >> $OUTPUT_FILE
echo "" >> $OUTPUT_FILE

# List projects
echo "## [PROJECTS]" >> $OUTPUT_FILE
cat << 'PROJECTS' >> $OUTPUT_FILE
WORKSPACE: Multi-root (each project = separate git repo)
project1/: Description (separate repo)
project2/: Description (separate repo)
PROJECTS
echo "" >> $OUTPUT_FILE

# Add workspace-wide patterns
echo "## [PATTERNS]" >> $OUTPUT_FILE
cat << 'PATTERNS' >> $OUTPUT_FILE
# Your common patterns across projects
# Example: python.projects: src-layout, pyproject.toml, pip install -e .
PATTERNS
echo "" >> $OUTPUT_FILE

# Add solved problems
echo "## [SOLVED_PROBLEMS]" >> $OUTPUT_FILE
cat << 'SOLVED' >> $OUTPUT_FILE
# Track solutions to prevent re-suggesting failed approaches
# Example: auth.approach(2025-01-15): JWT failed (size) → sessions instead
SOLVED
echo "" >> $OUTPUT_FILE

# Add anti-patterns
echo "## [ANTI_PATTERNS]" >> $OUTPUT_FILE
cat << 'ANTI' >> $OUTPUT_FILE
NEVER.force_push: Without explicit user confirmation
NEVER.commit_autogen: Add .claude/ to .gitignore
NEVER.create_docs: Unless explicitly requested by user
ANTI
echo "" >> $OUTPUT_FILE

# Git status (if applicable)
if git rev-parse --git-dir > /dev/null 2>&1; then
  echo "## [GIT_STATUS]" >> $OUTPUT_FILE
  echo "BRANCH:$(git branch --show-current 2>/dev/null)" >> $OUTPUT_FILE
  AHEAD=$(git rev-list --count @{u}..HEAD 2>/dev/null || echo 0)
  BEHIND=$(git rev-list --count HEAD..@{u} 2>/dev/null || echo 0)
  echo "AHEAD:$AHEAD | BEHIND:$BEHIND" >> $OUTPUT_FILE
  echo "" >> $OUTPUT_FILE
fi

echo "## [META]" >> $OUTPUT_FILE
echo "GENERATED:$(date '+%Y-%m-%d@%H:%M:%S')" >> $OUTPUT_FILE
echo "WORKSPACE:Multi-root workspace (each project = separate git repository)" >> $OUTPUT_FILE

echo "✓ Context map generated at $OUTPUT_FILE"

Make executable:

chmod +x .claude/generate-context-map.sh

3. Create Project Context Generator

Create PROJECT/.claude/generate-context-map.sh for each project:

#!/bin/bash
OUTPUT_FILE=".claude/context-map.md"

cat > $OUTPUT_FILE << 'HEADER'
# PROJECT_MEMORY v1.0
🧠 Project context. Machine-optimized format.
HEADER

echo "" >> $OUTPUT_FILE

echo "## [NOW]" >> $OUTPUT_FILE
echo "DATE:$(date '+%Y-%m-%d.%A') | BRANCH:$(git branch --show-current 2>/dev/null || echo 'no-git')" >> $OUTPUT_FILE
echo "" >> $OUTPUT_FILE

# Project architecture
echo "## [ARCHITECTURE]" >> $OUTPUT_FILE
cat << 'ARCH' >> $OUTPUT_FILE
type: Project type (Python CLI, Chrome Extension, Web App, etc)
structure: Key directories and layout
dependencies: Major dependencies
ARCH
echo "" >> $OUTPUT_FILE

# Commands
echo "## [COMMANDS]" >> $OUTPUT_FILE
cat << 'CMDS' >> $OUTPUT_FILE
build: Command to build the project
test: Command to run tests
install: How to install dependencies
dev: How to run in development mode
CMDS
echo "" >> $OUTPUT_FILE

# Solved problems specific to this project
echo "## [SOLVED]" >> $OUTPUT_FILE
cat << 'SOLVED' >> $OUTPUT_FILE
# Project-specific solutions
SOLVED
echo "" >> $OUTPUT_FILE

# Code paths
echo "## [PATHS]" >> $OUTPUT_FILE
cat << 'PATHS' >> $OUTPUT_FILE
# Important code flow paths
# Example: auth: login.js:45→validate→token→response
PATHS
echo "" >> $OUTPUT_FILE

# Anti-patterns
echo "## [NEVER]" >> $OUTPUT_FILE
cat << 'NEVER' >> $OUTPUT_FILE
# Project-specific anti-patterns
NEVER
echo "" >> $OUTPUT_FILE

# Recent changes
echo "## [RECENT]" >> $OUTPUT_FILE
git log --since="7 days ago" --pretty=format:"%ad %s" --date=format:'%m/%d' 2>/dev/null | head -8 >> $OUTPUT_FILE
echo "" >> $OUTPUT_FILE

# Git status
if git rev-parse --git-dir > /dev/null 2>&1; then
  echo "## [GIT]" >> $OUTPUT_FILE
  echo "BRANCH:$(git branch --show-current 2>/dev/null)" >> $OUTPUT_FILE
  AHEAD=$(git rev-list --count @{u}..HEAD 2>/dev/null || echo 0)
  BEHIND=$(git rev-list --count HEAD..@{u} 2>/dev/null || echo 0)
  echo "AHEAD:$AHEAD BEHIND:$BEHIND" >> $OUTPUT_FILE
  DIRTY=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
  [ "$DIRTY" -gt 0 ] && echo "UNCOMMITTED:$DIRTY" >> $OUTPUT_FILE
  echo "" >> $OUTPUT_FILE
fi

echo "## [META]" >> $OUTPUT_FILE
echo "GENERATED:$(date '+%Y-%m-%d@%H:%M:%S')" >> $OUTPUT_FILE
echo "PROJECT:Your project name and description" >> $OUTPUT_FILE

echo "✓ Project context map → $OUTPUT_FILE"

Make executable:

chmod +x PROJECT/.claude/generate-context-map.sh

4. Setup SessionStart Hooks

Create .claude/hooks.json:

{
  "sessionStart": [
    {
      "type": "command",
      "command": "bash .claude/generate-context-map.sh",
      "description": "Generate workspace context map",
      "timeout": 5000
    },
    {
      "type": "command",
      "command": "bash project1/.claude/generate-context-map.sh",
      "description": "Generate project1 context map",
      "timeout": 5000
    },
    {
      "type": "command",
      "command": "bash project2/.claude/generate-context-map.sh",
      "description": "Generate project2 context map",
      "timeout": 5000
    }
  ]
}

5. Update .gitignore Files

Add to workspace .gitignore:

# Claude AI context files (auto-generated)
.claude/
*/.claude/

Add to each project's .gitignore:

# Claude AI context files (auto-generated)
.claude/

6. Create CLAUDE.md Files

Workspace .claude/CLAUDE.md:

# Multi-Root Workspace - Claude Context

🧠 **CONTEXT RESET? START HERE:**
1. **Read workspace context first:** [.claude/context-map.md](./.claude/context-map.md)
2. **Then read project-specific context** when working on a project

## Context File Organization

**Two-tier structure:**
- **Workspace `.claude/`** - Workspace-wide instructions, general patterns
- **Project `.claude/`** - Project-specific architecture, commands, patterns

## Workspace Structure

This is a **multi-root workspace** containing multiple independent repositories:

1. **Project 1** - Description (separate repo)
2. **Project 2** - Description (separate repo)

## General Patterns (All Projects)

[Add your common patterns here]

## Anti-Patterns (Never Do These)

- **NEVER** commit auto-generated files (.claude/context-map.md)
- **NEVER** use unnecessary preamble - just do it
- **NEVER** force push without explicit user confirmation

Project .claude/CLAUDE.md:

# Project Name

🧠 **PROJECT CONTEXT:** [.claude/context-map.md](./.claude/context-map.md) - Read this first.

## Project Overview

[Brief description of what this project does]

## Quick Start

```bash
# Commands to get started

Architecture

[Key architectural decisions and structure]

Common Tasks

[Frequently used commands and workflows]


### 7. Test the System

```bash
# Generate all context maps manually
bash .claude/generate-context-map.sh
bash project1/.claude/generate-context-map.sh
bash project2/.claude/generate-context-map.sh

# Verify files were created
ls -la .claude/context-map.md
ls -la project1/.claude/context-map.md

# Verify auto-generation on session start works
# (Close and reopen your Claude Code session)

Context Map Sections Reference

Common sections to include in your context maps:

  • [NOW] - Current date, branch (for projects)
  • [PROJECTS] - List of projects in workspace
  • [ARCHITECTURE] - System architecture, key components
  • [COMMANDS] - Build, test, install commands
  • [PATTERNS] - Common patterns and conventions
  • [SOLVED_PROBLEMS] - What we tried and what worked
  • [ANTI_PATTERNS] - What never to do
  • [PATHS] - Important code paths (file:line→function→result)
  • [FILES] - Key files with hot zones (line ranges)
  • [RECENT] - Recent changes from git log
  • [GIT] - Branch, ahead/behind status
  • [HOT_FILES] - Frequently modified files
  • [META] - Generation timestamp, purpose

Benefits

Once set up, you get:

  • Instant context recovery after session resets
  • ~80% token reduction vs human-readable docs
  • Automatic updates on every session start
  • No repeating yourself - "See [SOLVED_PROBLEMS]"
  • Fast navigation - file:line references
  • Git awareness - recent changes, hot files

Customization

Customize the generators by:

  • Adding project-specific sections (e.g., [PAYMENT], [MODELS])
  • Including environment status checks
  • Adding TODO integration
  • Tracking feature flags
  • Including test results
  • Adding migration status

See existing generators in this workspace for examples.

Multi-Root Workspace - Claude Context

🧠 CONTEXT RESET? START HERE:

  1. Read workspace context first: .claude/context-map.md - Workspace-wide memory
  2. Then read project-specific context when working on a project:

⚠️ CUSTOMIZE THIS FILE: Update the project list above and the "Workspace Structure" section below with your actual projects.

Context File Organization

Two-tier structure:

  • Workspace .claude/ - Workspace-wide instructions, general patterns, solved problems across all projects
  • Project .claude/ - Project-specific architecture, commands, patterns, and memory

Workspace Level (.claude/)

  • CLAUDE.md - This file, navigation and structure
  • context-map.md - Auto-generated, machine-optimized memory for workspace-wide context
  • hooks.json - SessionStart hooks to regenerate all context maps
  • BOOTSTRAP.md - Setup instructions for new workspaces (only read when needed)

Project Level (project/.claude/)

Each project has its own .claude/ directory with:

  • CLAUDE.md - Human-readable project-specific instructions
  • context-map.md - Auto-generated project-specific memory
  • generate-context-map.sh - Project-specific context generator
  • Any project-specific planning/decision files

Workspace Structure

This is a multi-root workspace containing multiple independent repositories:

  1. [Project Name] - [Brief description] ([Language/Type], separate repo)
  2. [Project Name] - [Brief description] ([Language/Type], separate repo)
  3. [Project Name] - [Brief description] ([Language/Type], separate repo)

⚠️ UPDATE THIS LIST: Replace the examples above with your actual project names and descriptions.

Important: Each project is an independent Git repository. They are not submodules - this workspace simply groups multiple repositories together for convenience.

General Patterns (All Projects)

⚠️ CUSTOMIZE THIS SECTION: Add patterns common across your projects. Remove sections that don't apply.

Python Projects (Example)

  • Structure: src-layout with src/<package_name>/
  • Build: pyproject.toml with setuptools
  • Install: cd project/ && pip install -e . (always from project directory)
  • CLI: Entry points defined in [project.scripts]

JavaScript/TypeScript Projects (Example)

  • Build Tools: Vite, webpack, or rollup
  • Package Manager: npm, yarn, or pnpm
  • Tests: Jest, Vitest, or Playwright

Git Workflow (Example)

  • Feature branches for development
  • NO force push to main/master without explicit user confirmation
  • Commit messages should be clear and descriptive

Naming Conventions (Example)

  • Python: snake_case for modules/functions, PascalCase for classes
  • JavaScript: camelCase for functions, PascalCase for components
  • Files: kebab-case for config files, PascalCase for components

Anti-Patterns (Never Do These)

  • NEVER create documentation files (*.md) unless explicitly requested except README and CHANGELOG
  • NEVER commit auto-generated files (.claude/context-map.md should be in .gitignore)
  • NEVER use unnecessary preamble ("Here's what I'll do...") - just do it
  • NEVER force push without explicit user confirmation

Context Map Generation

Run the context map generator to refresh machine-optimized memory:

# Workspace level
bash .claude/generate-context-map.sh

# Project level
bash project/.claude/generate-context-map.sh

Bootstrapping a New Workspace

Need to set up this context system in a new workspace?

See BOOTSTRAP.md for complete step-by-step instructions including:

  • Directory structure setup
  • Context generator templates (workspace + project)
  • SessionStart hooks configuration
  • Gitignore setup
  • CLAUDE.md templates
  • Testing and verification steps

Remember: Read workspace context first, then dive into project-specific context when working on that project. Each project is a separate Git repository with its own history and version control.

#!/bin/bash
# Workspace Context Map Generator
# This script generates a machine-optimized memory file for Claude AI
# Run this script: bash .claude/generate-context-map.sh
OUTPUT_FILE=".claude/context-map.md"
# Create the header
cat > $OUTPUT_FILE << 'HEADER'
# WORKSPACE_MEMORY v1.0
🧠 Multi-root workspace context. Machine-optimized format.
Each project is a separate Git repository.
HEADER
echo "" >> $OUTPUT_FILE
# Current date (no git branch for multi-root workspace)
echo "## [NOW]" >> $OUTPUT_FILE
echo "DATE:$(date '+%Y-%m-%d.%A')" >> $OUTPUT_FILE
echo "" >> $OUTPUT_FILE
# Active work from TODO.md (optional)
if [ -f "TODO.md" ]; then
echo "## [ACTIVE_CONTEXT]" >> $OUTPUT_FILE
TASKS=$(grep "- \[ \]" TODO.md 2>/dev/null | head -5 | sed 's/- \[ \] //' | tr '\n' '|' | sed 's/|$//')
if [ -n "$TASKS" ]; then
echo "ACTIVE: $TASKS" >> $OUTPUT_FILE
fi
echo "" >> $OUTPUT_FILE
fi
# Project structure - CUSTOMIZE THIS SECTION
echo "## [PROJECTS]" >> $OUTPUT_FILE
cat << 'PROJECTS' >> $OUTPUT_FILE
WORKSPACE: Multi-root (each project = separate git repo)
project1-name/: Brief description of project 1 (Python/JS/etc, separate repo)
project2-name/: Brief description of project 2 (Python/JS/etc, separate repo)
project3-name/: Brief description of project 3 (Python/JS/etc, separate repo)
PROJECTS
echo "" >> $OUTPUT_FILE
# Workspace-wide patterns - CUSTOMIZE THIS SECTION
echo "## [PATTERNS]" >> $OUTPUT_FILE
cat << 'PATTERNS' >> $OUTPUT_FILE
# Add your common patterns here
# Examples:
# python.projects: src-layout, pyproject.toml, pip install -e .
# js.projects: npm/yarn, vite/webpack, jest/vitest
# git.workflow: feature branches, NO force push to main
# naming.py: snake_case functions, PascalCase classes
# naming.js: camelCase functions, PascalCase components
PATTERNS
echo "" >> $OUTPUT_FILE
# Solved problems - TRACK WHAT YOU'VE TRIED
echo "## [SOLVED_PROBLEMS]" >> $OUTPUT_FILE
cat << 'SOLVED' >> $OUTPUT_FILE
# Track solutions to prevent re-suggesting failed approaches
# Format: problem.name(date): What failed → What worked instead
# Example: auth.jwt(2025-01-15): JWT size issues → switched to sessions
# Example: db.orm(2025-01-10): ORM too slow → raw SQL with prepared statements
SOLVED
echo "" >> $OUTPUT_FILE
# Anti-patterns - THINGS TO NEVER DO
echo "## [ANTI_PATTERNS]" >> $OUTPUT_FILE
cat << 'ANTI' >> $OUTPUT_FILE
NEVER.force_push: Without explicit user confirmation
NEVER.commit_autogen: Add .claude/ to .gitignore (context maps are auto-generated)
NEVER.create_docs: Unless explicitly requested by user (except README/CHANGELOG)
NEVER.preamble: Skip "Here's what I'll do" - just do it
# Add your own anti-patterns below:
ANTI
echo "" >> $OUTPUT_FILE
# Key files across workspace (optional, remove if not applicable)
echo "## [KEY_FILES]" >> $OUTPUT_FILE
cat << 'FILES' >> $OUTPUT_FILE
# Important files that span multiple projects
# Format: path/to/file: description@line-range
# Example: scripts/deploy.sh: Deployment automation@1-150
FILES
echo "" >> $OUTPUT_FILE
# Git status (only if workspace root is a git repo)
if git rev-parse --git-dir > /dev/null 2>&1; then
echo "## [GIT_STATUS]" >> $OUTPUT_FILE
echo "BRANCH:$(git branch --show-current 2>/dev/null)" >> $OUTPUT_FILE
AHEAD=$(git rev-list --count @{u}..HEAD 2>/dev/null || echo 0)
BEHIND=$(git rev-list --count HEAD..@{u} 2>/dev/null || echo 0)
echo "AHEAD:$AHEAD | BEHIND:$BEHIND" >> $OUTPUT_FILE
DIRTY=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
if [ "$DIRTY" -gt 0 ]; then
echo "UNCOMMITTED: $DIRTY files" >> $OUTPUT_FILE
fi
echo "" >> $OUTPUT_FILE
fi
# Meta information
echo "## [META]" >> $OUTPUT_FILE
echo "GENERATED:$(date '+%Y-%m-%d@%H:%M:%S')" >> $OUTPUT_FILE
echo "PURPOSE:Claude's memory system. Not for humans." >> $OUTPUT_FILE
echo "WORKSPACE:Multi-root workspace (each project = separate git repository)" >> $OUTPUT_FILE
echo "✓ Context map generated at $OUTPUT_FILE"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment