Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
{
"name": "devflow-ambient",
"source": "./plugins/devflow-ambient",
"description": "Ambient mode — proportional quality enforcement without explicit commands",
"description": "Ambient mode — auto-loads relevant skills for every prompt",
"version": "1.0.0",
"keywords": ["ambient", "routing", "quality", "tdd"]
},
Expand Down
23 changes: 16 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ Plugin marketplace with 9 self-contained plugins, each following the Claude plug
| `devflow-resolve` | Review issue resolution | Optional |
| `devflow-debug` | Competing hypothesis debugging | Optional |
| `devflow-self-review` | Self-review (Simplifier + Scrutinizer) | No |
| `devflow-ambient` | Ambient mode — proportional quality enforcement | No |
| `devflow-ambient` | Ambient mode — auto-loads relevant skills based on each prompt | No |
| `devflow-core-skills` | Auto-activating quality enforcement | No |
| `devflow-audit-claude` | Audit CLAUDE.md files (optional) | No |

Commands with Teams Variant ship as `{name}.md` (parallel subagents) and `{name}-teams.md` (Agent Teams with debate). The installer copies the chosen variant based on `--teams`/`--no-teams` flag.

**Build-time asset distribution**: Skills and agents are stored once in `shared/skills/` and `shared/agents/`, then copied to each plugin at build time based on `plugin.json` manifests. This eliminates duplication in git.

**Working Memory**: Three shell-script hooks (`scripts/hooks/`) provide automatic session continuity. Stop hook → spawns a background `claude -p --resume` process that asynchronously updates `.docs/WORKING-MEMORY.md` (throttled: skips if updated <2min ago; concurrent sessions serialize via mkdir-based lock). SessionStart hook → injects previous memory + git state as `additionalContext` on `/clear`, startup, or compact (warns if >1h stale). PreCompact hook → saves git state backup + bootstraps minimal WORKING-MEMORY.md if none exists. Zero-ceremony context preservation.
**Working Memory**: Three shell-script hooks (`scripts/hooks/`) provide automatic session continuity. Toggleable via `devflow memory --enable/--disable/--status` or `devflow init --memory/--no-memory`. Stop hook → spawns a background `claude -p --resume` process that asynchronously updates `.memory/WORKING-MEMORY.md` with structured sections (`## Now`, `## Progress`, `## Decisions`, `## Modified Files`, `## Context`, `## Session Log`; throttled: skips if updated <2min ago; concurrent sessions serialize via mkdir-based lock; restricted to Write tool on two specific files via `--tools`/`--allowedTools`). SessionStart hook → injects previous memory + git state as `additionalContext` on `/clear`, startup, or compact (warns if >1h stale; injects pre-compact memory snapshot when compaction happened mid-session). PreCompact hook → saves git state + WORKING-MEMORY.md snapshot + bootstraps minimal WORKING-MEMORY.md if none exists. Zero-ceremony context preservation.

## Project Structure

Expand All @@ -43,7 +43,9 @@ devflow/
├── scripts/ # Helper scripts (statusline, docs-helpers)
│ └── hooks/ # Working Memory + ambient hooks (stop, session-start, pre-compact, ambient-prompt)
├── src/cli/ # TypeScript CLI (init, list, uninstall, ambient)
└── .claude-plugin/ # Marketplace registry
├── .claude-plugin/ # Marketplace registry
├── .docs/ # Project docs (reviews, design) — per-project
└── .memory/ # Working memory files — per-project
```

**Install paths**: Commands → `~/.claude/commands/devflow/`, Agents → `~/.claude/agents/devflow/`, Skills → `~/.claude/skills/` (flat), Scripts → `~/.devflow/scripts/`
Expand Down Expand Up @@ -75,14 +77,21 @@ All generated docs live under `.docs/` in the project root:
```
.docs/
├── reviews/{branch-slug}/ # Review reports per branch
├── design/ # Implementation plans
├── WORKING-MEMORY.md # Auto-maintained by Stop hook (overwritten each response)
└── working-memory-backup.json # Pre-compact git state snapshot
└── design/ # Implementation plans
```

Working memory files live in a dedicated `.memory/` directory:

```
.memory/
├── WORKING-MEMORY.md # Auto-maintained by Stop hook (overwritten each session)
├── PROJECT-PATTERNS.md # Accumulated patterns (merged, not overwritten)
└── backup.json # Pre-compact git state snapshot
```

**Naming conventions**: Timestamps as `YYYY-MM-DD_HHMM`, branch slugs replace `/` with `-`, topic slugs are lowercase-dashes. Use `.devflow/scripts/docs-helpers.sh` for consistent naming.

**Persisting agents**: Reviewer → `.docs/reviews/`, Synthesizer → `.docs/reviews/` (review mode), Working Memory → `.docs/WORKING-MEMORY.md` (automatic)
**Persisting agents**: Reviewer → `.docs/reviews/`, Synthesizer → `.docs/reviews/` (review mode), Working Memory → `.memory/WORKING-MEMORY.md` (automatic)

## Agent & Command Roster

Expand Down
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Then in Claude Code:
| `devflow-resolve` | `/resolve` | Process review issues — fix or defer to tech debt |
| `devflow-debug` | `/debug` | Parallel hypothesis debugging |
| `devflow-self-review` | `/self-review` | Self-review workflow (Simplifier + Scrutinizer) |
| `devflow-ambient` | `/ambient` | Ambient mode — proportional quality enforcement |
| `devflow-ambient` | `/ambient` | Ambient mode — auto-loads relevant skills based on each prompt |
| `devflow-core-skills` | (auto) | Auto-activating quality enforcement skills |

## Command Details
Expand Down Expand Up @@ -162,22 +162,25 @@ Three shell hooks run behind the scenes:

| Hook | When | What |
|------|------|------|
| **Stop** | After each response | Updates `.docs/WORKING-MEMORY.md` with current focus, decisions, and progress. Throttled — skips if updated <2 min ago. |
| **Stop** | After each response | Updates `.memory/WORKING-MEMORY.md` with current focus, decisions, and progress. Throttled — skips if updated <2 min ago. |
| **SessionStart** | On startup, `/clear`, resume, compaction | Injects previous working memory + fresh git state as system context. Warns if memory is >1h stale. |
| **PreCompact** | Before context compaction | Backs up git state to JSON. Bootstraps a minimal working memory from git if none exists yet. |

Working memory is **per-project** — scoped to each repo's `.docs/` directory. Multiple sessions across different repos don't interfere.
Working memory is **per-project** — scoped to each repo's `.memory/` directory. Multiple sessions across different repos don't interfere.

## Documentation Structure

DevFlow creates project documentation in `.docs/`:
DevFlow creates project documentation in `.docs/` and working memory in `.memory/`:

```
.docs/
├── reviews/{branch}/ # Review reports per branch
├── design/ # Implementation plans
└── design/ # Implementation plans

.memory/
├── WORKING-MEMORY.md # Auto-maintained by Stop hook
└── working-memory-backup.json # Pre-compact git state snapshot
├── PROJECT-PATTERNS.md # Accumulated patterns across sessions
└── backup.json # Pre-compact git state snapshot
```

## Workflow Examples
Expand Down
11 changes: 6 additions & 5 deletions docs/reference/file-organization.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ devflow/
├── commands/
│ ├── init.ts
│ ├── list.ts
│ ├── memory.ts
│ └── uninstall.ts
└── cli.ts
```
Expand Down Expand Up @@ -135,17 +136,17 @@ Included settings:

## Working Memory Hooks

Three hooks in `scripts/hooks/` provide automatic session continuity:
Three hooks in `scripts/hooks/` provide automatic session continuity. Toggleable via `devflow memory --enable/--disable/--status` or `devflow init --memory/--no-memory`:

| Hook | Event | File | Purpose |
|------|-------|------|---------|
| `stop-update-memory.sh` | Stop | `.docs/WORKING-MEMORY.md` | Throttled (skips if <2min fresh). Slim instruction after first write. |
| `session-start-memory.sh` | SessionStart | reads WORKING-MEMORY.md | Injects previous memory + git state as `additionalContext`. Warns if >1h stale. |
| `pre-compact-memory.sh` | PreCompact | `.docs/working-memory-backup.json` | Saves git state snapshot. Bootstraps minimal WORKING-MEMORY.md if none exists. |
| `stop-update-memory.sh` | Stop | `.memory/WORKING-MEMORY.md` | Throttled (skips if <2min fresh). Slim instruction after first write. |
| `session-start-memory.sh` | SessionStart | reads WORKING-MEMORY.md | Injects previous memory + git state as `additionalContext`. Warns if >1h stale. Injects pre-compact snapshot when compaction occurred mid-session. |
| `pre-compact-memory.sh` | PreCompact | `.memory/backup.json` | Saves git state + WORKING-MEMORY.md snapshot. Bootstraps minimal WORKING-MEMORY.md if none exists. |

**Flow**: Claude responds → Stop hook checks mtime (skips if <2min fresh) → blocks with instruction → Claude writes WORKING-MEMORY.md silently → `stop_hook_active=true` → allows stop. On `/clear` or new session → SessionStart injects memory as `additionalContext` (system context, not user-visible) with staleness warning if >1h old.

All hooks are no-ops in projects without `.docs/` (non-DevFlow projects).
Hooks auto-create `.memory/` on first run — no manual setup needed per project.

## Statusline Script

Expand Down
2 changes: 1 addition & 1 deletion plugins/devflow-ambient/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "devflow-ambient",
"description": "Ambient mode — proportional quality enforcement without explicit commands",
"description": "Ambient mode — auto-loads relevant skills for every prompt",
"version": "1.0.0",
"agents": [],
"skills": ["ambient-router"]
Expand Down
2 changes: 1 addition & 1 deletion plugins/devflow-ambient/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# devflow-ambient

Ambient mode — proportional quality enforcement without explicit command invocation.
Ambient mode — auto-loads relevant skills based on each prompt, no explicit commands needed.

## Command

Expand Down
6 changes: 3 additions & 3 deletions plugins/devflow-ambient/commands/ambient.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
description: Ambient mode — classify intent and apply proportional quality enforcement to any prompt
description: Ambient mode — classify intent and auto-load relevant skills for any prompt
---

# Ambient Command

Classify user intent and apply proportional quality enforcement. No agents spawned — enhances the main session only.
Classify user intent and auto-load relevant skills. No agents spawned — enhances the main session only.

## Usage

Expand Down Expand Up @@ -32,7 +32,7 @@ If no arguments provided, output:
```
## Ambient Mode

Classify intent and apply proportional quality enforcement.
Classify intent and auto-load relevant skills.

Usage: /ambient <your prompt>

Expand Down
2 changes: 1 addition & 1 deletion scripts/hooks/ambient-prompt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Ambient Mode: UserPromptSubmit Hook
# Injects a classification preamble before every user prompt so Claude applies
# proportional quality enforcement via the ambient-router skill.
# relevant skill loading via the ambient-router skill.
# Zero file I/O beyond stdin — static injection only.

set -euo pipefail
Expand Down
30 changes: 19 additions & 11 deletions scripts/hooks/background-memory-update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Background Working Memory Updater
# Called by stop-update-memory.sh as a detached background process.
# Resumes the parent session headlessly to update .docs/WORKING-MEMORY.md.
# Resumes the parent session headlessly to update .memory/WORKING-MEMORY.md.
# On failure: logs error, does nothing (no fallback).

set -euo pipefail
Expand All @@ -12,8 +12,8 @@ SESSION_ID="$2"
MEMORY_FILE="$3"
CLAUDE_BIN="$4"

LOG_FILE="$CWD/.docs/.working-memory-update.log"
LOCK_DIR="$CWD/.docs/.working-memory.lock"
LOG_FILE="$CWD/.memory/.working-memory-update.log"
LOCK_DIR="$CWD/.memory/.working-memory.lock"

# --- Logging ---

Expand Down Expand Up @@ -103,13 +103,13 @@ fi
# Build instruction
if [ -n "$EXISTING_MEMORY" ]; then
PATTERNS_INSTRUCTION=""
PATTERNS_FILE="$CWD/.docs/patterns.md"
PATTERNS_FILE="$CWD/.memory/PROJECT-PATTERNS.md"
EXISTING_PATTERNS=""
if [ -f "$PATTERNS_FILE" ]; then
EXISTING_PATTERNS=$(cat "$PATTERNS_FILE")
PATTERNS_INSTRUCTION="

Also update $PATTERNS_FILE by APPENDING any new recurring patterns discovered during this session. Do NOT overwrite existing entries — only add new ones. Skip if no new patterns were observed. Format each entry as: - **Pattern name**: Brief description (discovered: YYYY-MM-DD)
Also update $PATTERNS_FILE by APPENDING any new recurring patterns discovered during this session. Do NOT overwrite existing entries — only add new ones. Skip if no new patterns were observed. Format each entry as: - **Pattern name**: Brief description (discovered: YYYY-MM-DD). Keep patterns.md under 40 entries. When approaching the limit, consolidate related patterns into broader entries rather than adding duplicates.

Existing patterns:
$EXISTING_PATTERNS"
Expand All @@ -119,18 +119,22 @@ else
If recurring patterns were observed during this session (coding conventions, architectural decisions, team preferences, tooling quirks), create $PATTERNS_FILE with entries formatted as: - **Pattern name**: Brief description (discovered: YYYY-MM-DD). Only create this file if genuine patterns were observed — do not fabricate entries."
fi

INSTRUCTION="Update the file $MEMORY_FILE with working memory from this session. The file already has content — possibly from a concurrent session that just wrote it moments ago. Merge this session's context with the existing content to produce a single unified working memory snapshot. Both this session and the existing content represent fresh, concurrent work — integrate both fully. Working memory captures what's active now, not a changelog. Deduplicate overlapping information. Keep under 100 lines total. Use the same structure: ## Now, ## Decisions, ## Modified Files, ## Context, ## Session Log.${PATTERNS_INSTRUCTION}
INSTRUCTION="Update the file $MEMORY_FILE with working memory from this session. The file already has content — possibly from a concurrent session that just wrote it moments ago. Merge this session's context with the existing content to produce a single unified working memory snapshot. Both this session and the existing content represent fresh, concurrent work — integrate both fully. Working memory captures what's active now, not a changelog. Deduplicate overlapping information. Keep under 120 lines total. Use the same structure: ## Now, ## Progress, ## Decisions, ## Modified Files, ## Context, ## Session Log.

## Progress tracks Done (completed items), Remaining (next steps), and Blockers (if any). Keep each sub-list to 1-3 items. This section reflects current work state, not historical logs.

## Decisions entries must include date and status. Format: - **[Decision]** — [rationale] (YYYY-MM-DD) [ACTIVE|SUPERSEDED]. Mark superseded decisions rather than deleting them.${PATTERNS_INSTRUCTION}

Existing content:
$EXISTING_MEMORY"
else
PATTERNS_INSTRUCTION=""
PATTERNS_FILE="$CWD/.docs/patterns.md"
PATTERNS_FILE="$CWD/.memory/PROJECT-PATTERNS.md"
if [ -f "$PATTERNS_FILE" ]; then
EXISTING_PATTERNS=$(cat "$PATTERNS_FILE")
PATTERNS_INSTRUCTION="

Also update $PATTERNS_FILE by APPENDING any new recurring patterns discovered during this session. Do NOT overwrite existing entries — only add new ones. Skip if no new patterns were observed. Format each entry as: - **Pattern name**: Brief description (discovered: YYYY-MM-DD)
Also update $PATTERNS_FILE by APPENDING any new recurring patterns discovered during this session. Do NOT overwrite existing entries — only add new ones. Skip if no new patterns were observed. Format each entry as: - **Pattern name**: Brief description (discovered: YYYY-MM-DD). Keep patterns.md under 40 entries. When approaching the limit, consolidate related patterns into broader entries rather than adding duplicates.

Existing patterns:
$EXISTING_PATTERNS"
Expand All @@ -140,15 +144,18 @@ $EXISTING_PATTERNS"
If recurring patterns were observed during this session (coding conventions, architectural decisions, team preferences, tooling quirks), create $PATTERNS_FILE with entries formatted as: - **Pattern name**: Brief description (discovered: YYYY-MM-DD). Only create this file if genuine patterns were observed — do not fabricate entries."
fi

INSTRUCTION="Create the file $MEMORY_FILE with working memory from this session. Keep under 100 lines. Use this structure:
INSTRUCTION="Create the file $MEMORY_FILE with working memory from this session. Keep under 120 lines. Use this structure:

# Working Memory

## Now
<!-- Current focus, status, blockers (1-3 bullets) -->

## Progress
<!-- Done: completed items (1-3). Remaining: next steps (1-3). Blockers: if any. -->

## Decisions
<!-- Key decisions made this session with brief rationale -->
<!-- Format: - **[Decision]** — [rationale] (YYYY-MM-DD) [ACTIVE|SUPERSEDED] -->

## Modified Files
<!-- File paths only, most recent first -->
Expand All @@ -171,7 +178,8 @@ TIMEOUT=120 # Normal runtime 30-60s; 2x margin
DEVFLOW_BG_UPDATER=1 env -u CLAUDECODE "$CLAUDE_BIN" -p \
--resume "$SESSION_ID" \
--model haiku \
--dangerously-skip-permissions \
--tools "Write" \
--allowedTools "Write($CWD/.memory/WORKING-MEMORY.md)" "Write($CWD/.memory/PROJECT-PATTERNS.md)" \
--no-session-persistence \
--output-format text \
"$INSTRUCTION" \
Expand Down
17 changes: 17 additions & 0 deletions scripts/hooks/ensure-memory-gitignore.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash
# Ensures .memory/ exists and .gitignore entries are configured.
# Called from stop and pre-compact hooks. Idempotent, ~1μs after first run.
# Usage: source ensure-memory-gitignore.sh "$CWD"

_MEMORY_DIR="$1/.memory"

# Create .memory/ if needed
mkdir -p "$_MEMORY_DIR" 2>/dev/null || return 1

# One-time .gitignore setup (marker prevents repeated checks)
if [ ! -f "$_MEMORY_DIR/.gitignore-configured" ] && [ -e "$1/.git" ]; then
for _entry in ".memory/" ".docs/"; do
grep -qxF "$_entry" "$1/.gitignore" 2>/dev/null || echo "$_entry" >> "$1/.gitignore"
done
touch "$_MEMORY_DIR/.gitignore-configured"
fi
18 changes: 12 additions & 6 deletions scripts/hooks/pre-compact-memory.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@ if [ -z "$CWD" ]; then
exit 0
fi

# Only activate in DevFlow-initialized projects
if [ ! -d "$CWD/.docs" ]; then
exit 0
fi
# Auto-create .memory/ and ensure .gitignore entries (idempotent after first run)
source "$(cd "$(dirname "$0")" && pwd)/ensure-memory-gitignore.sh" "$CWD" || exit 0

BACKUP_FILE="$CWD/.docs/working-memory-backup.json"
BACKUP_FILE="$CWD/.memory/backup.json"

# Capture git state
GIT_BRANCH=""
Expand All @@ -39,16 +37,24 @@ if cd "$CWD" 2>/dev/null && git rev-parse --git-dir >/dev/null 2>&1; then
GIT_DIFF_STAT=$(git diff --stat HEAD 2>/dev/null || echo "")
fi

# Snapshot current WORKING-MEMORY.md (preserves session context through compaction)
MEMORY_SNAPSHOT=""
if [ -f "$CWD/.memory/WORKING-MEMORY.md" ]; then
MEMORY_SNAPSHOT=$(cat "$CWD/.memory/WORKING-MEMORY.md")
fi

# Write backup JSON
jq -n \
--arg ts "$TIMESTAMP" \
--arg branch "$GIT_BRANCH" \
--arg status "$GIT_STATUS" \
--arg log "$GIT_LOG" \
--arg diff "$GIT_DIFF_STAT" \
--arg memory "$MEMORY_SNAPSHOT" \
'{
timestamp: $ts,
trigger: "pre-compact",
memory_snapshot: $memory,
git: {
branch: $branch,
status: $status,
Expand All @@ -59,7 +65,7 @@ jq -n \

# Bootstrap minimal WORKING-MEMORY.md if none exists yet
# This ensures SessionStart has context to inject after compaction
MEMORY_FILE="$CWD/.docs/WORKING-MEMORY.md"
MEMORY_FILE="$CWD/.memory/WORKING-MEMORY.md"
if [ ! -f "$MEMORY_FILE" ] && [ -n "$GIT_BRANCH" ]; then
{
echo "# Working Memory"
Expand Down
Loading