From 08453a3890e0e623f9058bc2ba19dc5ee04ba3eb Mon Sep 17 00:00:00 2001 From: Copilot <223556219+Copilot@users.noreply.github.com> Date: Sat, 14 Mar 2026 08:32:53 -0700 Subject: [PATCH] docs: add feature pages for link, nap, and scrub-emails commands Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/src/content/docs/features/link.md | 119 +++++++++++ docs/src/content/docs/features/nap.md | 197 ++++++++++++++++++ .../src/content/docs/features/scrub-emails.md | 160 ++++++++++++++ docs/src/navigation.ts | 6 +- test/docs-build.test.ts | 3 + 5 files changed, 484 insertions(+), 1 deletion(-) create mode 100644 docs/src/content/docs/features/link.md create mode 100644 docs/src/content/docs/features/nap.md create mode 100644 docs/src/content/docs/features/scrub-emails.md diff --git a/docs/src/content/docs/features/link.md b/docs/src/content/docs/features/link.md new file mode 100644 index 000000000..38fe0f2fa --- /dev/null +++ b/docs/src/content/docs/features/link.md @@ -0,0 +1,119 @@ +# Link + +> ⚠️ **Experimental** — Squad is alpha software. APIs, commands, and behavior may change between releases. + +**Try this to link your project to a shared team:** +``` +Squad link to the team repository so we all use the same identities +``` + +**Try this to enable remote Squad mode:** +``` +Link this project to ../shared-team +``` + +Squad enables remote mode by linking a project to a shared team repository's Squad state. Multiple projects can share identity, roles, and decisions from a single "team root." + +--- + +## Overview + +By default, Squad stores team state (`.squad/`) locally in each project. In remote mode, you point to a shared team repository and use its state — enabling multiple projects to share the same agents, casting, roles, and decisions. + +This is useful when: + +- You have multiple related projects that should act as a single team +- You want team identity and decisions to be portable across codebases +- You're in dual-root mode where team governance lives separately from project code + +## Usage + +```bash +squad link +``` + +The path argument is required and can be relative or absolute: + +```bash +squad link ../ai-team +squad link /home/user/projects/shared-team +``` + +## What Happens + +When you run `squad link`: + +1. **Resolves the path** — Converts relative paths to absolute paths +2. **Validates the target** — Checks that the path exists and is a directory +3. **Checks for Squad** — Confirms the target contains `.squad/` or `.ai-team/` directory +4. **Creates `.squad/` locally** — Creates the directory if needed +5. **Computes relative path** — Stores the path relative to your project for portability +6. **Writes config** — Creates `.squad/config.json` with: + ```json + { + "version": 1, + "teamRoot": "", + "projectKey": null + } + ``` +7. **Updates `.gitignore`** — Adds `.squad/config.json` so the local link isn't committed (each dev can link to their own team repo location) + +## Key Behaviors + +- **Idempotent** — Safe to run multiple times. Re-running updates the config with the new path. +- **Relative paths** — Uses relative paths for portability. You can move both project and team repo together without breaking the link. +- **Local, never committed** — `.squad/config.json` stays out of git, so each developer can link to their own team repo location. +- **Validation** — Confirms the target is a real Squad directory before linking. + +## Files Created or Modified + +| File | Action | +|------|--------| +| `.squad/config.json` | Created or overwritten | +| `.gitignore` | Appended (adds `.squad/config.json`) | +| `.squad/` | Created if missing | + +## Related + +- `squad init --mode remote ` — Alternative command that initializes Squad AND links to a team in one step +- See [Team Setup](./team-setup.md) for multi-root architectures and team governance patterns + +## Examples + +Link to a team repo one level up: + +```bash +squad link ../shared-team +``` + +Link to an absolute path: + +```bash +squad link /home/user/projects/ai-team +``` + +Link again with a new path (updates the config): + +```bash +squad link /mnt/teams/our-squad +``` + +## Sample Prompts + +``` +link this project to the team repository +``` + +Enables remote mode by linking to the shared team's `.squad/` state. + +``` +show me the team link configuration +``` + +Displays the current `.squad/config.json` and active team root path. + +``` +are we using a shared team or local Squad? +``` + +Reports whether the project is in remote mode (linked) or local mode. diff --git a/docs/src/content/docs/features/nap.md b/docs/src/content/docs/features/nap.md new file mode 100644 index 000000000..ab168f16c --- /dev/null +++ b/docs/src/content/docs/features/nap.md @@ -0,0 +1,197 @@ +# Nap — Context Hygiene + +> ⚠️ **Experimental** — Squad is alpha software. APIs, commands, and behavior may change between releases. + +**Try this to compress your .squad/ directory:** +``` +Squad, run nap to clean up the context +``` + +**Try this to preview what would be cleaned:** +``` +Squad nap --dry-run +``` + +Context hygiene — the `squad nap` command reduces `.squad/` directory size for LLM context windows by compressing histories, pruning logs, archiving decisions, and merging inboxes. + +--- + +## Overview + +Squad team state grows as you work: histories accumulate sections, logs fill up, decisions pile into inboxes. Over time, your `.squad/` directory can bloat to sizes that consume significant LLM context — context you'd rather use for reasoning about your code. + +`squad nap` performs four cleanup actions to keep your team lean and efficient: + +1. **History compression** — Shrinks histories that exceed 15 KB +2. **Log pruning** — Deletes logs older than 7 days +3. **Inbox cleanup** — Merges inbox decisions into the main file +4. **Decision archival** — Moves old decisions to an archive when the main file is too large + +All actions are safe and reversible (archives are kept as `.md` files). + +## Usage + +```bash +squad nap [--deep] [--dry-run] +``` + +## Flags + +| Flag | Effect | +|------|--------| +| `--dry-run` | Preview what would be cleaned without modifying files | +| `--deep` | Aggressive compression — keeps 3 recent history entries instead of 5 | + +### Examples + +Preview what `nap` would do: + +```bash +squad nap --dry-run +``` + +Run standard cleanup: + +```bash +squad nap +``` + +Run aggressive deep cleanup: + +```bash +squad nap --deep +``` + +## Four Cleanup Actions + +### 1. History compression + +Files exceeding 15 KB trigger compression: + +- **Preserves** — Always keeps the `## Core Context` section +- **Normal mode** — Keeps the last 5 sections, archives older ones to `history-archive.md` +- **Deep mode** — Keeps the last 3 sections, archives older ones + +Example: An agent history of 45 KB with 12 sections: +- Compresses to ~8 KB (5 sections) → moved 7 older sections to `history-archive.md` +- Core Context stays intact + +### 2. Log pruning + +Deletes files older than 7 days from: + +- `.squad/log/` +- `.squad/orchestration-log/` + +Example: If your logs have entries from the last 30 days, `nap` removes anything older than 7 days. + +### 3. Inbox cleanup + +Merges all `.squad/decisions/inbox/*.md` files into `decisions.md`: + +- Reads each inbox file +- Appends content to `decisions.md` +- Deletes the inbox file +- Result: One unified decisions file, no scattered inboxes + +### 4. Decision archival + +When `decisions.md` exceeds 20 KB: + +- Finds entries older than 30 days +- Moves them to `decisions-archive.md` +- Keeps recent decisions in the main file for fast access + +## Output + +`squad nap` reports before/after sizes and actions taken: + +``` +🧘 Nap complete +━━━━━━━━━━━━━━━━━━━━━━━━━ +📊 Context reduction: + .squad/ shrunk from 412 KB → 156 KB (62% reduction) + Est. token savings: ~640 tokens + +✅ Actions completed: + [COMPRESS] agents/alice/history.md (45 KB → 12 KB) + [PRUNE] log/ (deleted 8 files, 47 KB) + [MERGE] decisions/inbox/ (3 files merged) + [ARCHIVE] decisions.md (moved 5 entries > 30d old) +``` + +Each action is tagged: `[COMPRESS]`, `[PRUNE]`, `[ARCHIVE]`, `[MERGE]`. + +## Safety + +`squad nap` creates a `.nap-journal` file to detect interrupted runs: + +- If a previous `nap` was interrupted, the next run detects it +- Warns you and continues anyway (resumes cleanup) +- `.nap-journal` is deleted when `nap` completes successfully + +This prevents partial states from accumulating if a cleanup is interrupted mid-way. + +## Normal vs. Deep Mode + +| Aspect | Normal | Deep | +|--------|--------|------| +| **History threshold** | Keep 5 sections | Keep 3 sections | +| **Archive trigger** | 15 KB | 15 KB | +| **Log age cutoff** | 7 days | 7 days | +| **Use case** | Regular maintenance | Before export or when context is tight | + +**Recommendation:** Start with `squad nap --dry-run` to see what would be cleaned, then decide if you want `--deep`. + +## When to Run + +- When your LLM context window feels bloated +- Before exporting a team with `squad export` +- As regular maintenance (monthly or quarterly) +- Before a long session where you need max context for reasoning + +## Examples + +Dry-run to preview: + +```bash +squad nap --dry-run +``` + +Standard cleanup: + +```bash +squad nap +``` + +Aggressive cleanup before export: + +```bash +squad nap --deep && squad export +``` + +## Sample Prompts + +``` +run nap to clean up the .squad directory +``` + +Executes standard cleanup and reports what was removed. + +``` +squad nap --dry-run +``` + +Shows what would be cleaned without making changes. + +``` +what's the size of .squad after cleanup? +``` + +Runs `nap --dry-run` and reports the projected savings. + +``` +aggressive cleanup — I need max context for this session +``` + +Runs `squad nap --deep` for maximum compression. diff --git a/docs/src/content/docs/features/scrub-emails.md b/docs/src/content/docs/features/scrub-emails.md new file mode 100644 index 000000000..500138aa6 --- /dev/null +++ b/docs/src/content/docs/features/scrub-emails.md @@ -0,0 +1,160 @@ +# Scrub Emails + +> ⚠️ **Experimental** — Squad is alpha software. APIs, commands, and behavior may change between releases. + +**Try this before sharing your team state:** +``` +Scrub email addresses from the team files before sharing +``` + +**Try this to remove PII from Squad state:** +``` +Squad scrub-emails +``` + +Remove personally identifiable information (email addresses) from Squad state files before sharing or exporting. + +--- + +## Overview + +Squad team state includes histories, decisions, and logs — files that may contain email addresses from team members, commit authors, or decision discussions. Before sharing your `.squad/` state publicly or with external teams, you can scrub these emails while keeping the rest of the context intact. + +`squad scrub-emails` preserves names while removing email addresses, ensuring your team's knowledge and decisions stay readable without exposing PII. + +## Usage + +```bash +squad scrub-emails [directory] +``` + +The directory argument is optional and defaults to `.squad/`: + +```bash +squad scrub-emails # Scrubs .squad/ (default) +squad scrub-emails .squad # Explicitly scrub .squad/ +squad scrub-emails /shared/ai-team # Scrub a specific directory +``` + +## What Gets Scrubbed + +`squad scrub-emails` targets these files: + +**Root team files:** +- `team.md` +- `decisions.md` +- `routing.md` +- `ceremonies.md` + +**Agent histories:** +- `.squad/agents/*/history.md` + +**Logs:** +- `.squad/log/**/*.md` +- `.squad/log/**/*.txt` +- `.squad/log/**/*.log` +- `*.txt` and `*.log` files in the target directory + +## Transformation Patterns + +The tool applies two replacement patterns: + +| Pattern | Replacement | Example | +|---------|-------------|---------| +| `name (email@example.com)` | `name` | `Alice (alice@corp.com)` → `Alice` | +| Bare email | `[email scrubbed]` | `contact me at bob@example.com` → `contact me at [email scrubbed]` | + +The goal: preserve the person's name (context-useful) but remove the email (PII). + +## Smart Skipping + +`squad scrub-emails` doesn't blindly scrub everything. It skips: + +- **URLs** — `https://example.com/contact?email=test@example.com` is left untouched +- **Code blocks** — Text inside ` ``` ` code fences is not scrubbed +- **example.com domains** — Fake emails used in docs/examples (e.g., `user@example.com`) are skipped +- **Comment lines** — Lines starting with `//` or `#` are not scrubbed (code examples) + +This prevents breaking URLs, removing documentation examples, and accidentally scrubbing safe mock emails. + +## Key Behaviors + +- **Only modifies files with emails** — Scans for `@` character; only rewrites files that contain email-like patterns +- **Returns count** — Reports how many files were scrubbed and how many emails were removed +- **Safe on missing directories** — If the directory doesn't exist, returns 0 (no error) +- **Idempotent** — Running twice on the same files produces the same result (second run finds no emails) + +## When to Use + +- **Before `squad export`** — Sanitize team state before sharing the export file +- **Before sharing `.squad/` publicly** — Remove emails from histories and decisions +- **When onboarding new team members** — Remove previous team member emails from shared state +- **Before publishing team templates** — Ensure example teams have no PII + +## Examples + +Scrub the default `.squad/` directory: + +```bash +squad scrub-emails +``` + +Scrub a shared team directory: + +```bash +squad scrub-emails /shared/teams/engineering-squad +``` + +Scrub before export: + +```bash +squad scrub-emails && squad export --out ./public-export.json +``` + +## Output Example + +``` +🧹 Scrub complete +━━━━━━━━━━━━━━━━━━━━━━━━━ +✅ 8 files scrubbed + 📄 decisions.md (3 emails removed) + 📄 agents/alice/history.md (5 emails removed) + 📄 agents/bob/history.md (2 emails removed) + 📄 log/2024-01-15.md (1 email removed) + +0 files skipped (no emails found) +``` + +If no emails are found: + +``` +🧹 Scrub complete +━━━━━━━━━━━━━━━━━━━━━━━━━ +No emails found. 0 files modified. +``` + +## Sample Prompts + +``` +scrub emails from the team state +``` + +Removes email addresses from `.squad/` files, preserving names and context. + +``` +scrub-emails before export +``` + +Sanitizes team state, then exports to `squad-export.json` without PII. + +``` +what emails would be scrubbed? +``` + +Shows a dry-run preview of files that contain emails. + +``` +scrub a specific directory +``` + +Targets a custom directory instead of the default `.squad/`. diff --git a/docs/src/navigation.ts b/docs/src/navigation.ts index 0521230b7..2f488428e 100644 --- a/docs/src/navigation.ts +++ b/docs/src/navigation.ts @@ -50,6 +50,7 @@ export const NAV_SECTIONS: NavSection[] = [ { title: 'GitHub Issues', slug: 'features/github-issues' }, { title: 'GitLab Issues', slug: 'features/gitlab-issues' }, { title: 'Labels & Triage', slug: 'features/labels' }, + { title: 'Link', slug: 'features/link' }, { title: 'PRD Mode', slug: 'features/prd-mode' }, { title: 'Project Boards', slug: 'features/project-boards' }, { title: 'Ralph — Work Monitor', slug: 'features/ralph' }, @@ -64,10 +65,12 @@ export const NAV_SECTIONS: NavSection[] = [ { title: 'Marketplace', slug: 'features/marketplace' }, { title: 'Plugins', slug: 'features/plugins' }, { title: 'MCP', slug: 'features/mcp' }, + { title: 'Nap — Context Hygiene', slug: 'features/nap' }, { title: 'Notifications', slug: 'features/notifications' }, { title: 'Enterprise Platforms', slug: 'features/enterprise-platforms' }, { title: 'Squad RC', slug: 'features/squad-rc' }, - { title: 'Streams', slug: 'features/streams' }, + { title: 'Streams', slug: 'features/streams' }, + { title: 'Scrub Emails', slug: 'features/scrub-emails' }, ], }, { @@ -142,3 +145,4 @@ export const STANDALONE_PAGES = [ { title: 'Community', slug: 'community' }, { title: 'Insider Program', slug: 'insider-program' }, ]; + diff --git a/test/docs-build.test.ts b/test/docs-build.test.ts index 513a7d5ec..e43795bae 100644 --- a/test/docs-build.test.ts +++ b/test/docs-build.test.ts @@ -61,10 +61,12 @@ const EXPECTED_FEATURES = [ 'human-team-members', 'issue-templates', 'labels', + 'link', 'marketplace', 'mcp', 'memory', 'model-selection', + 'nap', 'notifications', 'parallel-execution', 'plugins', @@ -75,6 +77,7 @@ const EXPECTED_FEATURES = [ 'response-modes', 'reviewer-protocol', 'routing', + 'scrub-emails', 'skills', 'squad-rc', 'streams',