Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 17:59:29 +08:00
commit 681c2e46c0
31 changed files with 6218 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
{
"name": "session",
"description": "v3.17.4 - Advanced session management for Claude Code with intelligent context tracking, automatic snapshots, and git history capture. Features zero-blocking conversation logging, AI-powered analysis, and optimized parallel subagent architecture. Never lose context!",
"version": "3.17.4",
"author": {
"name": "AutomateWith.Us",
"email": "team@automatewith.us"
},
"commands": [
"./commands"
],
"hooks": [
"./hooks"
]
}

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# session
v3.17.4 - Advanced session management for Claude Code with intelligent context tracking, automatic snapshots, and git history capture. Features zero-blocking conversation logging, AI-powered analysis, and optimized parallel subagent architecture. Never lose context!

187
commands/close.md Normal file
View File

@@ -0,0 +1,187 @@
You are managing a session memory system. The user wants to close and finalize the current session.
**CRITICAL - Command Format:**
All session plugin commands use the `/session:` prefix. DO NOT suggest commands without this prefix.
- ✅ Correct: `/session:list`, `/session:start`, `/session:continue`, `/session:status`
- ❌ Wrong: `/session list`, `/session start`, `/session continue`, `/session status`
Use ONLY the exact command formats specified in this template.
## Task: Close Session
Finalize the session by creating a final snapshot, updating metadata, and generating a summary.
### Step 1: Validate Active Session
1. Check if `.claude/sessions/.active-session` file exists
2. If NOT exists, show error:
```
❌ Error: No active session to close
💡 Use /session:start [name] to create a new session
💡 Or use /session:continue [name] to resume an existing session
```
Then STOP.
3. Read the active session name from `.active-session`
4. Verify session directory exists
### Step 2: Read Current Session Data
Read `.claude/sessions/{active_session}/session.md` and extract:
- Started timestamp
- Last Updated timestamp
- Goal
- Files Involved
- Milestones (count completed and total)
### Step 3: Calculate Session Statistics
1. **Duration**: Calculate time from "Started" to now
- Format: `Xh Ym` (e.g., "4h 35m")
2. **Snapshot Count**: Count all snapshot files matching `YYYY-MM-DD_HH-MM.md` pattern in session directory
3. **Files Modified**: Count unique files in "Files Involved" section of session.md
4. **Todos/Milestones Completed**: Count checked milestones in session.md
5. **Token Usage**: Get current conversation token usage (from system info or estimate)
- Format as "XXXk" (e.g., "67.4k")
### Step 4: Generate Final Snapshot
Create a final snapshot using the same process as `/session:save`:
1. Generate timestamp filename: `YYYY-MM-DD_HH-MM.md`
2. Capture:
- Conversation summary (what was accomplished in this session)
- Final completed todos
- Final file changes
- Final state
- Session outcome/results
3. **IMPORTANT**: In the snapshot, add a header line:
```markdown
# FINAL Snapshot: {session_name}
**Timestamp**: {timestamp}
**Session Closed**: This is the final snapshot before session closure
```
4. Include a "Session Outcome" section:
```markdown
## Session Outcome
- Goal: {original_goal_from_session_md}
- Status: {Completed|Partially Completed|In Progress}
- Key Achievements: {list_main_accomplishments}
- Remaining Work: {list_what_still_needs_to_be_done}
```
### Step 5: Update context.md with Final Summary
1. Read `.claude/sessions/{active_session}/context.md`
2. Add a final entry to the "Summary" section:
```markdown
## Session Closure Summary
**Closed**: {current_timestamp}
**Duration**: {duration}
**Outcome**: {Completed|Partially Completed}
### What Was Accomplished
{bullet_list_of_main_accomplishments}
### Final State
{description_of_final_state}
### Next Steps (if resuming later)
{what_to_do_when_session_is_continued}
```
3. Write updated context.md
### Step 6: Update session.md with Closed Status
1. Read `.claude/sessions/{active_session}/session.md`
2. Update these fields:
- **Status**: Change from "Active" to "Closed"
- **Closed**: Add current timestamp
- **Last Updated**: Update to current timestamp
3. Write updated session.md
### Step 7: Clear Active Session
1. Delete or clear the `.claude/sessions/.active-session` file
2. This marks that no session is currently active
### Step 8: Display Closing Summary
Show comprehensive closing summary:
```
✓ Session '{session_name}' closed
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 Session Summary:
Duration: {duration_formatted}
Snapshots: {snapshot_count}
Files modified: {file_count}
Milestones completed: {completed_milestones}/{total_milestones}
Token usage (this conversation): {token_usage_formatted}
🎯 Goal: {original_goal}
✅ Key Achievements:
{list_top_3_to_5_achievements}
📁 Session saved to: .claude/sessions/{session_name}/
💡 Use /session:continue {session_name} to resume later
💡 Use /session:list to see all sessions
```
### Example Output:
```
✓ Session 'feature-auth-system' closed
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 Session Summary:
Duration: 4h 35m
Snapshots: 5
Files modified: 12
Milestones completed: 8/10
Token usage (this conversation): 67.4k
🎯 Goal: Implement OAuth2 authentication system
✅ Key Achievements:
- Implemented Google OAuth provider integration
- Created authentication middleware
- Added token refresh mechanism
- Built user profile synchronization
- Completed security testing
📁 Session saved to: .claude/sessions/feature-auth-system/
💡 Use /session:continue feature-auth-system to resume later
💡 Use /session:list to see all sessions
```
### Step 9: Offer Next Steps
Ask the user:
```
Session closed successfully. Would you like to:
1. Start a new session (/session:start [name])
2. Review another session (/session:list)
3. Continue with other work
```
---
**IMPORTANT**:
- Execute all steps in order
- The final snapshot should be comprehensive - it's the last capture
- Update all metadata files (session.md, context.md)
- Clear active session AFTER all files are updated
- Format output professionally with clear statistics
- Handle errors gracefully (e.g., if session files are missing)
- Token usage should be from current conversation only, not cumulative
- Duration should be accurate based on timestamps
- Provide clear next steps for user

359
commands/continue.md Normal file
View File

@@ -0,0 +1,359 @@
You are managing a session memory system. The user wants to resume an existing session.
**CRITICAL - Command Format:**
All session plugin commands use the `/session:` prefix. DO NOT suggest commands without this prefix.
- ✅ Correct: `/session:list`, `/session:start`, `/session:continue`, `/session:status`
- ❌ Wrong: `/session list`, `/session start`, `/session continue`, `/session status`
Use ONLY the exact command formats specified in this template.
## Task: Continue Existing Session
Parse the session name from the command arguments. The command format is: `/session:continue [name]`
**OPTIMIZATION**: v3.7.0 uses parallel subagent delegation for 72% token reduction (77k → 22k tokens).
### Step 1: Validate Session Exists (CLI)
Extract the session name from arguments, then run:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js get {session_name}
```
If this returns an error (exit code 2), the session doesn't exist. Show:
```
❌ Error: Session '{name}' not found
💡 Use /session:list to see available sessions
💡 Use /session:start {name} to create a new session
```
Then STOP.
The JSON response contains metadata (status, started, snapshotCount, etc.).
### Step 1.5: Close Previous Active Session (If Different)
Before continuing the target session, close any currently active session if it's different:
1. Check if `.claude/sessions/.active-session` exists
2. If it exists:
- Read the current active session name
- If it's different from the target session {session_name}:
- Show: "📋 Closing previous session '{previous_session_name}'..."
- Close the previous session status:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js update-status "{previous_session_name}" "closed"
```
- This marks the previous session as closed in `.auto-capture-state`
3. Continue to next step
**Note**: This ensures clean session transitions with no abandoned active sessions.
### Step 1.8: Calculate Absolute Paths for Subagents
Before delegating to subagents, you need to determine absolute paths that subagents will use.
**IMPORTANT**: Subagents don't inherit the working directory or environment variables from the main conversation. You MUST provide absolute paths explicitly.
Calculate these values (conceptually - don't run bash commands, just determine the values):
- **Working directory**: Current working directory (you already know this from your environment)
- **Plugin root**: `/Users/prajyot/.claude/plugins/marketplaces/automatewithus-plugins/session`
- **Session path**: `{working_directory}/.claude/sessions/{session_name}`
You will substitute these absolute paths into the subagent prompts in the next step.
### Step 2: Delegate Heavy Work to Subagents (Parallel Execution)
**CRITICAL**: You MUST invoke ALL 3 Task tools in a SINGLE response message. This runs them in parallel and isolates heavy token usage from the main conversation.
Use the Task tool to spawn 3 parallel subagents with these exact configurations:
**Subagent 1 - Consolidate Conversation Log:**
- subagent_type: "general-purpose"
- description: "Consolidate conversation log"
- model: "haiku"
- prompt: |
You are working with session: {session_name}
**Absolute paths for this task:**
- Working directory: {working_directory}
- Plugin root: ${CLAUDE_PLUGIN_ROOT}
- Session path: {session_path}
Read the prompt file: ${CLAUDE_PLUGIN_ROOT}/prompts/consolidate-log.md
That file contains template placeholders like "{session_name}", "{session_path}", "${CLAUDE_PLUGIN_ROOT}".
Replace all such placeholders with the actual values provided above.
Then execute the resulting instructions.
**Subagent 2 - Refresh Git History:**
- subagent_type: "general-purpose"
- description: "Refresh git history"
- model: "haiku"
- prompt: |
You are working with session: {session_name}
**Absolute paths for this task:**
- Working directory: {working_directory}
- Plugin root: ${CLAUDE_PLUGIN_ROOT}
- Session path: {session_path}
Read the prompt file: ${CLAUDE_PLUGIN_ROOT}/prompts/refresh-git.md
That file contains template placeholders like "{session_name}", "{session_path}", "${CLAUDE_PLUGIN_ROOT}".
Replace all such placeholders with the actual values provided above.
Then execute the resulting instructions.
**Subagent 3 - Extract Session Goal:**
- subagent_type: "general-purpose"
- description: "Extract session goal"
- model: "haiku"
- prompt: |
You are working with session: {session_name}
**Absolute paths for this task:**
- Working directory: {working_directory}
- Plugin root: ${CLAUDE_PLUGIN_ROOT}
- Session path: {session_path}
Read the prompt file: ${CLAUDE_PLUGIN_ROOT}/prompts/extract-goal.md
That file contains template placeholders like "{session_name}", "{session_path}", "${CLAUDE_PLUGIN_ROOT}".
Replace all such placeholders with the actual values provided above.
Then execute the resulting instructions.
**REMINDER**: All 3 Task invocations MUST be in the SAME response to execute in parallel!
### Step 3: Process Subagent Results
After all 3 subagents complete, you'll receive their results. Handle errors gracefully:
**Consolidation Result**:
- If `success: true` → Snapshot created successfully
- If `skipped: true` → No conversation log found (OK, continue)
- If `success: false` → Log error but continue
**Git Refresh Result**:
- If `success: true` → Git history updated
- If `success: false` → No git repo or error (OK, continue)
**Goal Extraction Result**:
- If `success: true` → Use the extracted goal
- If `success: false` → Use fallback goal from result
### Step 3.5: Extract Full Snapshot Summary (Complete Context Approach)
Provide Claude with complete snapshot summary including all topics, decisions, and tasks for full context visibility using Claude Code tools.
**IMPORTANT**: This step uses Claude Code's Read and Glob tools instead of bash pipelines to avoid parse errors with command substitution.
**Implementation Steps:**
1. **Find the latest snapshot file using Glob tool:**
- Pattern: `.claude/sessions/{session_name}/auto_*.md`
- Glob returns files sorted by modification time (newest first)
- Take the first result as the latest snapshot
2. **If snapshot exists, use Read tool to extract content:**
- Read the snapshot file (first 80 lines should contain all needed sections)
- Extract all snapshot items with titles only:
- **Topics Discussed**: Extract ALL topic titles from "## Topics Discussed" section
- Format: "1. **Category**: Description"
- Extract only the category/title (bold text between ** markers)
- Store as array of titles
- **Decisions Made**: Extract ALL decision titles from "## Decisions Made" section
- Format: "1. **Decision**: Rationale"
- Extract only the decision title (bold text between ** markers)
- Store as array of titles
- **Tasks Completed**: Extract ALL tasks from "## Tasks Completed" section
- Format: "1. Task description"
- Extract full task line (simple numbered list)
- Store as array of tasks
- **Current Status**: Extract status lines from "## Current Status" section
- Look for "- **Progress**:" line and extract text after it
- Look for "- **Next Steps**:" line and extract text after it
- Look for "- **Blockers**:" line and extract text after it
- Store as object with progress, nextSteps, blockers
3. **Build full snapshot summary output:**
```
📋 Latest: {snapshot_filename}
Topics Discussed ({count}):
- {topic_1}
- {topic_2}
... (all topics)
Decisions Made ({count}):
- {decision_1}
- {decision_2}
... (all decisions)
Tasks Completed ({count}):
- {task_1}
- {task_2}
... (all tasks)
Current Status:
• Progress: {progress_text}
• Next Steps: {next_steps_text}
• Blockers: {blockers_text}
💡 Read {snapshot_path} for full details
```
4. **Display the summary in Step 6** (after showing the session goal)
**Graceful Handling**:
- If no snapshot exists → Skip summary display (OK, fresh session)
- If extraction fails → Show generic message "See snapshot for details"
- If Read fails → Silent failure, continue (don't break resume)
**Why Full Snapshot Summary Works Better**:
- Complete visibility: All topics, decisions, and tasks visible immediately (~300 tokens)
- No information loss: User sees everything without needing to read snapshot file
- Better context continuity: Claude knows full scope of work done
- Improved decision-making: All context available for next steps
- **No bash parse errors** - uses Claude Code tools (Glob, Read) natively
### Step 4: Activate Session (CLI)
Run the CLI command to activate the session:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js activate {session_name}
```
This updates both the .active-session file and the index.
### Step 4.5: Update Session Status to Active
Update the session status in `.auto-capture-state` and index:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js update-status "{session_name}" "active"
```
This ensures the session status matches its active state and prevents sync bugs.
### Step 5: Update Last Updated Timestamp
Update the "Last Updated" line in session.md to current time using the Edit tool:
```
**Last Updated**: {current ISO timestamp}
```
### Step 6: Display Summary with Full Snapshot Details
Show session goal plus complete snapshot summary with all topics, decisions, and tasks for full context visibility.
**Implementation**: Use Glob and Read tools (from Step 3.5) to extract and display the full summary.
**Display Format**:
```
✓ Session ready: {goal}
📋 Latest: {snapshot_filename}
Topics Discussed ({count}):
- {topic_1}
- {topic_2}
... (all topics)
Decisions Made ({count}):
- {decision_1}
- {decision_2}
... (all decisions)
Tasks Completed ({count}):
- {task_1}
- {task_2}
... (all tasks)
Current Status:
• Progress: {progress_text}
• Next Steps: {next_steps_text}
• Blockers: {blockers_text}
💡 Read {snapshot_path} for full details
What's next?
```
**Example Output**:
```
✓ Session ready: Implement product permission system
📋 Latest: auto_2025-11-16_05-24.md
Topics Discussed (8):
- Database Schema Design
- API Endpoint Implementation
- Permission Middleware
- Frontend Components
- Testing Strategy
- Deployment Planning
- Documentation Updates
- Performance Optimization
Decisions Made (3):
- Use RBAC Model for Permission System
- Implement Middleware-based Authorization
- Store Permissions in PostgreSQL
Tasks Completed (12):
- Created users, roles, permissions tables
- Implemented role assignment API
- Built permission checking middleware
- Added frontend permission components
- Wrote unit tests for permission logic
- Created integration tests
- Documented API endpoints
- Updated deployment guide
- Fixed TypeScript errors
- Ran build successfully
- Deployed to staging
- Verified permission checks work
Current Status:
• Progress: 12 of 12 tasks completed (100%)
• Next Steps: Deploy to production and monitor
• Blockers: None
💡 Read .claude/sessions/product-permission/auto_2025-11-16_05-24.md for full details
What's next?
```
**Notes**:
- If no snapshot exists, only show "✓ Session ready: {goal}" and "What's next?"
- Use Read tool to extract all items (avoids bash parse errors)
- Fallback gracefully if extraction fails (show generic pointer text)
**IMPORTANT**:
- DO show full snapshot summary (all topics/decisions/tasks) ← FULL VISIBILITY
- This provides complete context in ~300 tokens ← WORTH THE COST
- User doesn't need to read snapshot file separately ← CONVENIENCE
- All relevant context immediately available for decision-making ← BETTER UX
- User can still read snapshot file for additional details if needed
- The heavy analysis already happened in the subagents
- User can run `/session:status` for detailed view
---
**TOKEN OPTIMIZATION BENEFITS:**
- Current: ~20.3k tokens with full snapshot summary (74% reduction from v3.6.4)
- Full snapshot summary with all topics/decisions/tasks (~300 tokens)
- Complete visibility: All snapshot items visible immediately
- Benefit: Complete context for better decision-making and continuity
- Heavy work (consolidation, git analysis) happens in isolated subagent contexts
- Parallel execution: 3 subagents run simultaneously (~2-4 seconds total)
- Lazy-loaded prompts: Subagents read their own prompts (~1.7k token savings)
- Result: Faster session resume, massive token savings, complete context restoration
**ERROR HANDLING:**
- If all subagents fail: Still activate session, show generic message "✓ Session ready. What's next?"
- If session.md missing: Show corrupted session warning
- If CLI fails: Suggest rebuilding index with `/session:rebuild-index`
---
ARGUMENTS: {name}

View File

@@ -0,0 +1,199 @@
You are managing a session memory system. The user wants to resume an existing session.
## Task: Continue Existing Session
Parse the session name from the command arguments. The command format is: `/session continue [name]`
**OPTIMIZATION:** This command uses CLI for validation and metadata (60-70% token reduction).
### Step 1: Validate Session Exists (CLI)
Extract the session name from arguments, then run:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js get {session_name}
```
If this returns an error (exit code 2), the session doesn't exist. Show:
```
❌ Error: Session '{name}' not found
💡 Use /session list to see available sessions
💡 Use /session start {name} to create a new session
```
Then STOP.
The JSON response contains metadata (status, started, goal, snapshotCount, etc.).
### Step 2: Read Session Files
Now read the actual content files (these need full content for context synthesis):
1. Read `.claude/sessions/{name}/session.md`
2. Read `.claude/sessions/{name}/context.md` (if exists)
3. Get latest snapshot filename from the CLI JSON response (`latestSnapshot` field)
4. If `latestSnapshot` exists, read `.claude/sessions/{name}/{latestSnapshot}`
### Step 3: Check for Active Session and Transition (NEW - Session Cleanup)
Before activating the new session, check if there's already a different active session:
1. Check if `.claude/sessions/.active-session` exists
2. If it exists, read the current active session name
3. If the current active session is **different** from the session being continued:
- Show: "📋 Closing previous session '{previous_session_name}'..."
- Update the previous session's `session.md` "Last Updated" timestamp to current time
- This provides clean transition tracking
4. If it's the **same** session, skip this step (just updating timestamp)
**Note:** The SessionEnd hook will handle final cleanup on Claude Code termination.
### Step 4: Activate Session (CLI)
Run the CLI command to activate the session:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js activate {session_name}
```
This updates both the .active-session file and the index.
### Step 5: Update Last Updated Timestamp
Update the "Last Updated" line in session.md to current time using the Edit tool.
### Step 6: Synthesize and Display Context Summary
Using the data from CLI JSON + file contents, show a comprehensive summary:
```
✓ Loaded session: '{name}'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📅 Started: {started from CLI JSON}
🎯 Goal: {goal from CLI JSON or session.md}
📝 Last update: {lastUpdated from CLI JSON}
⏰ Status: {status from CLI JSON}
📸 Snapshots: {snapshotCount from CLI JSON}
## Recent Context
{latest_snapshot_conversation_summary if available}
## Key Files
{list of files from filesInvolved array in CLI JSON}
## Milestones
{key milestones from session.md with checkboxes}
## Recent Decisions
{recent decisions from context.md, max 3}
## Current State
{current state from latest snapshot if available}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Ready to continue! How would you like to proceed?
```
### Step 7: Prepare for Work
Tell the user:
"I've loaded the full context for session '{name}'. All previous work, decisions, and progress have been restored. What would you like to work on next?"
---
**PERFORMANCE BENEFITS:**
- **Before:** 10-20K tokens, reads session.md + context.md + snapshot + metadata parsing, 3-5s
- **After:** 3-8K tokens, CLI provides metadata instantly, only reads content files, 1-2s
- **Improvement:** ~60-70% token reduction, ~2x faster
**WHY STILL READ CONTENT FILES:**
- context.md and snapshots contain narrative context needed for synthesis
- Claude needs full context to provide meaningful summary
- CLI provides structure/metadata, Claude provides intelligence/understanding
**ERROR HANDLING:**
- If session.md missing, show corrupted session warning
- If CLI fails, suggest rebuilding index
- Handle missing context.md or snapshots gracefully (show what's available)
---
## CRITICAL: Check for Unconsolidated Logs (Inline Analysis)
**YOU MUST CHECK THIS BEFORE DISPLAYING THE SESSION SUMMARY:**
When resuming a session, check if the previous session left unconsolidated logs:
1. Check if `.claude/sessions/{name}/conversation-log.jsonl` exists
2. If the file exists:
- Show brief message: "📊 Analyzing previous session... (this may take 1-3 seconds)"
- Read the conversation log file
- Parse interactions from JSONL format
- **Parse self-contained conversation log (v3.6.2+):**
- Each entry has type: 'interaction' (user prompt) or 'assistant_response' (Claude's response)
- Extract full conversation from log entries:
- User prompts: `user_prompt` field in 'interaction' entries
- Claude responses: `response_text` field in 'assistant_response' entries
- Tools used: `tools_used` field in 'assistant_response' entries
- File modifications: `modified_files` field in 'interaction' entries
- Log is self-contained - NO need to read transcript file!
- **Backward compatibility**: If `transcript_path` exists but no `response_text`, fall back to reading transcript file (for v3.6.1 logs)
- **Capture git history (if available):**
- Run: `node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js capture-git "{name}"`
- This creates `.claude/sessions/{name}/git-history.json` (~2-3KB compressed)
- Contains: last 50 commits, uncommitted changes, branch status, hotspots
- Performance: ~60-90ms (acceptable at session boundary)
- If no git repo, command returns success: false (silent skip, no error)
- **Analyze the conversation with Claude inline:**
- Use the full conversation from log entries (user prompts + Claude responses)
- Extract conversation summary (2-3 paragraphs covering what happened)
- Identify key decisions made with rationale
- List completed todos/tasks
- Document files modified with context about what changed and why (from conversation, not just file paths)
- Assess current state, what's next, and any blockers
- Create consolidated snapshot via CLI:
```bash
echo "# Consolidated Snapshot: {session_name}
**Timestamp**: {ISO timestamp}
**Method**: Claude Inline Analysis (Free)
**Status**: Consolidated from conversation log
## Conversation Summary
{2-3 paragraph summary of what happened in session}
## Key Decisions
- {Decision 1 with rationale}
- {Decision 2 with rationale}
## Completed Tasks
- {Task 1}
- {Task 2}
## Files Modified
- {file_path}: {what changed and why}
## Current State
{Where things stand, what's next, blockers}
## Notes
Consolidated via Claude inline analysis at session boundary. Zero cost, highest quality." | node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js write-snapshot "{name}" --stdin --type auto
```
- Delete conversation-log.jsonl after successful snapshot creation
- Update `.auto-capture-state` to reset counters and set last_snapshot_timestamp
3. If no log exists:
- **Still capture git history** for updated repository context:
- Run: `node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js capture-git "{name}"`
- This refreshes git context since last session
- Silent skip if no git repo (no error)
**PERFORMANCE:**
- Log check: <5ms
- Claude analysis: 1-3s (acceptable at session boundaries - users expect loading)
- Snapshot write: <50ms
- Log deletion: <5ms
- **Total: ~1-3 seconds** (users expect loading at session resume)
**NOTE:** This is the v3.5.1 architecture where:
- During session: Conversation logged incrementally (<2ms per interaction, zero blocking)
- At session boundaries: Claude inline analysis creates intelligent snapshots (FREE, highest quality)
- Result: User NEVER experiences blocking during work, only brief wait at session resume where loading is expected

207
commands/delete.md Normal file
View File

@@ -0,0 +1,207 @@
You are managing a session memory system. The user wants to delete a session permanently.
## Task: Delete Session
Delete a session and all its data. This action cannot be undone.
**IMPORTANT:** This is a destructive operation. Always confirm with the user before deleting.
---
## Step 1: Parse Arguments
Check if user provided a session name:
- If user provided a session name (e.g., `/session:delete old-feature`) → Use that name
- If no name provided → Show error and list available sessions for reference
If no session name provided:
```
❌ Session name required.
Usage: /session:delete [session-name]
Available sessions: /session:list
```
Then STOP.
---
## Step 2: Get Session Details
Run the CLI command to get session information:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js get [session-name]
```
If the command fails (session not found), display:
```
❌ Session '[session-name]' not found.
Available sessions: /session:list
```
Then STOP.
---
## Step 3: Check If Active Session
Check if this is the currently active session by running:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js list --json
```
Parse the JSON and check if `activeSession === session-name`.
---
## Step 4: Show Confirmation Prompt
Use the AskUserQuestion tool to confirm deletion.
### If NOT the active session:
```json
{
"questions": [
{
"question": "⚠️ Delete Session: [session-name]\n\n📅 Started: [started]\n📸 Snapshots: [count]\n📁 Files Involved: [count]\n\nThis will permanently delete all session data.\n\nAre you sure you want to delete this session?",
"header": "Confirm Delete",
"multiSelect": false,
"options": [
{
"label": "Yes, Delete",
"description": "Permanently delete this session and all its data"
},
{
"label": "No, Cancel",
"description": "Keep the session and go back"
}
]
}
]
}
```
### If IS the active session:
```json
{
"questions": [
{
"question": "⚠️ WARNING: Deleting ACTIVE Session!\n\n'[session-name]' is your currently active session.\n\n📅 Started: [started]\n📸 Snapshots: [count]\n📁 Files Involved: [count]\n\nDeleting this will:\n- End your current working session\n- Delete all snapshots and context\n- Clear the active session\n\nThis cannot be undone.\n\nAre you ABSOLUTELY SURE?",
"header": "Delete Active",
"multiSelect": false,
"options": [
{
"label": "Yes, Delete Active Session",
"description": "I understand this will end my active session"
},
{
"label": "No, Cancel",
"description": "Keep the session and go back"
}
]
}
]
}
```
---
## Step 5: Handle User Response
### If user selected "No, Cancel":
```
Session deletion cancelled.
```
Then STOP.
### If user selected "Yes" (or "Yes, Delete Active Session"):
Proceed to Step 6.
---
## Step 6: Execute Deletion
Run the CLI delete command:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js delete [session-name]
```
The CLI will:
- Delete the session directory and all files
- Remove from index
- Clear active session if needed
---
## Step 7: Display Result
Parse the JSON response from the delete command.
### If successful:
**For regular session:**
```
✅ Session '[session-name]' has been deleted.
📊 Deleted:
- [count] snapshots
- [count] files tracked
💡 View remaining sessions: /session:list
```
**For active session:**
```
✅ Session '[session-name]' has been deleted.
📊 Deleted:
- [count] snapshots
- [count] files tracked
⚠️ No active session. Start a new one:
/session:start [name]
💡 View remaining sessions: /session:list
```
### If error occurred:
```
❌ Error deleting session: [error message]
Try rebuilding the index:
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js update-index --full-rebuild
```
---
## Error Handling
- **Session not found:** Show available sessions list
- **Permission error:** Show clear error message about file permissions
- **Active session:** Show extra warning and confirmation
- **CLI error:** Show error and suggest index rebuild
---
## Performance
- **Single confirmation:** < 300 tokens
- **CLI deletion:** < 50ms for small sessions, < 500ms for large sessions
- **Total time:** 1-2 seconds including user confirmation
---
## Safety Features
1.**Always requires confirmation** - No accidental deletions
2.**Shows what will be deleted** - User knows the impact
3.**Extra warning for active session** - Prevents losing current work
4.**Clear feedback** - User knows what happened
5.**Graceful error handling** - Helpful messages on failure

124
commands/git-decompress.md Normal file
View File

@@ -0,0 +1,124 @@
You are managing a session memory system. The user wants to decompress git history for human inspection.
## Task: Decompress Git History
Parse the session name from the command arguments. The command format is: `/session:git-decompress [name]`
### Step 1: Validate and Read Compressed File
1. Extract session name from arguments
2. Check if `.claude/sessions/{name}/git-history.json` exists
3. If not exists, show:
```
❌ Error: No git history found for session '{name}'
💡 Git history is captured automatically at session start/continue
💡 Or run: /session:capture-git {name}
```
Then STOP.
4. Read `.claude/sessions/{name}/git-history.json`
5. Parse JSON into object
### Step 2: Expand into Human-Readable Format
Display the expanded markdown format:
```markdown
# Git History: {s}
**Captured**: {t}
**Branch**: {b}
**HEAD**: {h}
## Summary
- **Commits analyzed**: {sm.n}
- **Date range**: {sm.r}
- **Days span**: {sm.d}
- **Total files modified**: {sm.f}
- **Total changes**: {sm.ch}
## Uncommitted Changes
### Tracking Status
- **Ahead of upstream**: {uc.ah} commits
- **Behind upstream**: {uc.bh} commits
### Staged for Commit ({uc.stg.length} files)
{for each file in uc.stg:}
- `{file[0]}`: {file[1]}
### Modified (Unstaged) ({uc.mod.length} files)
{for each file in uc.mod:}
- `{file[0]}`: {file[1]}
### New Files (Untracked) ({uc.new.length} files)
{for each file in uc.new:}
- `{file}`
### Deleted Files ({uc.del.length} files)
{for each file in uc.del:}
- `{file}`
### Conflicted Files ({uc.con.length} files)
{for each file in uc.con:}
- `{file}`
**Total uncommitted changes**: {uc.tot}
## Recent Commits
{for each commit in c:}
### {commit[0]} - {commit[1]}
**Message**: {commit[2]}
**Changes**: {commit[3]}
**Files modified** ({commit[4]}):
{for each file in commit[5]:}
- `{file}`
---
## Development Hotspots
Shows directories with most commit activity:
{for each hotspot in hot:}
- **{hotspot[0]}**: {hotspot[1]} commits
---
**Note**: This is a decompressed view of the compressed JSON format used for token efficiency. The compressed format saves ~70-75% tokens compared to markdown while preserving all information.
```
### Step 3: Display Statistics
After showing the decompressed data, display:
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 Decompression Statistics
Compressed size: {fileSize} bytes ({fileSizeKB} KB)
Estimated markdown size: ~{estimatedMarkdownSize} bytes (~{estimatedMarkdownKB} KB)
Compression efficiency: ~{compressionPercent}% smaller
Token efficiency: Compressed JSON uses ~70-75% fewer tokens than markdown
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```
---
## Usage Notes
- This command is primarily for debugging and human inspection
- Claude can read the compressed format directly (it's more efficient)
- Use this when you need to:
- Verify git history capture is working correctly
- Inspect what commits are included
- Debug git context issues
- Share git history in readable format
---
## Error Handling
- If git-history.json doesn't exist: Show helpful error with instructions
- If JSON is malformed: Show parsing error and suggest recapture
- If file is empty: Suggest running capture-git again

231
commands/list.md Normal file
View File

@@ -0,0 +1,231 @@
You are managing a session memory system. The user wants to see all available sessions.
## Task: List All Sessions (Enhanced with Interactive Selection)
Display all sessions with enhanced metadata in a clean, organized format. Optionally enable interactive selection mode.
**OPTIMIZATION:** This command uses the lightweight CLI tool for instant metadata retrieval (< 10ms, < 200 tokens).
---
## Step 1: Detect Mode
Check if user provided arguments:
- If user provided a **number** (e.g., `/session:list 2`) → Jump to **Step 5: Handle Selection**
- If user typed `/session:list` with no args → Continue to Step 2 (display mode)
---
## Step 2: Get Session List from CLI
Run the CLI command to get all session metadata:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js list
```
This returns JSON with all session data from the index (no file reading needed).
---
## Step 3: Handle Empty Sessions
If the JSON shows `totalSessions: 0`, display:
```
No sessions found.
💡 Create your first session with:
/session:list [name]
Example:
/session:start my-feature
```
Then STOP.
---
## Step 4: Format and Display Sessions (Enhanced)
Parse the JSON response and format with **enhanced visual design**:
### Calculate Stats:
- Count active vs closed sessions
- Calculate relative times (use helper function below)
- Determine activity status for badges
### Display Format:
```
Available Sessions ({activeCount} active, {closedCount} closed):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
{for each session in sessions array:}
{number}. {name} {badges}
📅 {relativeTime} (started {relativeStartTime}) 📸 {snapshotCount} snapshots 📁 {filesInvolvedCount} files
🎯 {goal}
{if latestSnapshotSummary exists: show "💬 Last: \"{latestSnapshotSummary}\""}
{Add TWO blank lines between sessions for clear visual separation}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
💡 Select a session: /session:list [number]
💡 Create new: /session:start [name]
```
### Badges Logic:
- If `session.name === activeSession`: Show `[ACTIVE] 🔥`
- If `status === "closed"`: Show `✅ CLOSED`
- If last update > 7 days and not closed: Show `🧊 COLD`
- If last update < 1 hour: Show `🔥 HOT`
### Relative Time Helper:
Calculate relative time for display:
- < 1 minute: "just now"
- < 60 minutes: "{n}m ago"
- < 24 hours: "{n}h ago"
- < 7 days: "{n}d ago"
- < 30 days: "{n}w ago"
- >= 30 days: "{n} months ago"
### Example Output:
```
Available Sessions (2 active, 1 closed):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. feature-auth-system [ACTIVE] 🔥 HOT
📅 2h ago (started 3d ago) 📸 5 snapshots 📁 12 files
🎯 Implement OAuth2 authentication system
💬 Last: "Completed login flow, testing redirect logic"
2. bugfix-login-issue ✅ CLOSED
📅 1d ago (started 2d ago) 📸 3 snapshots 📁 4 files
🎯 Fix session timeout bug in login flow
3. refactor-api-layer 🧊 COLD
📅 14d ago (started 15d ago) 📸 8 snapshots 📁 23 files
🎯 Refactor REST API to GraphQL architecture
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
💡 Select a session: /session:list [number]
💡 Create new: /session:start [name]
```
After displaying, **STOP and wait for user input**. Do not prompt further.
---
## Step 5: Handle Selection (Interactive Mode)
If user provided a number (e.g., `/session:list 2`), this is interactive selection mode.
### 5.1: Validate Selection
1. Get session list again (same CLI command)
2. Check if number is valid (1 to totalSessions)
3. If invalid, show error and STOP:
```
❌ Invalid selection. Please choose 1-{totalSessions}.
```
### 5.2: Show Session Details
Display the selected session with full details:
```
Selected Session: {name}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📋 Status: {status} {badges}
📅 Started: {started}
📅 Last Update: {lastUpdated}
📸 Snapshots: {snapshotCount}
📁 Files Involved: {filesInvolvedCount}
🎯 Goal:
{goal}
{if latestSnapshotSummary:}
💬 Latest Snapshot:
{latestSnapshotSummary}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```
### 5.3: Use AskUserQuestion Tool
Present action options using the AskUserQuestion tool:
```json
{
"questions": [
{
"question": "What would you like to do with this session?",
"header": "Action",
"multiSelect": false,
"options": [
{
"label": "Continue/Resume",
"description": "Load session context and continue working"
},
{
"label": "View Status",
"description": "Show detailed session statistics and state"
},
{
"label": "Save Snapshot",
"description": "Capture current conversation as a snapshot"
},
{
"label": "Close Session",
"description": "Finalize and close this session"
},
{
"label": "Delete Session",
"description": "Permanently delete this session and all its data"
},
{
"label": "Back to List",
"description": "Return to session list"
}
]
}
]
}
```
### 5.4: Execute Selected Action
Based on user's choice, execute the appropriate command:
- **Continue/Resume** → Run: `/session:continue {sessionName}`
- **View Status** → Run: `/session:status` (after activating if needed)
- **Save Snapshot** → Run: `/session:save`
- **Close Session** → Run: `/session:close`
- **Delete Session** → Run: `/session:delete {sessionName}`
- **Back to List** → Run: `/session:list` (restart from Step 2)
**Important:** Actually execute the command, don't just tell the user to run it.
---
## Error Handling
If CLI command fails, show:
```
❌ Error reading sessions. Try rebuilding the index:
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js update-index --full-rebuild
```
---
## Performance Benefits
- **Display Mode:** < 200 tokens, < 50ms
- **Selection Mode:** ~300-500 tokens total
- **No file reads** for list display (index only)
- **95-98% token reduction** vs old approach

195
commands/plan-execute.md Normal file
View File

@@ -0,0 +1,195 @@
You are executing the /session:plan-execute command to start executing a plan.
**NOTE:** Plans are now global and independent of sessions.
**CRITICAL - Command Format:**
All session plugin commands use the `/session:` prefix. DO NOT suggest commands without this prefix.
- ✅ Correct: `/session:plan-execute`, `/session:plan-status`, `/session:plan-finalize`, `/session:plan-list`
- ❌ Wrong: `/plan-execute`, `/plan-status`, `/plan-show`, `/plan-list`
Use ONLY the exact command formats specified in this template.
## Arguments
Parsed from user input:
- `plan_name`: {name} (required)
ARGUMENTS: {name}
## Workflow
### Step 1: Validate Plan Exists
Plans are stored globally in `.claude/plans/`. Check if the plan exists:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js plan-exists {plan_name}
```
If the plan doesn't exist, show error and STOP:
```
❌ Error: Plan '{plan_name}' not found
Use /session:save-plan {name} to create a plan first.
Use /session:plan-list to see available plans.
```
### Step 2: Validate Plan Format
Before executing, verify the plan is in implementation format (not conceptual):
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js get-plan-format {plan_name}
```
This returns JSON with `format: "conceptual"` or `format: "implementation"`.
If the format is "conceptual", show this error and STOP:
```
❌ Error: Cannot execute conceptual plan
Plan '{plan_name}' is still in conceptual format (requirements only).
You must finalize the plan first to transform requirements into executable tasks:
/session:plan-finalize {plan_name}
This will use AI to break down requirements into concrete implementation tasks
organized by phases (Database, API, UI, Testing, etc.)
After finalization, you can execute the plan.
```
If the format is "implementation", continue to next step.
### Step 4: Load Plan Status
Get the current plan status to show what will be executed:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js plan-status {session_name} {plan_name}
```
This returns JSON with plan metadata, progress, and current phase.
### Step 5: Show Execution Overview
Display a summary of what will be executed:
```
📋 Plan: {plan_name}
Goal: {goal}
Progress: {completed_tasks}/{total_tasks} tasks ({percentage}%)
Status: {status}
Phases:
1. [✓] Phase 1: {name} (completed)
2. [→] Phase 2: {name} (in progress - will continue here)
3. [ ] Phase 3: {name} (pending)
4. [ ] Phase 4: {name} (pending)
Current Phase: {current_phase_name}
Next Task: {next_task_description}
Ready to execute this plan?
```
### Step 6: Execution Strategy
**IMPORTANT**: Plan execution is currently **manual** with task tracking:
1. Show the user the next task to work on
2. The user implements the task manually
3. After completing a task, update its status:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js update-task-status {session_name} {plan_name} {task_id} completed
```
4. Show progress after each task completion
5. Repeat until all tasks are completed
### Step 7: Display Current Task
Show the next task that needs to be completed:
```
🎯 Next Task: {task_id}
Phase: {phase_name}
Task: {task_description}
Details:
{task_details}
Technical Notes:
- {note_1}
- {note_2}
Dependencies: {dependencies} (all completed ✓)
---
To mark this task as complete when done:
/update-task-status {task_id} completed
To see overall progress:
/session:plan-status {plan_name}
To continue to next task:
Just complete the current task and I'll show you the next one.
```
### Step 8: Task Completion Loop
After the user completes work:
1. Ask: "Have you completed task {task_id}?"
2. If yes, update task status:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js update-task-status {session_name} {plan_name} {task_id} completed
```
3. Show updated progress
4. Load next task
5. If more tasks exist, show next task (Step 6)
6. If all tasks complete, show completion message (Step 8)
### Step 9: Completion Message
When all tasks are completed:
```
🎉 Plan Complete: {plan_name}
All tasks completed successfully!
Summary:
- Total Tasks: {total_tasks}
- Completed: {total_tasks} (100%)
- Phases: {total_phases}
- Time Tracked: {duration}
Next Steps:
1. Review all changes
2. Run tests if applicable
3. Create a pull request
4. Deploy to production
Use /session:save to capture this milestone!
```
---
## Notes
- The execution is **manual** - Claude doesn't automatically execute code
- Users implement tasks themselves, Claude tracks progress
- This provides visibility and structure without automation
- Future: Automated task execution with agent orchestration
---
## Error Handling
At each step, handle errors gracefully:
- Plan not found: Show clear message with available plans
- Invalid task ID: Show valid task IDs for current phase
- Session errors: Guide user to start/continue session

403
commands/plan-finalize.md Normal file
View File

@@ -0,0 +1,403 @@
You are executing the /session:plan-finalize command to transform requirements into executable tasks.
**NOTE:** Plans are now global and independent of sessions.
**CRITICAL - Command Format:**
All session plugin commands use the `/session:` prefix. DO NOT suggest commands without this prefix.
- ✅ Correct: `/session:plan-execute`, `/session:plan-status`, `/session:plan-finalize`
- ❌ Wrong: `/plan-execute`, `/plan-status`, `/plan-show`
Use ONLY the exact command formats specified in this template.
## Arguments
Parsed from user input:
- `plan_name`: {name} (required)
ARGUMENTS: {name}
## Purpose
This is the TRANSFORMATION step that bridges conceptual planning and execution:
**Before (Conceptual - requirements.json):**
```
Requirements (WHAT):
- "Restrict products based on user permissions"
- "Track who created each product"
```
**After (Implementation - orchestration.json + phases/):**
```
Phase 1: Database Layer
✓ task-1-1: Add restriction_level column to public.new_product table
✓ task-1-2: Create migration script for ALTER TABLE
✓ task-1-3: Add created_by column with foreign key to users
Phase 2: API Layer
✓ task-2-1: Add validation in POST /api/products endpoint
✓ task-2-2: Add validation in PUT /api/products/:id endpoint
✓ task-2-3: Return 403 error for restricted products
Phase 3: UI Layer
✓ task-3-1: Add restriction checkbox in product form
✓ task-3-2: Show error message when restriction fails
```
**This step uses AI to break down requirements into concrete, actionable tasks.**
## Workflow
### Step 1: Load Plan and Validate Format
Plans are global and stored in `.claude/plans/`. Check what format the plan is in:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js get-plan-format {plan_name}
```
This returns `format: "conceptual"` or `format: "implementation"`.
**If format is "implementation":**
```
✓ Plan '{plan_name}' is already finalized
This plan has already been transformed into executable tasks.
Use /session:plan-execute {plan_name} to start implementation.
```
Then STOP.
**If format is "conceptual":** Continue to next step.
### Step 2: Load Requirements
Load the requirements.json file from the global plans directory:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js load-requirements {plan_name}
```
This returns the requirements data:
```json
{
"goal": "...",
"requirements": [
{ "id": "req-1", "description": "...", "priority": "high" },
{ "id": "req-2", "description": "...", "priority": "medium" }
],
"metadata": { "work_type": "feature" }
}
```
### Step 4: Show Requirements Summary
Display what will be transformed:
```
📋 Plan: {plan_name}
Goal: {goal}
Format: Conceptual (requirements)
Requirements to Transform:
1. req-1: {description} [{priority}]
2. req-2: {description} [{priority}]
... ({total} requirements)
Work Type: {work_type}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
💡 Finalization Process:
I will use AI to break down each requirement into concrete implementation tasks,
organized by phases (Database, API, UI, Testing, etc.)
This transformation will:
• Convert high-level requirements into actionable tasks
• Organize tasks by implementation layer
• Add implementation details (SQL, API endpoints, UI components)
• Track which requirement led to which tasks
• Create execution-ready plan structure
Ready to proceed? (yes/no)
```
### Step 5: Get User Confirmation
Use the AskUserQuestion tool to confirm.
If user says no/cancel, show:
```
Plan finalization cancelled. The plan remains in conceptual format.
```
Then STOP.
If yes, continue.
### Step 6: AI-Powered Task Breakdown
Show progress indicator:
```
🤖 AI Analysis in Progress...
This will take 30-60 seconds.
```
Invoke the Task tool with:
- subagent_type: "general-purpose"
- model: "sonnet" (use sonnet for better quality breakdown)
- prompt: Read the file at `${CLAUDE_PLUGIN_ROOT}/prompts/breakdown-requirement.md`, replace `[REQUIREMENTS JSON INSERTED HERE]` with the actual requirements JSON, then execute those instructions
The subagent will analyze requirements and return structured breakdown:
```json
{
"implementation_goal": "...",
"phases": [
{
"name": "Database Layer",
"description": "...",
"tasks": [
{
"description": "Add restriction_level column to products",
"details": "ALTER TABLE products ADD COLUMN...",
"from_requirement": "req-1"
}
]
}
],
"traceability": {
"req-1": ["task-1-1", "task-2-1", "task-3-1"],
"req-2": ["task-1-2", "task-2-2"]
},
"assumptions": [...],
"risks": [...]
}
```
### Step 7: Show Transformation Preview
Display the AI-generated breakdown for user review:
```
✓ AI Analysis Complete
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📋 Transformation Preview
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Implementation Goal:
{implementation_goal}
Phase 1: {phase_1_name}
• task-1-1: {description}
• task-1-2: {description}
• task-1-3: {description}
[{task_count} tasks]
Phase 2: {phase_2_name}
• task-2-1: {description}
• task-2-2: {description}
[{task_count} tasks]
Phase 3: {phase_3_name}
• task-3-1: {description}
[{task_count} tasks]
[Show all phases]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Summary:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Requirements: {requirement_count}
• Phases: {phase_count}
• Tasks: {task_count}
• Traceability: Complete (all tasks mapped to requirements)
Assumptions:
- {assumption_1}
- {assumption_2}
Risks:
- {risk_1}
- {risk_2}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Does this breakdown look good? (yes/edit/cancel)
```
### Step 8: Handle User Response
**If "yes":** Continue to Step 9
**If "edit":**
```
What would you like to modify?
You can:
a) Adjust task descriptions
b) Add/remove tasks
c) Change phase organization
d) Add more details to specific tasks
e) Re-run AI analysis with different focus
Your choice:
```
Based on user input, make modifications and show preview again (repeat Step 7).
**If "cancel":**
```
Finalization cancelled. Plan remains in conceptual format.
```
STOP.
### Step 9: Transform and Save
Show progress:
```
💾 Transforming plan...
Creating implementation structure...
```
Call the transformation function:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js transform-plan {plan_name} '{breakdown_json}'
```
This will:
1. Create orchestration.json with metadata and phase registry
2. Create phases/*.json files with tasks
3. Create execution-state.json for progress tracking
4. Keep requirements.json for traceability
5. Mark plan as "implementation" type
### Step 10: Success Message
```
✓ Plan Finalized: {plan_name}
Requirements successfully transformed into executable implementation plan!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Transformation Summary:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Input:
• Format: Conceptual (requirements)
• Requirements: {requirement_count}
Output:
• Format: Implementation (orchestration + phases)
• Phases: {phase_count}
• Tasks: {task_count}
• Structure: Optimized for parallel execution
Files Created:
• orchestration.json (coordinator)
• phases/phase-1-{name}.json
• phases/phase-2-{name}.json
• phases/phase-3-{name}.json
• execution-state.json (progress tracking)
Preserved:
• requirements.json (for traceability)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Next Steps:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Review the finalized plan:
/session:plan-status {plan_name}
2. Start execution:
/session:plan-execute {plan_name}
3. Track progress as you implement each task
🎯 Ready for implementation!
```
---
## Transformation Details
### File Structure
**Before (Conceptual):**
```
plans/{plan_name}/
├── requirements.json (only file)
└── conversation-context.md (reference)
```
**After (Implementation):**
```
plans/{plan_name}/
├── requirements.json (preserved for traceability)
├── orchestration.json (coordinator + metadata)
├── phases/
│ ├── phase-1-database.json
│ ├── phase-2-api.json
│ └── phase-3-ui.json
├── execution-state.json (runtime progress)
└── conversation-context.md (reference)
```
### Traceability
Every task in the implementation plan has a `from_requirement` field:
```json
{
"task_id": "task-1-1",
"description": "Add restriction_level column",
"from_requirement": "req-1"
}
```
This allows you to trace back from implementation tasks to original requirements.
### Why AI-Powered?
Breaking down requirements into tasks requires:
- Understanding of technical architecture (DB → API → UI)
- Knowledge of implementation patterns
- Ability to infer specific tasks from general requirements
- Context about dependencies and ordering
AI excels at this transformation, turning:
- "Restrict products" → 10+ specific tasks across layers
- "Track creators" → Database schema, API logic, UI display
### Quality Assurance
The AI breakdown is trained to:
- Create concrete, actionable tasks (not vague)
- Provide implementation details (SQL, file paths, logic)
- Organize by architectural layers
- Specify dependencies correctly
- Estimate token usage realistically
---
## Error Handling
- **Plan not found**: Show available plans
- **Already finalized**: Show success, suggest execution
- **Invalid session**: Guide to start/continue
- **AI breakdown fails**: Offer retry or manual task creation
- **User cancels**: Keep conceptual format, can retry later
---
## Notes
- Finalization is REQUIRED to execute a plan
- AI breakdown takes 30-60 seconds (uses Sonnet for quality)
- User can review and modify before saving
- Original requirements.json is preserved for traceability
- Transformation is reversible (can re-finalize if needed)
- This is where requirements (WHAT) become tasks (HOW)

148
commands/plan-list.md Normal file
View File

@@ -0,0 +1,148 @@
You are executing the /session:plan-list command to list all global plans.
**NOTE:** Plans are now global and stored in `.claude/plans/`. This command works without requiring an active session.
**CRITICAL - Command Format:**
All session plugin commands use the `/session:` prefix. DO NOT suggest commands without this prefix.
- ✅ Correct: `/session:plan-execute`, `/session:plan-status`, `/session:plan-finalize`, `/session:plan-list`
- ❌ Wrong: `/plan-execute`, `/plan-status`, `/plan-show`, `/plan-list`
Use ONLY the exact command formats specified in this template.
## Arguments
No arguments required.
ARGUMENTS:
## Workflow
### Step 1: List All Global Plans
Get the list of all plans from the global plans directory:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js plan-list
```
This returns JSON:
```json
{
"success": true,
"data": {
"plans": ["plan-1", "plan-2", "plan-3"],
"count": 3
},
"message": "Found 3 plan(s)"
}
```
### Step 2: Get Details for Each Plan
For each plan in the list, get its format and basic metadata:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js get-plan-format {plan_name}
```
This tells you if it's "conceptual" (requirements only) or "implementation" (executable tasks).
Optionally, for implementation plans, get status:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js plan-status {plan_name}
```
### Step 3: Display Plan List
Show a formatted list of all plans:
```
📋 Global Plans ({count} total)
Conceptual Plans (Requirements Only):
1. api-redesign
├─ Goal: Redesign API for better performance
├─ Requirements: 12
├─ Created: 3 days ago
└─ Next: Use /session:plan-finalize api-redesign to create executable tasks
2. user-permissions
├─ Goal: Implement role-based permissions system
├─ Requirements: 8
├─ Created: 1 week ago
└─ Next: Use /session:plan-finalize user-permissions to create executable tasks
Implementation Plans (Executable):
3. oauth-implementation (feature)
├─ Progress: 15/22 tasks (68%)
├─ Status: in-progress
├─ Current: Phase 2 - OAuth Flow Implementation
└─ Last Updated: 2 hours ago
4. database-migration (refactor)
├─ Progress: 8/8 tasks (100%)
├─ Status: completed
└─ Completed: 1 day ago
Helpful Commands:
/session:plan-status {name} - Show detailed plan status
/session:plan-execute {name} - Start/continue plan execution
/session:plan-finalize {name} - Transform conceptual plan to executable
/session:save-plan {name} - Create a new plan
```
### Step 4: Handle Empty Case
If no plans exist, show:
```
📋 No plans found
You haven't created any plans yet.
Get started:
1. Have a conversation about what you want to build
2. Run /session:save-plan {name} to capture requirements
3. Run /session:plan-finalize {name} to create executable tasks
4. Run /session:plan-execute {name} to start implementation
💡 Plans are global and accessible from any session.
```
---
## Display Formatting
### Plan Type Indicators
- 📝 Conceptual (requirements captured, not yet broken down into tasks)
- ⚙️ Implementation (executable tasks, ready to execute)
### Status Icons
- ✓ Completed
- → In Progress
- ○ Pending
- ⊘ Blocked
### Progress Bars
For implementation plans with progress:
```
Progress: [████████████░░░░░░░░] 68% (15/22 tasks)
```
---
## Error Handling
- No plans directory: Show empty state message
- Corrupted plan files: Skip and show warning for specific plan
- CLI command failures: Show error message with suggestion to run /session:rebuild-index
---
## Notes
- This command does NOT require an active session
- Plans are stored globally in `.claude/plans/`
- Both conceptual and implementation plans are shown
- The list is sorted by last updated (most recent first)
- Use /session:plan-status {name} for detailed information about a specific plan

285
commands/plan-save.md Normal file
View File

@@ -0,0 +1,285 @@
You are executing the /session:save-plan command to create a conceptual plan from the current conversation.
**CRITICAL - Command Format:**
All session plugin commands use the `/session:` prefix. DO NOT suggest commands without this prefix.
- ✅ Correct: `/session:plan-execute`, `/session:plan-status`, `/session:plan-finalize`, `/session:plan-list`, `/session:save-plan`
- ❌ Wrong: `/plan-execute`, `/plan-status`, `/plan-show`, `/plan-list`, `/save-plan`
Use ONLY the exact command formats specified in this template.
## Arguments
Parsed from user input:
- `plan_name`: {name} (required)
ARGUMENTS: {name}
## Workflow
### Step 1: Check for Active Session (Optional)
Plans are now global and don't require a session. However, if there's an active session, we can extract requirements from the conversation.
Check for active session:
```bash
[ -f .claude/sessions/.active-session ] && cat .claude/sessions/.active-session || echo "none"
```
- If result is "none": Skip Steps 2-3, create an empty plan with placeholder requirements (go to Step 4)
- If there's an active session: Continue to Step 2 to extract from conversation
### Step 2: Read Conversation Log (If Session Active)
**Only execute this step if there's an active session.**
Load the conversation log for the active session. The conversation log file is at:
`.claude/sessions/{session_name}/conversation-log.jsonl`
**Chunked Reading Strategy:**
1. Check if file exists
2. Count lines: `wc -l .claude/sessions/{session_name}/conversation-log.jsonl`
3. If <= 2000 lines: Read entire file
4. If > 2000 lines: Read in chunks of 2000 using Read tool's offset/limit parameters
5. Concatenate all chunks into full conversation log
If the file doesn't exist or is empty:
- Show warning: "⚠️ No conversation log found. Creating empty plan template."
- Continue to Step 4 with empty requirements
### Step 3: Detect Work Type (Optional - If Session Active)
Detect the work type from the conversation for metadata purposes:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js detect-work-type {session_name}
```
This returns a JSON object with:
```json
{
"type": "feature|bug|spike|refactor|unknown",
"confidence": 87,
"scores": {...},
"signals": {...}
}
```
Show the detection result:
```
🔍 Analyzing conversation...
✓ Detected work type: {TYPE} ({confidence}% confidence)
```
This is for metadata only - conceptual plans don't use templates.
### Step 4: Extract Requirements from Conversation
Use a subagent to analyze the conversation and extract requirements (not tasks!).
Invoke the Task tool with:
- subagent_type: "general-purpose"
- model: "haiku"
- prompt: Read the file at `${CLAUDE_PLUGIN_ROOT}/prompts/analyze-conversation.md`, replace placeholders with actual values, then execute those instructions
The subagent will return extracted requirements:
```json
{
"goal": "High-level objective",
"requirements": [
{
"id": "req-1",
"description": "What the user wants (high-level)",
"notes": "Additional context",
"open_questions": ["Question 1", "Question 2"],
"priority": "high|medium|low",
"conversation_context": "Relevant conversation excerpts"
}
],
"discussion_notes": "Free-form notes from planning discussion",
"conversation_summary": "Summary of conversation"
}
```
**IMPORTANT:** Extract REQUIREMENTS (what user wants), NOT tasks (how to implement).
- ✓ Good requirement: "Restrict products based on user permissions"
- ✗ Bad (too detailed): "Add restriction_level column to public.new_product table"
Requirements are exploratory and high-level during planning.
### Step 4: Build Requirements Plan
Create the requirements.json structure:
```json
{
"plan_name": "{plan_name}",
"plan_type": "conceptual",
"goal": "{extracted_goal_or_placeholder}",
"requirements": [...extracted_requirements_or_empty],
"discussion_notes": "{discussion_notes_or_empty}",
"conversation_summary": "{conversation_summary_or_empty}",
"created_at": "{ISO_8601_timestamp}",
"metadata": {
"work_type": "{detected_work_type_or_unknown}",
"estimated_complexity": "simple|moderate|complex",
"source_session": "{session_name_if_available_else_null}"
}
}
```
**Note:** The `session_name` field is no longer required. Plans are global and can be created with or without session context.
### Step 6: Show Requirements Preview
Display a preview of the requirements to the user:
```
📋 Requirements Preview: {plan_name}
Goal: {goal}
Work Type: {type} ({confidence}% confidence)
Requirements Captured:
1. {req-1-description}
Notes: {req-1-notes}
Open Questions: {req-1-questions}
2. {req-2-description}
Notes: {req-2-notes}
[Show first 3-4 requirements, summarize rest if more]
💡 This is a conceptual plan. Use /session:plan-finalize to transform requirements into executable tasks.
Options:
1. ✓ Save this plan (recommended)
2. Cancel
```
### Step 7: Get User Choice
Use the AskUserQuestion tool to get the user's choice.
Handle the response:
- **Option 1 (Save)**: Continue to Step 8
- **Option 2 (Cancel)**: Show "Plan creation cancelled" and STOP
### Step 8: Validate Requirements
Validate the requirements against requirements-schema.json:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js validate-requirements '{requirements_json}'
```
If validation fails, show the errors and STOP:
```
❌ Validation errors found:
1. {error_1}
2. {error_2}
Cannot save invalid plan. Please review.
```
If validation succeeds, continue.
### Step 9: Save Requirements File
Create the requirements.json file using the global plans directory:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js save-requirements {plan_name} '{requirements_json}'
```
This creates:
- `.claude/plans/{plan_name}/requirements.json`
Also create a conversation context markdown file for reference (if conversation was analyzed):
- Path: `.claude/plans/{plan_name}/conversation-context.md`
- Content: Include conversation summary, key decisions, requirements discussion, etc.
- If no session context, skip this file or create with placeholder noting manual plan creation
### Step 10: Display Success
Show success message with next steps:
```
✓ Global plan saved: {plan_name}
📋 Plan Details:
• Type: Conceptual (requirements captured)
• Work type: {type} (detected with {confidence}% confidence)
• Requirements: {requirement_count}
• Location: .claude/plans/{plan_name}/requirements.json
• Scope: Global (accessible from any session)
📝 Next Steps:
1. Review requirements:
/session:plan-status {plan_name}
2. List all plans:
/session:plan-list
3. Transform into executable plan:
/session:plan-finalize {plan_name}
This will use AI to break down requirements into concrete tasks
organized by implementation phases (Database, API, UI, etc.)
4. After finalization, execute:
/session:plan-execute {plan_name}
💡 Plans are now global and accessible from any session. No need to be in a specific session to work with plans.
```
---
## Error Handling
At each step, handle errors gracefully:
- **File not found**: Show clear message with suggestion on how to proceed
- **Validation failed**: Show specific validation errors
- **Detection low confidence**: Accept it (work type is just metadata)
- **Parse errors**: Show error details and abort
- **CLI command failures**: Check exit codes and show appropriate error messages
Always provide actionable next steps when errors occur.
---
## Key Principles
**Planning Phase = Requirements Capture**
- Users discuss WHAT they want (requirements), not HOW to implement (tasks)
- Keep it lightweight and exploratory
- Allow for open questions and uncertainty
- No forced structure - just capture what was discussed
**Examples of Good Requirements:**
- "Restrict products based on user permissions"
- "Track who created each product"
- "Add audit logging for product changes"
- "Improve product search performance"
**Examples of Bad (Too Detailed for Planning):**
- "Add restriction_level column to public.new_product table" ← This is a task!
- "Create POST /api/products validation" ← This is a task!
- "Add checkbox in product form component" ← This is a task!
The transformation from requirements → tasks happens in /session:plan-finalize.
---
## Notes
- The ${CLAUDE_PLUGIN_ROOT} environment variable should point to the session plugin source directory
- Plans are now global - stored in `.claude/plans/` regardless of active session
- The {session_name} variable is optional - used only if there's an active session for conversation context
- All CLI commands should use absolute paths
- Error messages should be user-friendly and actionable
- The workflow is designed to be interruptible - user can cancel at any point
- Conceptual plans use requirements.json format (not orchestration.json)
- Plans can be created with or without session context (conversation analysis is optional)

174
commands/plan-status.md Normal file
View File

@@ -0,0 +1,174 @@
You are executing the /session:plan-status command to show plan execution status.
**NOTE:** Plans are now global and independent of sessions.
**CRITICAL - Command Format:**
All session plugin commands use the `/session:` prefix. DO NOT suggest commands without this prefix.
- ✅ Correct: `/session:plan-execute`, `/session:plan-status`, `/session:plan-finalize`, `/session:plan-list`
- ❌ Wrong: `/plan-execute`, `/plan-status`, `/plan-show`, `/plan-list`
Use ONLY the exact command formats specified in this template.
## Arguments
Parsed from user input:
- `plan_name`: {name} (optional - if not provided, show status for all plans)
ARGUMENTS: {name}
## Workflow
### Step 1: Get Plan Status
Plans are stored globally in `.claude/plans/` and can be accessed without an active session.
If plan_name is provided, get status for that specific plan:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js plan-status {plan_name}
```
If no plan_name, list all global plans first:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js plan-list
```
Then get status for each plan.
### Step 2: Display Status
**For a specific plan:**
```
📋 Plan Status: {plan_name}
Goal: {goal}
Work Type: {work_type}
Scope: Global (accessible from any session)
Created: {created_date}
Last Updated: {updated_date}
Overall Progress: {completed_tasks}/{total_tasks} tasks ({percentage}%)
├─ Completed: {completed}
├─ In progress: {in_progress}
├─ Pending: {pending}
└─ Blocked: {blocked}
Phase Progress: {completed_phases}/{total_phases}
Phases:
1. [✓] {phase_1_name} (completed)
├─ Tasks: 5/5 (100%)
└─ Duration: {duration}
2. [→] {phase_2_name} (in-progress)
├─ Tasks: 2/7 (29%)
├─ Current Task: {current_task_id} - {description}
└─ Status: {task_status}
3. [ ] {phase_3_name} (pending)
├─ Tasks: 0/6 (0%)
└─ Depends on: Phase 2
4. [ ] {phase_4_name} (pending)
├─ Tasks: 0/4 (0%)
└─ Depends on: Phase 2, Phase 3
Current Task: {current_task_id}
Description: {description}
Details: {details}
Status: {status}
Phase: {phase_name}
Next Steps:
/session:plan-execute {plan_name} - Continue execution
/update-task-status {task_id} completed - Mark current task complete
```
**For all plans:**
```
📋 All Global Plans
1. oauth-implementation (feature)
├─ Progress: 15/22 tasks (68%)
├─ Status: in-progress
├─ Current: Phase 2 - OAuth Flow Implementation
└─ Last Updated: 2 hours ago
2. database-migration (refactor)
├─ Progress: 8/8 tasks (100%)
├─ Status: completed
└─ Completed: 1 day ago
3. api-redesign (spike)
├─ Progress: 0/12 tasks (0%)
├─ Status: pending
└─ Created: 3 days ago
Use /session:plan-status {plan_name} for detailed status.
Use /session:plan-execute {plan_name} to start/continue execution.
Use /session:plan-list to see all available plans.
```
### Step 3: Show Recommendations
Based on plan status, show context-aware recommendations:
**If plan is in-progress:**
```
💡 Recommendations:
- Current task is {status} - {recommendation}
- {next_task_count} tasks remaining in current phase
- Estimated completion: {estimate}
```
**If plan is blocked:**
```
⚠️ Blocked:
- Task {task_id} is blocked
- Blocker: {blocker_reason}
- Action needed: {action}
```
**If plan is completed:**
```
✅ Plan Complete:
- All {total_tasks} tasks completed
- Duration: {total_duration}
- Consider: Code review, testing, deployment
```
---
## Display Formats
### Progress Bar
```
Progress: [████████████░░░░░░░░] 68% (15/22 tasks)
```
### Status Icons
- [✓] Completed
- [→] In Progress
- [ ] Pending
- [✗] Failed
- [⊘] Blocked
- [~] Skipped
### Phase Status
```
Phase 2: OAuth Flow Implementation (in-progress)
├─ task-2-1: Create OAuth callback routes [✓]
├─ task-2-2: Implement JWT generation [→]
├─ task-2-3: Add session middleware [ ]
└─ task-2-4: Configure passport.js [ ]
```
---
## Error Handling
- Plan not found: Show available plans using /session:plan-list
- Corrupted plan data: Show error with recovery steps
- No plans exist: Show message about creating first plan with /session:save-plan {name}

344
commands/plan-update.md Normal file
View File

@@ -0,0 +1,344 @@
You are executing the /session:plan-update command to modify an existing plan.
**NOTE:** Plans are now global and independent of sessions.
**CRITICAL - Command Format:**
All session plugin commands use the `/session:` prefix. DO NOT suggest commands without this prefix.
- ✅ Correct: `/session:plan-execute`, `/session:plan-status`, `/session:plan-finalize`, `/session:plan-list`, `/session:plan-update`
- ❌ Wrong: `/plan-execute`, `/plan-status`, `/plan-show`, `/plan-list`, `/plan-update`
Use ONLY the exact command formats specified in this template.
## Arguments
Parsed from user input:
- `plan_name`: {name} (required - the plan to update)
- `update_request`: {request} (optional - natural language description of changes)
ARGUMENTS: {name} {request}
## Workflow
### Step 1: Validate Plan Exists
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js plan-exists {plan_name}
```
If the plan doesn't exist, show error and STOP:
```
❌ Error: Plan '{plan_name}' not found
Use /session:plan-list to see available plans.
Use /session:plan-save {name} to create a new plan.
```
### Step 2: Load Current Plan State
Get the current plan state for preview generation:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js plan-status {plan_name}
```
This returns JSON with plan metadata, phases, tasks, and execution state.
### Step 3: Parse Update Request
If `update_request` is provided, parse it into structured operations.
**Common Update Patterns:**
| Natural Language | Operation |
|-----------------|-----------|
| "add a new task to phase X" | `{ type: 'add', target: 'task', data: {...} }` |
| "remove task-2-3" | `{ type: 'delete', target: 'task', data: { id: 'task-2-3' } }` |
| "rename phase 1 to 'Setup'" | `{ type: 'update', target: 'phase', data: { id: 'phase-1', name: 'Setup' } }` |
| "mark task-1-1 as completed" | `{ type: 'update', target: 'task', data: { id: 'task-1-1', status: 'completed' } }` |
| "add a new phase called Testing" | `{ type: 'add', target: 'phase', data: { name: 'Testing' } }` |
If no `update_request` is provided, prompt the user:
```
What changes would you like to make to plan '{plan_name}'?
Examples:
- "add a new task 'Write unit tests' to phase 2"
- "remove the documentation phase"
- "rename task-3-1 to 'API integration'"
- "mark phase 1 as completed"
Enter your update request:
```
### Step 4: Check Execution State
Determine if the plan is being executed:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js get-execution-state {plan_name}
```
**If plan has started execution:**
Show mode selection:
```
⚠️ Plan '{plan_name}' is currently being executed.
Progress: {completed}/{total} tasks ({percentage}%)
Completed phases: {completed_phases}
Current phase: {current_phase}
How would you like to proceed?
1. [selective] Apply changes to pending tasks only (recommended)
- Completed work is preserved
- Only pending tasks/phases can be modified
- May need --force for some operations
2. [rollback] Reset and replan (full update)
- All progress will be reset to pending
- Execution history is preserved in logs
- Start fresh with updated plan
3. [cancel] Cancel update
Choice [1/2/3]:
```
### Step 5: Generate Preview
Show what changes will be made:
```
╔══════════════════════╗
║ Plan Update Preview ║
╚══════════════════════╝
Plan: {plan_name}
Mode: {selective|rollback}
─── Summary ────────────────────────────────────────────
Operations: {count}
+ Additions: {add_count}
~ Updates: {update_count}
- Deletions: {delete_count}
─── Operations ─────────────────────────────────────────
+ [1] ADD task: "Write unit tests"
Phase: phase-2-implementation
Description: Create comprehensive test suite
~ [2] UPDATE task: task-3-1
description: "API endpoints" → "API integration"
- [3] DELETE phase: phase-4-documentation
⚠ Contains 3 tasks that will also be deleted
─── Warnings ───────────────────────────────────────────
⚠ Deleting phase with completed tasks - use --force
⚠ Some operations affect completed work
─── Safety Notices ─────────────────────────────────────
⚠ DESTRUCTIVE: This update includes 1 deletion(s)
```
### Step 6: Confirm with User
```
Apply these changes? [+1 ~1 -1]
[y] Yes, apply changes
[n] No, cancel
[e] Edit operations
[?] Show help
Choice:
```
**If user chooses 'e' (edit):**
```
--- Edit Mode ---
Operations:
[1] ADD task: "Write unit tests"
[2] UPDATE task: task-3-1
[3] DELETE phase: phase-4-documentation
Commands:
remove <n> - Remove operation #n
done - Finish editing and confirm
cancel - Cancel all changes
Edit>
```
### Step 7: Execute Update
Based on mode selection:
**For selective mode:**
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js plan-update-selective {plan_name} --operations '{operations_json}'
```
**For rollback mode:**
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js plan-update-rollback {plan_name} --operations '{operations_json}'
```
### Step 8: Report Results
**Success:**
```
✅ Plan Updated Successfully
Plan: {plan_name}
Mode: {mode}
Changes Applied:
+ Added 1 task
~ Updated 1 task
- Deleted 1 phase (3 tasks removed)
Updated Progress: {new_completed}/{new_total} tasks
Next Steps:
/session:plan-status {plan_name} - View updated plan
/session:plan-execute {plan_name} - Continue execution
```
**Partial Success (selective mode):**
```
⚠️ Plan Partially Updated
Applied: 2 operations
Skipped: 1 operation (affects completed work)
Skipped Operations:
- DELETE phase: phase-1-setup (completed, requires --force)
To apply skipped operations, use:
/session:plan-update {plan_name} --force
```
**Failure:**
```
❌ Update Failed
Error: {error_message}
Details:
- Operation 3 failed: {reason}
- Validation error: {details}
Recovery:
- Backup created at: .claude/plans/{plan_name}/.backups/backup-{timestamp}
- To restore: /session:plan-restore {plan_name} {backup_name}
```
---
## Quick Update Examples
### Add a Task
```
/session:plan-update my-plan add a new task "Implement caching" to phase-2
```
### Remove a Task
```
/session:plan-update my-plan remove task-3-2
```
### Rename a Phase
```
/session:plan-update my-plan rename phase-1 to "Infrastructure Setup"
```
### Mark Task Complete
```
/session:plan-update my-plan mark task-2-1 as completed
```
### Add a New Phase
```
/session:plan-update my-plan add a new phase called "Performance Testing" after phase-3
```
### Force Update (completed items)
```
/session:plan-update my-plan remove task-1-1 --force
```
---
## Command Options
| Option | Description |
|--------|-------------|
| `--force` | Allow modifications to completed items |
| `--yes` | Skip confirmation prompt |
| `--dry-run` | Preview changes without applying |
| `--mode selective` | Only update pending items (default for executing plans) |
| `--mode rollback` | Reset progress and apply all changes |
| `--json` | Output results as JSON |
---
## Error Handling
### Plan Not Found
```
❌ Error: Plan 'unknown-plan' not found
Available plans:
- my-feature (in-progress, 45%)
- refactor-api (pending, 0%)
Use /session:plan-list for full details.
```
### Invalid Operation
```
❌ Error: Could not parse update request
Input: "do something to the plan"
Could not determine:
- Operation type (add, remove, update?)
- Target (phase, task?)
Try being more specific:
- "add a task called 'X' to phase Y"
- "remove task-1-2"
- "rename phase-1 to 'New Name'"
```
### Blocked by Execution State
```
❌ Error: Cannot modify in-progress task
Task 'task-2-3' is currently in progress.
Wait for completion or use rollback mode.
Options:
1. Wait for task to complete
2. Use /session:plan-update {plan} --mode rollback
```
### Validation Error
```
❌ Error: Invalid operation
Cannot add task with duplicate ID 'task-1-1'
A task with this ID already exists in phase-1.
Suggestion: Let the system generate a unique ID automatically.
```
---
## Related Commands
- `/session:plan-status {name}` - View current plan status
- `/session:plan-execute {name}` - Execute plan tasks
- `/session:plan-list` - List all plans
- `/session:plan-save {name}` - Create new plan
- `/session:plan-finalize {name}` - Finalize conceptual plan

View File

@@ -0,0 +1,212 @@
# Project Maps Generate Command
Generate project context maps for the current project.
## Usage
```
/project-maps-generate [--path <project-path>]
```
## Options
- `--path <path>`: Project path to scan (defaults to current directory)
- No options: Generate maps for current working directory
## Implementation
### Step 1: Determine Project Path
Parse command arguments to determine project path:
```javascript
const args = process.argv.slice(2);
const pathIndex = args.indexOf('--path');
const projectPath = pathIndex >= 0 && args[pathIndex + 1]
? args[pathIndex + 1]
: process.cwd();
```
Default to current working directory if no path specified.
### Step 2: Check if Maps Already Exist
Check if maps have already been generated for this project:
```bash
cd {working_directory}
node ${CLAUDE_PLUGIN_ROOT}/cli/lib/map-loader.js {project_path} --staleness-only 2>&1
```
If maps exist (exit code 0), ask user if they want to regenerate:
```
⚠️ Maps already exist for this project
Existing maps:
Location: {maps_dir}
Last generated: {timestamp}
Staleness: {score}/100
Regenerate maps? This will overwrite existing maps.
• Yes, regenerate (will take ~10-30 seconds)
• No, use refresh instead (faster, preserves existing data)
```
If user chooses "No", suggest using refresh instead:
```
Tip: Use /project-maps-refresh for faster updates
```
### Step 3: Initialize and Scan Project
Show progress and start generation:
```
Generating project context maps...
Project: {project_path}
Project hash: {hash}
```
Run the map generator:
```bash
cd {working_directory}
node ${CLAUDE_PLUGIN_ROOT}/cli/lib/map-generator.js {project_path}
```
The map generator will:
1. Initialize configuration
2. Scan file system
3. Generate 11 map files (Phases 1-3)
4. Apply compression
5. Save to `~/.claude/project-maps/{project-hash}/`
### Step 4: Show Progress
The map generator outputs progress:
```
Scanning project...
Scanned 145 files in 127ms
Generating maps...
✓ summary.json (2.1 KB → 907 B, 56% compression)
✓ tree.json (3.2 KB → 1.4 KB, 56% compression)
✓ metadata.json (12.5 KB → 5.2 KB, 58% compression)
✓ content-summaries.json (1.1 KB → 465 B, 58% compression)
✓ indices.json (11.8 KB → 5.0 KB, 58% compression)
✓ existence-proofs.json (4.0 KB → 1.7 KB, 58% compression)
✓ quick-queries.json (6.4 KB → 2.7 KB, 58% compression)
✓ dependencies-forward.json (1.1 KB → 477 B, 57% compression)
✓ dependencies-reverse.json (1.1 KB → 445 B, 60% compression)
✓ relationships.json (1.5 KB → 630 B, 58% compression)
✓ issues.json (1.3 KB → 557 B, 57% compression)
```
### Step 5: Display Summary
After generation completes, show summary:
```
✓ Maps generated successfully!
Summary:
Files scanned: {file_count}
Maps created: 11
Storage location: {maps_dir}
Total size:
• Original: {original_size} KB
• Compressed: {compressed_size} KB
• Compression: {compression_ratio}%
Maps by tier:
• Tier 1 (Always loaded): summary.json, quick-queries.json
• Tier 2 (On demand): tree.json, existence-proofs.json
• Tier 3 (When needed): metadata.json, content-summaries.json, indices.json
• Tier 4 (Deep analysis): dependencies-*.json, relationships.json, issues.json
Next steps:
• Load maps: /project-maps-load
• Quick queries: /project-maps-query
• Refresh maps: /project-maps-refresh
```
### Step 6: Verify Generation
Verify all expected files were created:
```bash
ls -lh ~/.claude/project-maps/{project_hash}/*.json | wc -l
```
Expected: 11 files
If count != 11, show warning:
```
⚠️ Warning: Expected 11 map files but found {actual_count}
Some maps may have failed to generate.
```
## Error Handling
**Project path doesn't exist:**
```
❌ Error: Project path not found
Path: {project_path}
Please check the path and try again.
```
**Permission denied:**
```
❌ Error: Permission denied
Cannot write to: ~/.claude/project-maps/
Check directory permissions.
```
**Generation failed:**
```
❌ Map generation failed: {error_message}
Possible causes:
1. Insufficient disk space
2. Invalid project structure
3. File access permissions
Try:
• Check disk space
• Verify project directory is accessible
• Run with --verbose for more details
```
**No files found:**
```
⚠️ No files found in project
The project appears to be empty or all files are excluded.
Check your .gitignore or .projectmaprc configuration.
```
## Performance Notes
- Small projects (<100 files): ~5-10 seconds
- Medium projects (100-1000 files): ~10-30 seconds
- Large projects (1000+ files): ~30-60 seconds
- Generation happens once, subsequent updates use incremental refresh (much faster)
## Examples
```bash
# Generate maps for current directory
/project-maps-generate
# Generate maps for specific project
/project-maps-generate --path /path/to/project
# Generate with verbose output
/project-maps-generate --verbose
```

View File

@@ -0,0 +1,120 @@
# Project Maps List Command
List all projects with generated context maps.
## Usage
```
/project-maps-list
```
## Implementation
### Step 1: Scan Maps Directory
List all subdirectories in the maps storage:
```bash
ls -d ~/.claude/project-maps/*/ 2>/dev/null
```
Each subdirectory represents a project hash.
### Step 2: Load Summary for Each Project
For each project hash, load the summary.json to get project details:
```javascript
const fs = require('fs').promises;
const path = require('path');
const MapLoader = require('./map-loader');
const mapsBaseDir = path.join(process.env.HOME, '.claude/project-maps');
const projectDirs = await fs.readdir(mapsBaseDir);
for (const hash of projectDirs) {
if (hash === 'maps' || hash === 'schemas' || hash === 'temp') continue;
try {
const summaryPath = path.join(mapsBaseDir, hash, 'summary.json');
const summary = await loadSummary(summaryPath);
// Display project info
} catch (error) {
// Skip invalid projects
}
}
```
### Step 3: Display Projects List
Show all projects with their metadata:
```
Project Maps
Found {count} projects with generated maps:
1. {project_name}
Path: {project_path}
Hash: {project_hash}
Files: {file_count}
Generated: {timestamp}
Staleness: {score}/100 ({level})
Size: {total_size}
2. {project_name}
Path: {project_path}
Hash: {project_hash}
Files: {file_count}
Generated: {timestamp}
Staleness: {score}/100 ({level})
Size: {total_size}
Total storage: {total_storage_size}
Commands:
• Load project: /project-maps-load
• Refresh: /project-maps-refresh
• Generate new: /project-maps-generate
```
### Step 4: Highlight Stale Projects
Mark projects that need refresh:
```
⚠️ The following projects may need refresh:
• {project_name} - Staleness: {score}/100
• {project_name} - Staleness: {score}/100
Run: /project-maps-refresh to update
```
## Error Handling
**No maps found:**
```
No project maps found
Storage location: ~/.claude/project-maps/
Generate maps for current project:
/project-maps-generate
```
**Corrupt project data:**
```
⚠️ Found {count} projects, but {error_count} have corrupt data:
• {hash} - Cannot read summary
• {hash} - Missing metadata
Consider removing corrupt entries:
rm -rf ~/.claude/project-maps/{hash}
```
## Examples
```bash
# List all projects with maps
/project-maps-list
```

View File

@@ -0,0 +1,301 @@
# Project Maps Load Command
Load and display project context maps with tiered loading.
## Usage
```
/project-maps-load [--tier <1|2|3|4>] [--map <map-name>]
```
## Options
- `--tier <N>`: Load all maps from specific tier (1, 2, 3, or 4)
- `--map <name>`: Load specific map by name
- No options: Load Tier 1 (summary + quick-queries)
## Tier Levels
**Tier 1** (Always loaded, ~3KB):
- `summary.json` - Project overview and statistics
- `quick-queries.json` - Pre-computed answers to common questions
**Tier 2** (On demand, ~10KB):
- `tree.json` - Directory structure
- `existence-proofs.json` - File manifests and negative space
**Tier 3** (When needed, ~60KB):
- `metadata.json` - Comprehensive file metadata
- `content-summaries.json` - Exports, imports, entities
- `indices.json` - Navigation indices by type/role/size/recency
**Tier 4** (Deep analysis, ~10KB):
- `dependencies-forward.json` - Import graphs
- `dependencies-reverse.json` - Who imports what
- `relationships.json` - Dependency chains
- `issues.json` - Broken imports, circular deps, unused files
## Implementation
### Step 1: Check if Maps Exist
First, verify maps exist for current project:
```bash
cd {working_directory}
node ${CLAUDE_PLUGIN_ROOT}/cli/lib/map-loader.js . --staleness-only
```
If no maps exist (exit code 1), show error:
```
❌ No project maps found
Generate maps first:
/project-maps-generate
```
### Step 2: Parse Arguments and Determine Load Mode
Parse command arguments:
```javascript
const args = process.argv.slice(2);
let loadMode = 'tier';
let tierLevel = 1;
let mapName = null;
if (args.includes('--tier')) {
const tierIndex = args.indexOf('--tier');
tierLevel = parseInt(args[tierIndex + 1]) || 1;
loadMode = 'tier';
}
if (args.includes('--map')) {
const mapIndex = args.indexOf('--map');
mapName = args[mapIndex + 1];
loadMode = 'single';
}
```
### Step 3: Load Maps
**For Tier Loading:**
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/lib/map-loader.js . --tier {tier_level}
```
**For Single Map Loading:**
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/lib/map-loader.js . {map_name}
```
The loader will:
1. Decompress maps automatically
2. Check staleness and show warnings
3. Return the map data
### Step 4: Display Results
**Tier 1 Display (Summary):**
```
✓ Tier 1 maps loaded
Project Overview:
Name: {project_name}
Path: {project_path}
Files: {total_files}
Size: {total_size}
Primary languages: {languages}
Framework: {framework_name} ({framework_type})
Quick Answers:
• Entry points: {entry_points}
• Test location: {test_location}
• Largest files: {largest_files}
• Recently modified: {recent_files}
Staleness: {staleness_score}/100 ({staleness_level})
Next steps:
• Load more detail: /project-maps-load --tier 2
• Query specific info: /project-maps-query
• Refresh maps: /project-maps-refresh
```
**Tier 2 Display (Structure):**
```
✓ Tier 2 maps loaded
Directory Structure:
{tree_visualization}
Top-level directories:
• src/ ({file_count} files)
• tests/ ({file_count} files)
• config/ ({file_count} files)
File Existence:
✓ package.json
✓ tsconfig.json
✓ .gitignore
✗ jest.config.js (missing)
✗ .env.example (missing)
```
**Tier 3 Display (Detailed Metadata):**
```
✓ Tier 3 maps loaded
Detailed File Metadata: {total_files} files
By Type:
• TypeScript: {ts_count} files ({ts_size})
• JavaScript: {js_count} files ({js_size})
• JSON: {json_count} files ({json_size})
By Role:
• Source: {source_count} files
• Tests: {test_count} files
• Config: {config_count} files
Content Summaries:
Top exports:
• {file}: {exports}
• {file}: {exports}
Indices loaded:
• By type: {type_count} types
• By role: {role_count} roles
• By size: {size_buckets} buckets
• By recency: Last {recent_days} days
```
**Tier 4 Display (Dependencies):**
```
✓ Tier 4 maps loaded
Dependency Analysis:
Forward Dependencies:
• {file} imports from {import_count} sources
• {file} imports from {import_count} sources
Reverse Dependencies (Most imported):
1. {file} - imported by {count} files
2. {file} - imported by {count} files
3. {file} - imported by {count} files
Issues Detected:
⚠️ Circular dependencies: {circular_count}
⚠️ Broken imports: {broken_count}
⚠️ Unused files: {unused_count}
Relationship Metrics:
• Max dependency depth: {max_depth}
• Average dependencies per file: {avg_deps}
• Tightly coupled modules: {coupled_count}
```
**Single Map Display:**
Show the specific map data in formatted JSON:
```
✓ Map loaded: {map_name}
{formatted_json_output}
Staleness: {score}/100
Size: {compressed_size} compressed ({original_size} original, {ratio}% compression)
```
### Step 5: Staleness Warning
If staleness score >= 30, show warning (automatically done by loader):
```
⚠️ Maps may be outdated
Staleness: {score}/100 - {recommendation}
Consider running: /project-maps-refresh --incremental
```
## Error Handling
**Maps not found:**
```
❌ No project maps found
Generate maps first:
/project-maps-generate
```
**Invalid tier:**
```
❌ Invalid tier level: {tier}
Valid tiers: 1, 2, 3, or 4
```
**Map not found:**
```
❌ Map not found: {map_name}
Available maps:
• summary
• tree
• metadata
• content-summaries
• indices
• existence-proofs
• quick-queries
• dependencies-forward
• dependencies-reverse
• relationships
• issues
```
**Load failed:**
```
❌ Failed to load maps: {error_message}
Try:
1. Regenerate maps: /project-maps-generate
2. Check file permissions
3. Verify maps directory exists
```
## Performance Notes
- Tier 1: Instant load (~3KB)
- Tier 2: Very fast (~10KB)
- Tier 3: Fast (~60KB)
- Tier 4: Fast (~10KB)
- Single map: Depends on map size
- All decompression happens automatically
## Examples
```bash
# Load Tier 1 (default)
/project-maps-load
# Load Tier 2 (directory structure)
/project-maps-load --tier 2
# Load Tier 3 (detailed metadata)
/project-maps-load --tier 3
# Load Tier 4 (dependencies)
/project-maps-load --tier 4
# Load specific map
/project-maps-load --map summary
/project-maps-load --map dependencies-forward
```

View File

@@ -0,0 +1,297 @@
# Project Maps Query Command
Query pre-computed answers from project context maps.
## Usage
```
/project-maps-query <query-type>
```
## Query Types
- `entry-points` - What are the entry points?
- `framework` - Which framework is used?
- `tests` - Where are the tests?
- `largest` - What are the largest files?
- `recent` - What changed recently?
- `structure` - What's the project structure?
- `languages` - What languages are used?
- `all` - Show all available queries
## Implementation
### Step 1: Check if Maps Exist
Verify maps exist for current project:
```bash
cd {working_directory}
node ${CLAUDE_PLUGIN_ROOT}/cli/lib/map-loader.js . --staleness-only
```
If no maps exist, show error and stop.
### Step 2: Parse Query Type
Extract query type from arguments:
```javascript
const args = process.argv.slice(2);
const queryType = args[0] || 'all';
```
### Step 3: Load Quick Queries Map
Load the pre-computed quick-queries map:
```javascript
const MapLoader = require('./map-loader');
const loader = new MapLoader(process.cwd());
const quickQueries = await loader.load('quick-queries');
```
### Step 4: Execute Query and Display Results
Based on query type, extract and display the relevant information:
**Entry Points Query:**
```
Query: What are the entry points?
Entry Points:
1. src/index.ts - Main application entry
2. src/server.ts - Server entry
3. src/cli.ts - CLI entry
Description:
These files serve as the main entry points to the application.
They are typically referenced in package.json or imported first.
Related files:
• package.json: "main": "src/index.ts"
• package.json: "bin": "src/cli.ts"
```
**Framework Query:**
```
Query: Which framework is used?
Framework: React
Type: Frontend (Single Page Application)
Version: Detected from package.json
Key indicators:
• package.json dependencies: react, react-dom
• File patterns: *.jsx, *.tsx files in src/
• Common React patterns detected
Related:
• Build tool: Vite
• Testing: Jest + React Testing Library
• State management: Redux
```
**Tests Query:**
```
Query: Where are the tests?
Test Files: {test_count} files
Locations:
• tests/ - {count} files
• src/**/*.test.ts - {count} files
• src/**/*.spec.ts - {count} files
Test Frameworks:
• Jest - Main test runner
• React Testing Library - Component tests
Coverage:
• Source files: {source_count}
• Test files: {test_count}
• Coverage ratio: {ratio}%
```
**Largest Files Query:**
```
Query: What are the largest files?
Largest Files (by size):
1. dist/bundle.js - 2.4 MB (generated)
2. src/components/Dashboard.tsx - 842 KB
3. src/utils/helpers.ts - 567 KB
4. node_modules/.bin/webpack - 234 KB (dependency)
5. src/data/constants.json - 189 KB
Recommendations:
⚠️ Dashboard.tsx is unusually large (842 KB)
Consider splitting into smaller components
⚠️ helpers.ts contains many utilities (567 KB)
Consider organizing into separate modules
```
**Recent Changes Query:**
```
Query: What changed recently?
Recently Modified Files (last 7 days):
1. src/components/Login.tsx - 2 hours ago
2. src/api/auth.ts - 5 hours ago
3. tests/auth.test.ts - 5 hours ago
4. src/types/user.ts - 1 day ago
5. README.md - 3 days ago
Activity Summary:
• Most active directory: src/components/ ({count} changes)
• Most active author: {author} ({count} commits)
• Files modified: {count}
```
**Structure Query:**
```
Query: What's the project structure?
Project Structure:
├── src/ ({file_count} files)
│ ├── components/ ({file_count} files)
│ ├── utils/ ({file_count} files)
│ ├── api/ ({file_count} files)
│ └── types/ ({file_count} files)
├── tests/ ({file_count} files)
├── config/ ({file_count} files)
└── dist/ ({file_count} files)
Conventions:
• Source code: src/
• Tests: tests/ and *.test.ts
• Configuration: config/
• Build output: dist/
```
**Languages Query:**
```
Query: What languages are used?
Primary Languages:
1. TypeScript - {count} files ({percentage}%)
2. JavaScript - {count} files ({percentage}%)
3. JSON - {count} files ({percentage}%)
4. Markdown - {count} files ({percentage}%)
Language Distribution:
[▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░] TypeScript (75%)
[▓▓▓░░░░░░░░░░░░░░░] JavaScript (15%)
[▓░░░░░░░░░░░░░░░░░] JSON (5%)
[░░░░░░░░░░░░░░░░░░] Other (5%)
```
**All Queries:**
```
Available Queries:
1. entry-points - What are the entry points?
2. framework - Which framework is used?
3. tests - Where are the tests?
4. largest - What are the largest files?
5. recent - What changed recently?
6. structure - What's the project structure?
7. languages - What languages are used?
Usage:
/project-maps-query <query-type>
Example:
/project-maps-query entry-points
/project-maps-query framework
```
### Step 5: Show Staleness If Relevant
If staleness score >= 30, append warning:
```
⚠️ Note: Maps are {staleness_score}/100 stale
Query results may be outdated. Consider refreshing:
/project-maps-refresh
```
## Error Handling
**Maps not found:**
```
❌ No project maps found
Generate maps first:
/project-maps-generate
```
**Invalid query type:**
```
❌ Unknown query type: {query_type}
Available query types:
• entry-points
• framework
• tests
• largest
• recent
• structure
• languages
• all
Usage:
/project-maps-query <query-type>
```
**No data available:**
```
⚠️ No data available for query: {query_type}
This might happen if:
1. The project doesn't have this information
2. Maps need to be regenerated
3. The data wasn't captured during generation
Try:
/project-maps-refresh
```
## Performance Notes
- Queries are instant (pre-computed during generation)
- No file system scanning required
- Answers come from quick-queries.json (~3KB)
- Perfect for getting quick insights without deep analysis
## Examples
```bash
# What are the entry points?
/project-maps-query entry-points
# Which framework is used?
/project-maps-query framework
# Where are the tests?
/project-maps-query tests
# What are the largest files?
/project-maps-query largest
# What changed recently?
/project-maps-query recent
# Show all available queries
/project-maps-query all
```

View File

@@ -0,0 +1,176 @@
# Project Maps Refresh Command
Refresh project context maps (full or incremental).
## Usage
```
/project-maps-refresh [--full|--incremental]
```
## Options
- `--full`: Perform full rescan and regenerate all maps (slower, complete)
- `--incremental`: Only update changed files (faster, recommended for small changes)
- No option: Auto-detect based on changes (incremental if <30% files changed, otherwise full)
## Implementation
### Step 1: Check if Maps Exist
First, check if maps have been generated for this project:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/lib/map-loader.js . --staleness-only
```
If no maps exist (exit code 1), show error and suggest running generation first:
```
❌ No project maps found
Generate maps first:
/project-maps-generate
Or manually:
node session/cli/lib/map-generator.js generate
```
### Step 2: Determine Refresh Mode
Parse command arguments to determine refresh mode:
- If user specified `--full`: Use full refresh
- If user specified `--incremental`: Use incremental refresh
- If no option: Auto-detect
For auto-detect:
1. Load summary map to get project hash and last refresh info
2. Count changed files using git diff
3. If changed files > 30% of total: Recommend full refresh
4. Otherwise: Use incremental refresh
### Step 3: Perform Refresh
**For Full Refresh:**
Run the map generator to regenerate all maps:
```bash
cd {working_directory}
node ${CLAUDE_PLUGIN_ROOT}/cli/lib/map-generator-cli.js refresh --full --project .
```
This will:
- Rescan entire project
- Regenerate all 11 maps
- Update staleness metadata
- Show completion statistics
**For Incremental Refresh:**
Run the incremental updater:
```bash
cd {working_directory}
node ${CLAUDE_PLUGIN_ROOT}/cli/lib/incremental-updater-cli.js --project . --hash {project_hash}
```
This will:
- Use git diff to find changed files
- Rescan only changed files
- Update affected map entries
- Regenerate dependency chains
- Much faster than full refresh
### Step 4: Show Results
After refresh completes, display results:
**Full Refresh:**
```
✓ Full refresh completed
Maps regenerated:
• summary.json (Level 1)
• tree.json (Level 2)
• metadata.json (Level 3)
• content-summaries.json (Level 3)
• indices.json (Level 3)
• existence-proofs.json (Level 2)
• quick-queries.json (Level 1)
• dependencies-forward.json (Level 4)
• dependencies-reverse.json (Level 4)
• relationships.json (Level 4)
• issues.json (Level 4)
Statistics:
Files scanned: {total_files}
Time taken: {time_ms}ms
Maps location: {maps_dir}
Staleness: 0/100 (fresh)
```
**Incremental Refresh:**
```
✓ Incremental refresh completed
Files updated:
• Modified: {modified_count}
• Added: {added_count}
• Deleted: {deleted_count}
Maps updated:
• metadata.json
• content-summaries.json
• dependencies-forward.json
• dependencies-reverse.json
Statistics:
Files scanned: {scanned_count}
Time taken: {time_ms}ms
Time saved: ~{time_saved_percent}% vs full rescan
Staleness: 0/100 (fresh)
```
### Step 5: Verification
After refresh, automatically verify staleness:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/lib/staleness-checker.js . {maps_dir}/summary.json
```
Expected result: Score should be 0/100 (fresh)
## Error Handling
**Git not available:**
```
⚠️ Warning: Git not available, falling back to full refresh
```
**Too many changes for incremental:**
```
⚠️ Too many files changed ({change_percent}%)
Incremental refresh may miss dependencies.
Recommend: /project-maps-refresh --full
```
**Refresh failed:**
```
❌ Refresh failed: {error_message}
Try:
1. Check git status
2. Ensure no file permission issues
3. Run full refresh: /project-maps-refresh --full
```
## Notes
- Incremental refresh is faster (target: <20% of full scan time)
- Full refresh guarantees consistency
- Refresh automatically updates staleness metadata
- Maps are compressed automatically during refresh

View File

@@ -0,0 +1,139 @@
# Project Maps Stats Command
Show compression metrics and system statistics for project maps.
## Usage
```
/project-maps-stats
```
## Implementation
### Step 1: Scan All Project Maps
Scan the maps directory and collect statistics:
```bash
du -sh ~/.claude/project-maps/
ls -lR ~/.claude/project-maps/ | wc -l
```
### Step 2: Calculate Compression Metrics
For each project, read compression metadata:
```javascript
const allStats = {
totalProjects: 0,
totalFiles: 0,
totalMaps: 0,
originalSize: 0,
compressedSize: 0,
totalStorage: 0
};
// Aggregate from all summary.json files
for (const projectHash of projectHashes) {
const summary = await loadSummary(projectHash);
allStats.totalFiles += summary.statistics.totalFiles;
// ... aggregate other stats
}
```
### Step 3: Display Statistics
Show comprehensive system stats:
```
Project Maps Statistics
System Overview:
Projects mapped: {project_count}
Total files scanned: {total_files}
Total maps generated: {total_maps}
Storage location: ~/.claude/project-maps/
Storage Metrics:
Total storage used: {total_storage} MB
Original data size: {original_size} MB
Compressed size: {compressed_size} MB
Space saved: {space_saved} MB ({savings_percent}%)
Compression Efficiency:
Average compression ratio: {avg_ratio}%
Best compression: {best_ratio}% ({project_name})
Worst compression: {worst_ratio}% ({project_name})
Compression breakdown:
• Level 1 (minification): {level1_ratio}%
• Level 2 (key abbreviation): {level2_ratio}%
• Level 3 (deduplication): {level3_ratio}%
Map Distribution:
• Per project: 11 maps (fixed)
• Total maps: {total_maps}
Performance:
• Average generation time: {avg_gen_time}ms
• Average map size: {avg_map_size} KB
• Staleness distribution:
Fresh (0-30): {fresh_count} projects
Moderate (30-60): {moderate_count} projects
Critical (60+): {critical_count} projects
Recommendations:
⚠️ {stale_count} projects need refresh
✓ Storage efficiency: {efficiency}%
💡 Consider cleaning old maps: /project-maps-clean
```
### Step 4: Per-Project Breakdown
Optionally show detailed per-project stats:
```
Per-Project Breakdown:
1. {project_name}
Maps: 11
Original: {original_size} KB
Compressed: {compressed_size} KB
Ratio: {ratio}%
Staleness: {score}/100
2. {project_name}
Maps: 11
Original: {original_size} KB
Compressed: {compressed_size} KB
Ratio: {ratio}%
Staleness: {score}/100
```
## Error Handling
**No maps found:**
```
No project maps found
Generate maps first:
/project-maps-generate
```
**Cannot calculate stats:**
```
⚠️ Unable to calculate complete statistics
Some map files may be corrupt or inaccessible.
Try regenerating maps for affected projects.
```
## Examples
```bash
# Show system statistics
/project-maps-stats
# Show detailed per-project stats
/project-maps-stats --detailed
```

215
commands/save.md Normal file
View File

@@ -0,0 +1,215 @@
You are managing a session memory system. The user wants to manually save a snapshot of the current session state.
**CRITICAL - Command Format:**
All session plugin commands use the `/session:` prefix. DO NOT suggest commands without this prefix.
- ✅ Correct: `/session:list`, `/session:start`, `/session:continue`, `/session:status`
- ❌ Wrong: `/session list`, `/session start`, `/session continue`, `/session status`
Use ONLY the exact command formats specified in this template.
## Task: Save Session Snapshot
Capture the current context and save it as a timestamped snapshot.
**CRITICAL OPTIMIZATION:** This command now uses CLI for snapshot writes, enabling plan mode support.
### Step 1: Validate Active Session
1. Check if `.claude/sessions/.active-session` file exists
2. If NOT exists, show error:
```
❌ Error: No active session
💡 Use /session:start [name] to create a new session
💡 Or use /session:continue [name] to resume an existing session
```
Then STOP.
3. Read the active session name from `.active-session`
4. Verify the session directory `.claude/sessions/{active_session}/` exists
5. If NOT exists, show error:
```
❌ Error: Active session directory not found
The session may have been deleted. Please start a new session.
```
Then STOP.
### Step 2: Capture Conversation Context
Analyze the recent conversation (last 10-20 exchanges) and create a summary:
- What topics were discussed
- What problems were solved
- What decisions were made
- What tasks were attempted or completed
Keep this summary concise but informative (3-5 sentences).
### Step 3: Capture Completed Todos
Look for any todos that were marked as completed in this conversation:
- Check for completed checkboxes in messages
- Check for explicit "completed" or "done" mentions
- List them in checkbox format: `- [x] Task description`
If no todos were completed, write: `- No todos completed in this segment`
### Step 4: Capture Files Modified
Identify all files that were modified in this conversation:
- Files written with Write tool
- Files edited with Edit tool
- Files created or modified
For each file, capture:
- File path
- Brief description of changes made (1-2 lines)
Format:
```markdown
### path/to/file.ts
- Added authentication middleware
- Updated error handling
```
If no files were modified, write: `No files modified in this segment`
### Step 5: Capture Current State
Describe the current state of the work:
- What's working now
- What's in progress
- What's blocked
- What's next
Format as bullet points (3-5 items).
### Step 6: Capture Key Code Snippets (Optional)
If any particularly important code was written or discussed, include a representative snippet:
- Limit to 20-30 lines maximum
- Include language identifier for syntax highlighting
- Add brief explanation
Only include if genuinely important. Skip if no critical code.
### Step 7: Generate Snapshot Content
Create the snapshot content in this structure (but DON'T write it yet):
```markdown
# Snapshot: {session_name}
**Timestamp**: {full_timestamp_YYYY-MM-DD_HH:MM:SS}
**Format Version**: 2.0
## Topics Discussed
1. **[Category]**: {topic_1_brief_description}
2. **[Category]**: {topic_2_brief_description}
{continue_for_all_topics}
## Suggestions & Recommendations
1. **[Category]**: {suggestion} - {rationale}
{if_any_suggestions_given}
## Decisions Made
1. **[Decision]**: {rationale}
{if_any_decisions_made}
## Tasks Completed
1. {completed_task_1}
2. {completed_task_2}
{or_write_"No_tasks_completed"}
## Files Modified
1. `{file_path}`: {what_changed_and_why}
{or_write_"No_files_modified"}
## Current Status
- **Progress**: {where_things_stand}
- **Next Steps**: {what_should_be_done_next}
- **Blockers**: {issues_or_"None"}
## Notes
{any_additional_important_observations}
```
### Step 8: Write Snapshot via CLI (CRITICAL - Plan Mode Support)
**Instead of using the Write tool**, use the CLI with stdin to write the snapshot.
This enables snapshot saves even in plan mode where Write tool is blocked.
Run this command, piping the snapshot content via stdin:
```bash
echo "{snapshot_content}" | node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js write-snapshot {session_name} --stdin --type manual
```
**IMPORTANT:** Escape any special characters in the content appropriately for the shell.
Alternative approach if echo has escaping issues:
```bash
cat <<'EOF' | node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js write-snapshot {session_name} --stdin --type manual
{snapshot_content}
EOF
```
The CLI will:
- Write the snapshot file with timestamp
- Update the index automatically
- Return success with filename
### Step 9: Update context.md
1. Read current `.claude/sessions/{active_session}/context.md`
2. If any key decisions were made in this conversation, add them to "Key Decisions" section:
```markdown
### {current_timestamp}
- Decision: {what_was_decided}
- Rationale: {why_this_approach}
- Impact: {what_this_affects}
```
3. If any important discoveries were made, add to "Important Discoveries" section
4. If any blockers were encountered or resolved, update "Blockers & Resolutions" section
5. Update the "Summary" section with a running summary including this snapshot
6. Write the updated context.md back (use Edit tool for this - it's allowed in plan mode for session files)
### Step 10: Update session.md Timestamp
1. Read `.claude/sessions/{active_session}/session.md`
2. Update the "Last Updated" field to current timestamp
3. If any new files were involved, add them to "Files Involved" section
4. Write back the updated session.md (use Edit tool)
### Step 11: Display Success Message
Show confirmation:
```
✓ Session snapshot saved
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📁 .claude/sessions/{session_name}/{timestamp}.md
📝 Captured:
- Conversation summary
- {X} completed todos
- {Y} file changes
- Current state and next steps
{if_decisions: "- {Z} key decisions"}
💾 Context updated in context.md
⏰ Session timestamp updated
```
---
**CRITICAL BENEFITS - PLAN MODE SUPPORT:**
- **Problem:** In plan mode, Write tool is blocked (prevents accidental code changes)
- **Impact:** Snapshots couldn't be saved, causing data loss on `/clear`
- **Solution:** CLI delegation via Bash bypasses Write tool restrictions
- **Result:** Zero data loss in plan mode, seamless user experience
**PERFORMANCE BENEFITS:**
- **Before:** 15-25K tokens for snapshot analysis and writes
- **After:** 8-15K tokens, CLI handles write operations
- **Improvement:** ~40-50% token reduction, instant index update
**IMPORTANT NOTES:**
- Use heredoc (cat <<'EOF') for reliable content piping, avoids escaping issues
- CLI write-snapshot automatically updates index, no separate step needed
- Edit tool can still be used for session.md and context.md (they're documentation, not code)
- This approach works in BOTH normal mode and plan mode

369
commands/setup.md Normal file
View File

@@ -0,0 +1,369 @@
You are helping the user configure session plugin hooks in their project's `.claude/settings.json` file.
## Task: Setup Session Plugin Hooks
This command manages the automatic configuration of session plugin hooks that enable auto-tracking of sessions, user interactions, and file modifications.
**IMPORTANT:** This command uses the session CLI tool to perform hook management operations safely with atomic writes and backups.
### Parse Command Arguments
Extract the operation from the command arguments. Format: `/session:setup [options]`
**Supported options:**
- No arguments: Install/configure hooks (default)
- `--permissions`: Install hooks + permission bypasses (eliminates ALL prompts)
- `--remove`: Remove hooks from settings.json
- `--status`: Show current hook and permission configuration
- `--force-cleanup`: Force cleanup of orphaned hooks
- `--dry-run`: Preview changes without applying them
### Step 1: Determine Operation Mode
1. Check arguments to determine which operation to perform:
- **Install mode** (default/no args): Add hooks to settings.json
- **Remove mode** (`--remove`): Remove hooks from settings.json
- **Status mode** (`--status`): Show current configuration
- **Cleanup mode** (`--force-cleanup`): Clean up orphaned hooks
- **Dry run** (`--dry-run`): Can be combined with other modes to preview
### Step 2: Execute CLI Command
Run the appropriate CLI command based on the operation mode:
**For Install (hooks only):**
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js setup-hooks
```
**For Install (hooks + permissions):**
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js setup-hooks --permissions
```
**For Remove:**
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js setup-hooks --remove
```
**For Status:**
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js setup-hooks --status
```
**For Force Cleanup:**
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js setup-hooks --force-cleanup
```
**For Dry Run (example with install):**
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js setup-hooks --dry-run
```
The CLI will return JSON with the operation result.
### Step 3: Display Results
Parse the JSON response and display user-friendly output based on the action:
#### Install Success (action: "installed")
**If permissions were added (permissionsRequested: true, permissionsCount > 0):**
```
✅ Session plugin configured successfully!
📋 Hooks added to .claude/settings.json:
✓ SessionStart - Auto-clears session on /clear
✓ SessionEnd - Cleanup on Claude Code exit
✓ UserPromptSubmit - Tracks user interactions
✓ PostToolUse (Write, Edit, NotebookEdit) - Tracks file changes
✓ Stop - Captures Claude's responses for self-contained logs
🔓 Permissions added ({permissionsCount} entries):
✓ Read(.claude/sessions/**)
✓ Bash(git log --oneline:*)
✓ Bash(git status --porcelain:*)
✓ Bash(git diff --stat:*)
✓ Bash(git branch -vv:*)
✓ Bash(git rev-parse --abbrev-ref:*)
⚡ Result: ZERO permission prompts during:
• /session:continue (no Read prompts, no git prompts)
• /session:save (no Read prompts)
• /session:status (no Read prompts)
• All session operations run silently
💾 Backup saved: {backupPath}
📁 Settings: {settingsPath}
⚠️ IMPORTANT: Restart Claude Code for changes to take effect!
Hooks and permissions are loaded at startup.
💡 To disable temporarily: Set "disableAllHooks": true in settings.json
💡 To remove these hooks: /session:setup --remove
```
**If permissions were NOT added (permissionsRequested: false):**
```
✅ Session plugin hooks configured successfully!
📋 Hooks added to .claude/settings.json:
✓ SessionStart - Auto-clears session on /clear
✓ SessionEnd - Cleanup on Claude Code exit
✓ UserPromptSubmit - Tracks user interactions
✓ PostToolUse (Write, Edit, NotebookEdit) - Tracks file changes
✓ Stop - Captures Claude's responses for self-contained logs
🎯 Sessions now automatically track:
• Session state changes
• User prompts and interactions
• Claude's full responses
• File modifications
💡 TIP: Eliminate ALL permission prompts during session operations!
Run: /session:setup --permissions
This adds safe read-only permissions for:
• .claude/sessions/** files (Read access)
• git commands (log, status, diff, branch)
Result: Zero prompts during /session:continue ⚡
💾 Backup saved: {backupPath}
📁 Settings: {settingsPath}
⚠️ IMPORTANT: Restart Claude Code for hooks to take effect!
Hooks are loaded at startup and won't activate until you restart.
💡 To disable temporarily: Set "disableAllHooks": true in settings.json
💡 To remove these hooks: /session:setup --remove
```
#### Already Configured (action: "already_configured")
```
Session plugin hooks are already configured!
✓ All session plugin hooks are properly configured in settings.json
Current hooks:
✓ SessionStart - Active
✓ UserPromptSubmit - Active
✓ PostToolUse - Active
✓ Stop - Active
💡 To reinstall: /session:setup --remove, then /session:setup
💡 To view details: /session:setup --status
```
#### Remove Success (action: "removed")
```
✅ Session plugin hooks removed!
📋 Removed from .claude/settings.json:
✓ SessionStart
✓ UserPromptSubmit
✓ PostToolUse
✓ Stop
💾 Backup saved: {backupPath}
⚠️ IMPORTANT: Restart Claude Code to stop hooks!
Active hooks will continue running until you restart.
💡 Sessions still work, but automatic tracking is disabled
💡 To re-enable: /session:setup
```
#### Not Configured (action: "not_configured")
```
No session plugin hooks found
Session plugin hooks are not currently configured in settings.json
💡 To install hooks: /session:setup
💡 This will enable automatic session tracking
```
#### Status Display (action: "status")
**When properly configured:**
```
✅ Session Plugin Status
📋 Hooks configured in .claude/settings.json:
✓ SessionStart
→ node ${CLAUDE_PLUGIN_ROOT}/hooks/session-start.js
✓ SessionEnd
→ node ${CLAUDE_PLUGIN_ROOT}/hooks/session-end.js
✓ UserPromptSubmit
→ node ${CLAUDE_PLUGIN_ROOT}/hooks/user-prompt-submit.js
✓ PostToolUse (3 matchers)
→ Write: node ${CLAUDE_PLUGIN_ROOT}/hooks/post-tool-use.js
→ Edit: node ${CLAUDE_PLUGIN_ROOT}/hooks/post-tool-use.js
→ NotebookEdit: node ${CLAUDE_PLUGIN_ROOT}/hooks/post-tool-use.js
✓ Stop
→ node ${CLAUDE_PLUGIN_ROOT}/hooks/stop.js
📊 Hooks: {configuredHookTypes}/{totalHookTypes} hook types configured
✅ All hooks pointing to valid scripts
🔓 Permissions configured: {permissionsCount}/{totalPermissions}
{if permissionsConfigured === true}
✅ All session permissions configured
• Read(.claude/sessions/**)
• Bash(git log --oneline:*)
• Bash(git status --porcelain:*)
• Bash(git diff --stat:*)
• Bash(git branch -vv:*)
• Bash(git rev-parse --abbrev-ref:*)
⚡ Result: Zero prompts during session operations
{else if permissionsCount > 0 && permissionsCount < totalPermissions}
⚠️ Partial permissions configured ({permissionsCount}/{totalPermissions})
💡 To add missing permissions: /session:setup --permissions
{else}
⚠️ No session permissions configured
💡 To eliminate permission prompts: /session:setup --permissions
This adds safe read-only permissions for session files and git commands
{end if}
🎯 Plugin Status: Installed & Configured
💡 To remove: /session:setup --remove
```
**When orphaned (plugin uninstalled but hooks remain):**
```
⚠️ Session Plugin Hooks Status
📋 Found in .claude/settings.json:
⚠️ SessionStart
→ node ${CLAUDE_PLUGIN_ROOT}/hooks/session-start.js
❌ Script not found (plugin may be uninstalled)
⚠️ UserPromptSubmit
❌ Script not found
⚠️ PostToolUse (3 matchers)
❌ All scripts not found
⚠️ Stop
❌ Script not found
🔍 Plugin Status: Not Found
❌ Hooks are orphaned (pointing to missing files)
Found {orphanedHooks.length} orphaned hook entries
🧹 Cleanup Options:
1. Auto-cleanup: /session:setup --force-cleanup
2. Manual cleanup: Edit .claude/settings.json
3. Reinstall plugin to restore functionality
```
#### Cleanup Success (action: "cleaned")
```
✅ Orphaned hooks cleaned up!
🧹 Removed {removedCount} orphaned hook entries:
{List each orphaned hook that was removed}
💾 Backup saved: {backupPath}
⚠️ IMPORTANT: Restart Claude Code to apply cleanup!
Settings changes take effect on next restart.
💡 Settings.json has been cleaned
💡 To reinstall hooks: /session:setup
```
#### No Orphans (action: "no_orphans")
```
✅ No orphaned hooks found
All hooks in settings.json are valid
💡 Everything looks good!
```
#### Error Cases
**On error (success: false):**
```
❌ Error: {error message}
{Provide helpful context based on the error:}
Common issues:
- **Malformed JSON**: settings.json has syntax errors
→ Fix: Restore from backup or manually repair JSON
- **Permission denied**: No write access to .claude/settings.json
→ Fix: Check file permissions
- **Plugin not found**: Session plugin may not be installed
→ Fix: Reinstall the session plugin
💡 To restore from backup: cp .claude/settings.json.backup .claude/settings.json
💡 Need help? Check the README or /session:setup --status
```
### Important Notes
- **Atomic Operations**: All writes use atomic operations with backups
- **Idempotent**: Safe to run multiple times, won't create duplicates
- **Portable Paths**: Uses `${CLAUDE_PLUGIN_ROOT}` variable for cross-platform compatibility
- **Merge Strategy**: Preserves existing hooks when installing
- **Safety**: Creates `.backup` file before any modifications
### Usage Examples
```bash
# Install hooks only (basic setup)
/session:setup
# Install hooks + permissions (RECOMMENDED - eliminates ALL prompts)
/session:setup --permissions
# Check current status (shows hooks and permissions)
/session:setup --status
# Preview what would be installed (dry run)
/session:setup --dry-run
# Preview with permissions
/session:setup --permissions --dry-run
# Remove hooks before uninstalling plugin
/session:setup --remove
# Clean up orphaned hooks after plugin uninstall
/session:setup --force-cleanup
```
**Recommended:** Always use `--permissions` flag for best experience:
- Zero permission prompts during `/session:continue`
- Zero permission prompts during `/session:save`
- Zero permission prompts during `/session:status`
- Completely silent session operations
---
**CRITICAL for Plugin Uninstallation:**
Before uninstalling the session plugin, users should run:
```bash
/session:setup --remove
```
This ensures clean removal and prevents orphaned hook entries in settings.json.

293
commands/start.md Normal file
View File

@@ -0,0 +1,293 @@
You are managing a session memory system. The user wants to start a new named session.
**CRITICAL - Command Format:**
All session plugin commands use the `/session:` prefix. DO NOT suggest commands without this prefix.
- ✅ Correct: `/session:list`, `/session:start`, `/session:continue`, `/session:status`
- ❌ Wrong: `/session list`, `/session start`, `/session continue`, `/session status`
Use ONLY the exact command formats specified in this template.
## Task: Start New Session
Parse the session name from the command arguments. The command format is: `/session:start [name]`
**OPTIMIZATION:** This command now updates the metadata index after creating the session.
### Step 1: Validate Session Name
1. Extract the session name from the arguments
2. Validate the name matches regex: `^[a-zA-Z0-9_-]+$`
3. If invalid, show error:
```
❌ Error: Invalid session name '{name}'
Session names can only contain:
- Letters (a-z, A-Z)
- Numbers (0-9)
- Hyphens (-)
- Underscores (_)
Example: my-session or my_session_123
```
Then STOP.
### Step 2: Check for Duplicate Sessions
**CRITICAL:** Check both directory names AND session.md file contents to prevent duplicates.
1. **Check directory collision:**
- Check if `.claude/sessions/{name}/` directory already exists
- If exists, show error:
```
❌ Error: Session directory '{name}' already exists
💡 Use /session:continue {name} to resume
💡 Or use /session:list to see all sessions
```
Then STOP.
2. **Check session name collision (NEW - prevents duplicate names):**
- Use the CLI to get all existing sessions:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js list
```
- Parse the JSON response and check if any existing session has `name: "{name}"`
- If a session with this name exists (even if directory name is different), show error:
```
❌ Error: A session named '{name}' already exists
💡 Use /session:list to see all sessions
💡 Choose a different name for this session
```
Then STOP.
This dual-check prevents both directory collisions and duplicate session names.
### Step 3: Check for Active Session and Transition (NEW - Session Cleanup)
Before creating the new session, check if there's already an active session:
1. Check if `.claude/sessions/.active-session` exists
2. If it exists:
- Read the current active session name
- Show: "📋 Closing previous session '{previous_session_name}'..."
- Close the previous session status:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js update-status "{previous_session_name}" "closed"
```
- This marks the previous session as closed in `.auto-capture-state`
3. Continue to next step (the new session activation will overwrite `.active-session`)
**Note:** The SessionEnd hook will handle final cleanup on Claude Code termination.
### Step 4: Create Session Folder
1. Create directory: `.claude/sessions/{name}/`
2. Verify creation was successful
### Step 5: Initialize session.md
**CRITICAL:** The session name in session.md MUST match the directory name to prevent duplicates.
Create `.claude/sessions/{name}/session.md` with this content:
```markdown
# Session: {name}
**Started**: {current_timestamp_YYYY-MM-DD_HH:MM}
**Last Updated**: {current_timestamp_YYYY-MM-DD_HH:MM}
## Goal
[Ask user to describe the goal for this session]
## Overview
Working on: {name}
## Key Milestones
- [ ] [To be defined during session]
## Files Involved
- [Will be tracked as work progresses]
## Configuration
- Auto-capture: enabled
## Notes
Session started. Use /session:save to capture important milestones.
```
### Step 6: Initialize context.md
Create `.claude/sessions/{name}/context.md` with this content:
```markdown
# Session Context: {name}
## Key Decisions
[Decisions will be captured during session]
## Important Discoveries
[Discoveries will be documented as they occur]
## Blockers & Resolutions
[Issues and resolutions will be tracked here]
## Technical Context
[Architecture decisions and technical details]
## Summary
Session started on {current_timestamp}. Ready to capture context.
```
### Step 7: Update Active Session Tracker
1. Write the session name to `.claude/sessions/.active-session` (single line, just the name)
2. This marks it as the currently active session
### Step 7.5: Initialize .auto-capture-state with Session Status
Create `.claude/sessions/{name}/.auto-capture-state` with initial session status:
```bash
echo '{
"interaction_count": 0,
"modified_files": [],
"last_snapshot_timestamp": null,
"session_status": "active",
"session_started": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",
"session_closed": null
}' > .claude/sessions/{name}/.auto-capture-state
```
This initializes the operational state tracking for the session, including the session status which is now tracked in JSON for fast, atomic updates.
### Step 8: Update Index (NEW - CRITICAL)
Run the CLI command to add the new session to the metadata index:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js update-index --session {name}
```
This ensures the new session appears immediately in `/session:list` without requiring a full rebuild.
### Step 9: Display Success Message
Show this confirmation to the user:
```
✓ Session '{name}' started
📁 Location: .claude/sessions/{name}/
💡 Use /session:save to capture important milestones
📊 Check /session:status to monitor tokens
Ready to work! What would you like to accomplish in this session?
```
### Step 10: Ask for Session Goal
After showing the success message, ask the user:
"What is the main goal or purpose of this session? (This will be saved to session.md)"
Wait for their response, then update the "Goal" section in session.md with their answer.
---
**PERFORMANCE BENEFITS:**
- **Before:** No index integration, sessions invisible until manual list command scans
- **After:** Instant index update, session immediately visible in list
- **Improvement:** Better UX, no stale index issues
**IMPORTANT:**
- Execute all steps in order
- Use the Read, Write, and Bash tools to perform file operations
- The CLI update-index command is fast (< 10ms) and ensures consistency
- Do not skip any steps
---
## CRITICAL: Check for Unconsolidated Logs (Inline Analysis)
**IMPORTANT:** New session start should NOT have unconsolidated logs, but check anyway for robustness.
**MUST CHECK BEFORE DISPLAYING SUCCESS MESSAGE:**
After starting the session, check if previous session left unconsolidated logs:
1. Check if `.claude/sessions/{name}/conversation-log.jsonl` exists
2. If the file exists:
- Show brief message: "📊 Analyzing previous session... (this may take 1-3 seconds)"
- Read the conversation log file
- Parse interactions from JSONL format
- **Capture git history (if available):**
- Run: `node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js capture-git "{name}"`
- This creates `.claude/sessions/{name}/git-history.json` (~2-3KB compressed)
- Contains: last 50 commits, uncommitted changes, branch status, hotspots
- Performance: ~60-90ms (acceptable at session boundary)
- If no git repo, command returns success: false (silent skip, no error)
- Analyze the conversation with Claude inline:
- Extract conversation summary (2-3 paragraphs covering what happened)
- Identify key decisions made with rationale
- List completed todos/tasks
- Document files modified with context about what changed and why
- Assess current state, what's next, and any blockers
- Create consolidated snapshot via CLI:
```bash
echo "# Consolidated Snapshot: {session_name}
**Timestamp**: {ISO timestamp}
**Method**: Claude Inline Analysis (Free)
**Status**: Consolidated from conversation log
**Format Version**: 2.0
## Topics Discussed
1. **[Category]**: [Brief description of what was discussed]
2. **[Category]**: [Brief description of what was discussed]
[Continue for ALL topics in chronological order]
## Suggestions & Recommendations
1. **[Category]**: [Specific suggestion] - [Rationale]
2. **[Category]**: [Specific suggestion] - [Rationale]
[Continue for ALL suggestions]
## Decisions Made
1. **[Decision]**: [Rationale and context]
2. **[Decision]**: [Rationale and context]
[Continue for ALL decisions]
## Tasks Completed
1. [Action completed in past tense]
2. [Action completed in past tense]
[Continue for ALL tasks]
## Files Modified
1. `[file_path]`: [What changed and why]
2. `[file_path]`: [What changed and why]
[Continue for ALL files]
## Current Status
- **Progress**: [Where things stand - what's been accomplished]
- **Next Steps**: [What should be done next]
- **Blockers**: [Issues or write \"None\"]
## Notes
Consolidated via Claude inline analysis at session boundary. Zero cost, highest quality." | node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js write-snapshot "{name}" --stdin --type auto
```
- Delete conversation-log.jsonl after successful snapshot creation
- Update `.auto-capture-state` to reset counters and set last_snapshot_timestamp
3. If no log exists:
- **Still capture git history** for repository context:
- Run: `node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js capture-git "{name}"`
- This provides git context even for new sessions
- Silent skip if no git repo (no error)
- Initialize `.auto-capture-state` if needed
**PERFORMANCE:**
- Log check: <5ms
- Claude analysis: 1-3s (acceptable at session boundaries - users expect loading)
- Snapshot write: <50ms
- Log deletion: <5ms
- **Total: ~1-3 seconds** (users expect loading at session start)
**NOTE:** This is the v3.5.1 architecture where conversation logging is incremental (<2ms per interaction) and consolidation happens inline at session boundaries using FREE Claude analysis for highest quality.

153
commands/status.md Normal file
View File

@@ -0,0 +1,153 @@
You are managing a session memory system. The user wants to check the current session status.
## Task: Display Session Status (Ultra-Minimal)
Show essential session information quickly and efficiently.
**OPTIMIZATION:** Ultra-minimal output. Uses CLI for instant stats (<50ms, <50 tokens).
### Step 1: Get Active Session from CLI
Run the CLI command to get session list and find active session:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js list
```
Parse the JSON response to get `activeSession` field.
If `activeSession` is null, show error:
```
❌ No active session
💡 /session:start [name] to create new session
💡 /session:continue [name] to resume existing session
```
Then STOP.
### Step 2: Get Session Statistics
Run the CLI stats command for the active session:
```bash
node ${CLAUDE_PLUGIN_ROOT}/cli/session-cli.js stats {activeSession}
```
This returns JSON with:
- Session metadata (status, started, lastUpdated, goal)
- Snapshot counts (snapshotCount)
- File counts (filesInvolvedCount)
### Step 3: Calculate Session Duration
Parse the `started` timestamp from stats (format: "2025-11-13 14:30").
Calculate duration from start time to now:
1. Parse started date/time
2. Calculate difference in minutes
3. Format as:
- If < 60 min: "Xm" (e.g., "45m")
- If < 24 hours: "Xh Ym" (e.g., "2h 15m" or "5h 0m")
- If >= 24 hours: "Xd Yh" (e.g., "2d 3h")
### Step 4: Calculate Time Since Last Activity
Parse `lastUpdated` timestamp (ISO format: "2025-11-14T10:27:04.345Z").
Calculate time since last update:
1. Parse ISO timestamp
2. Calculate difference from now
3. Format as relative time:
- "just now" (< 1 min)
- "Xm ago" (< 60 min)
- "Xh ago" (< 24 hours)
- "Xd ago" (>= 24 hours)
### Step 5: Display Ultra-Minimal Status
Show clean, essential information only:
```
✓ Session: {sessionName} ({status})
Working for: {duration} (started {started_short})
Snapshots: {snapshotCount} total
Files: {filesInvolvedCount} tracked
Last activity: {time_since_last_update}
💡 /session:save to capture milestones
💡 /session:close to finalize
```
**Format notes:**
- {status}: "active" or "closed"
- {started_short}: "Nov 14, 14:30" format
- All numbers: plain integers (no formatting)
- No emojis except status indicator (✓)
- No Unicode art, no progress bars
- 5 lines max
### Example Output
**Active session:**
```
✓ Session: feature-auth (active)
Working for: 2h 15m (started Nov 14, 14:30)
Snapshots: 12 total
Files: 7 tracked
Last activity: 30m ago
💡 /session:save to capture milestones
💡 /session:close to finalize
```
**Recently started:**
```
✓ Session: bug-fix-login (active)
Working for: 15m (started Nov 14, 18:45)
Snapshots: 1 total
Files: 2 tracked
Last activity: just now
💡 /session:save to capture milestones
💡 /session:close to finalize
```
**Closed session:**
```
✓ Session: refactor-api (closed)
Worked for: 5h 30m (started Nov 13, 09:00)
Snapshots: 18 total
Files: 12 tracked
Last activity: 2d ago
💡 /session:continue {sessionName} to resume
```
---
**PERFORMANCE:**
- **Tokens:** ~50 tokens (vs 150 before) - **66% reduction**
- **Speed:** <50ms (CLI delegation)
- **Lines:** 5-7 lines (vs 15-20 before) - **70% reduction**
**WHAT WAS REMOVED:**
- ❌ Token usage tracking (unreliable, verbose)
- ❌ Progress bars (unnecessary decoration)
- ❌ Warning messages (not reliable)
- ❌ Unicode art (bloat)
- ❌ Total size display (rarely useful)
- ❌ Auto vs manual snapshot breakdown (not essential)
**WHAT WAS KEPT:**
- ✅ Session name and status
- ✅ Duration (how long working)
- ✅ Snapshot count (progress indicator)
- ✅ File count (scope indicator)
- ✅ Last activity (freshness indicator)
- ✅ Quick action tips
**FOR TOKEN USAGE:** Users should run `/context` directly for accurate real-time token information.
**ERROR HANDLING:**
- If CLI command fails, show error and suggest rebuilding index
- If timestamps can't be parsed, show raw values

71
hooks/hooks.json Normal file
View File

@@ -0,0 +1,71 @@
{
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/session-start.js"
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/user-prompt-submit.js"
}
]
}
],
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/post-tool-use.js"
}
]
},
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/post-tool-use.js"
}
]
},
{
"matcher": "NotebookEdit",
"hooks": [
{
"type": "command",
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/post-tool-use.js"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/stop.js"
}
]
}
],
"SessionEnd": [
{
"hooks": [
{
"type": "command",
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/session-end.js"
}
]
}
]
}

188
hooks/post-tool-use.js Executable file
View File

@@ -0,0 +1,188 @@
#!/usr/bin/env node
// Intelligent Post-Tool-Use Hook - Tracks file modifications for smart analysis
// Works with async analysis system for intelligent snapshots
//
// SAFETY: Includes graceful failure handling to avoid blocking Claude Code
// if plugin is uninstalled or dependencies are missing.
const fs = require('fs');
const path = require('path');
// Graceful failure wrapper - protect against plugin uninstallation
try {
// Check if critical dependencies exist (indicates plugin is installed)
const cliLibPath = path.join(__dirname, '../cli/lib');
if (!fs.existsSync(cliLibPath)) {
// Plugin likely uninstalled, exit silently
process.exit(0);
}
const LockManager = require('../cli/lib/lock-manager');
// Read tool operation data from stdin (Claude Code provides this as JSON)
// NOTE: Do NOT use process.env.CLAUDE_TOOL_NAME - it's always "unknown" due to Claude Code bug
let toolName = 'unknown';
let filePath = null;
try {
const input = fs.readFileSync(0, 'utf8').trim();
if (input) {
const eventData = JSON.parse(input);
// Get tool name from stdin data (NOT environment variable)
toolName = eventData.tool_name || 'unknown';
// Extract file path from tool input
// Different tools use different field names for file paths
if (eventData.tool_input) {
if (eventData.tool_input.file_path) {
filePath = eventData.tool_input.file_path;
} else if (eventData.tool_input.notebook_path) {
// NotebookEdit uses notebook_path instead of file_path
filePath = eventData.tool_input.notebook_path;
}
}
}
} catch (err) {
// If we can't read stdin or parse it, exit early
process.exit(0);
}
// Only track file modifications (Write, Edit, and NotebookEdit tools)
if (toolName !== 'Write' && toolName !== 'Edit' && toolName !== 'NotebookEdit') {
process.exit(0);
}
// Configuration
const SESSIONS_DIR = '.claude/sessions';
const ACTIVE_SESSION_FILE = path.join(SESSIONS_DIR, '.active-session');
const lockManager = new LockManager(SESSIONS_DIR);
// Exit early if no active session
if (!fs.existsSync(ACTIVE_SESSION_FILE)) {
process.exit(0);
}
// Read active session name
let activeSession;
try {
activeSession = fs.readFileSync(ACTIVE_SESSION_FILE, 'utf8').trim();
} catch (err) {
process.exit(0);
}
if (!activeSession) {
process.exit(0);
}
const sessionDir = path.join(SESSIONS_DIR, activeSession);
if (!fs.existsSync(sessionDir)) {
process.exit(0);
}
// Check if auto-capture is enabled
const sessionMd = path.join(sessionDir, 'session.md');
if (fs.existsSync(sessionMd)) {
try {
const content = fs.readFileSync(sessionMd, 'utf8');
if (content.includes('Auto-capture: disabled')) {
process.exit(0);
}
} catch (err) {
// Continue if we can't read the file
}
}
// State file
const stateFile = path.join(sessionDir, '.auto-capture-state');
// Use lock to prevent race conditions with user-prompt-submit.js hook
const lock = lockManager.acquireLock(`auto-capture-${activeSession}`, {
timeout: 1000,
wait: true
});
if (!lock.acquired) {
// Could not acquire lock - skip this update to avoid blocking
// The file will be captured on next tool use
process.exit(0);
}
try {
// Initialize state if doesn't exist
let state = {
file_count: 0,
interaction_count: 0,
interactions_since_last_analysis: 0,
last_snapshot: '',
last_reason: '',
last_analysis_timestamp: '',
modified_files: [] // Track actual file paths
};
if (fs.existsSync(stateFile)) {
try {
state = JSON.parse(fs.readFileSync(stateFile, 'utf8'));
} catch (err) {
// Use default state if parse fails
}
}
// Increment file count
state.file_count++;
// Track the modified file path if we captured it
if (filePath) {
// Initialize modified_files array if it doesn't exist (backward compatibility)
if (!state.modified_files) {
state.modified_files = [];
}
// Add file to list if not already tracked
const fileEntry = {
path: filePath,
operation: toolName.toLowerCase(),
timestamp: new Date().toISOString()
};
// Avoid duplicates - check if file already in list
const existingIndex = state.modified_files.findIndex(f => f.path === filePath);
if (existingIndex >= 0) {
// Update existing entry with latest operation
state.modified_files[existingIndex] = fileEntry;
} else {
// Add new file
state.modified_files.push(fileEntry);
}
}
// Update state atomically
// Note: We no longer immediately create snapshot markers here
// Instead, the file_count contributes to analysis queue logic in user-prompt-submit.js
const tempPath = `${stateFile}.tmp.${Date.now()}`;
try {
fs.writeFileSync(tempPath, JSON.stringify(state, null, 2));
fs.renameSync(tempPath, stateFile);
} catch (writeError) {
// Clean up temp file
if (fs.existsSync(tempPath)) {
try {
fs.unlinkSync(tempPath);
} catch (cleanupError) {
// Ignore
}
}
throw writeError;
}
} finally {
// Always release lock
lock.release();
}
process.exit(0);
} catch (error) {
// Outer catch: Handle plugin missing/uninstalled
// Exit silently to avoid blocking Claude Code
process.exit(0);
}

111
hooks/session-end.js Executable file
View File

@@ -0,0 +1,111 @@
#!/usr/bin/env node
/**
* SessionEnd Hook
*
* Handles cleanup when Claude Code session terminates.
* Ensures .active-session file is removed and index is updated.
*
* Hook receives:
* - session_id: string
* - transcript_path: string
* - cwd: string
* - permission_mode: string
* - hook_event_name: "SessionEnd"
* - reason: "exit" | "clear" | "logout" | "prompt_input_exit" | "other"
*
* SAFETY: Includes graceful failure handling to avoid blocking Claude Code shutdown
* if plugin is uninstalled or dependencies are missing.
*/
const fs = require('fs');
const path = require('path');
// Graceful failure wrapper - protect against plugin uninstallation
try {
// Check if critical dependencies exist (indicates plugin is installed)
const cliLibPath = path.join(__dirname, '../cli/lib');
if (!fs.existsSync(cliLibPath)) {
// Plugin likely uninstalled, exit silently
process.exit(0);
}
const IndexManager = require('../cli/lib/index-manager');
// Constants
const SESSIONS_DIR = '.claude/sessions';
const ACTIVE_SESSION_FILE = path.join(SESSIONS_DIR, '.active-session');
const indexManager = new IndexManager(SESSIONS_DIR);
try {
// Read input from stdin (provided by Claude Code)
const input = fs.readFileSync(0, 'utf8').trim();
// Parse the JSON input
let eventData;
try {
eventData = JSON.parse(input);
} catch (parseError) {
// If parsing fails, exit silently (no input provided)
process.exit(0);
}
// Clean up active session marker
let sessionName = null;
if (fs.existsSync(ACTIVE_SESSION_FILE)) {
try {
sessionName = fs.readFileSync(ACTIVE_SESSION_FILE, 'utf8').trim();
} catch (readError) {
// Continue even if read fails
}
// Delete the .active-session file
try {
fs.unlinkSync(ACTIVE_SESSION_FILE);
} catch (unlinkError) {
// File may already be deleted, continue
}
}
// Mark session as closed in .auto-capture-state (fast, atomic)
if (sessionName) {
const sessionDir = path.join(SESSIONS_DIR, sessionName);
const statePath = path.join(sessionDir, '.auto-capture-state');
if (fs.existsSync(statePath)) {
try {
let state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
state.session_status = 'closed';
state.session_closed = new Date().toISOString();
fs.writeFileSync(statePath, JSON.stringify(state, null, 2));
} catch (stateError) {
// Silent fail - hook must be safe
// Session status update failed but continue with other cleanup
}
}
}
// Update the index.json to clear activeSession using IndexManager
// This uses proper locking and atomic writes to prevent corruption
try {
const index = indexManager.read({ skipValidation: true });
index.activeSession = null;
indexManager.write(index);
} catch (indexError) {
// Continue even if index update fails
// This prevents blocking the hook if index is temporarily locked
}
// Exit successfully
process.exit(0);
} catch (error) {
// Exit silently on any errors to avoid blocking Claude Code shutdown
process.exit(0);
}
} catch (error) {
// Outer catch: Handle plugin missing/uninstalled
// Exit silently to avoid blocking Claude Code
process.exit(0);
}

110
hooks/session-start.js Executable file
View File

@@ -0,0 +1,110 @@
#!/usr/bin/env node
/**
* SessionStart Hook
*
* Handles session state cleanup when /clear is executed.
* Clears active session markers to prevent confusion when context is lost.
*
* Hook receives:
* - source: "startup" | "resume" | "clear" | "compact"
* - session_id: string
* - cwd: string
* - permission_mode: string
*
* SAFETY: Includes graceful failure handling to avoid blocking Claude Code
* if plugin is uninstalled or dependencies are missing.
*/
const fs = require('fs');
const path = require('path');
// Graceful failure wrapper - protect against plugin uninstallation
try {
// Check if critical dependencies exist (indicates plugin is installed)
const cliLibPath = path.join(__dirname, '../cli/lib');
if (!fs.existsSync(cliLibPath)) {
// Plugin likely uninstalled, exit silently
process.exit(0);
}
// Import IndexManager for safe index updates
const IndexManager = require('../cli/lib/index-manager');
// Constants
const SESSIONS_DIR = '.claude/sessions';
const ACTIVE_SESSION_FILE = path.join(SESSIONS_DIR, '.active-session');
const indexManager = new IndexManager(SESSIONS_DIR);
try {
// Read input from stdin (provided by Claude Code)
const input = fs.readFileSync(0, 'utf8').trim();
// Parse the JSON input
let eventData;
try {
eventData = JSON.parse(input);
} catch (parseError) {
// If parsing fails, exit silently (no input provided)
process.exit(0);
}
const { source } = eventData;
// Only process when source is "clear"
// Other sources ("startup", "resume", "compact") should allow normal auto-resume
if (source === 'clear') {
let sessionName = null;
// Read the active session name before clearing (for the message)
if (fs.existsSync(ACTIVE_SESSION_FILE)) {
try {
sessionName = fs.readFileSync(ACTIVE_SESSION_FILE, 'utf8').trim();
} catch (readError) {
// Continue even if read fails
}
// Clear the .active-session file
try {
fs.unlinkSync(ACTIVE_SESSION_FILE);
} catch (unlinkError) {
// File may already be deleted, continue
}
}
// Update the index.json to clear activeSession using IndexManager
// This uses proper locking and atomic writes to prevent corruption
try {
const index = indexManager.read({ skipValidation: true });
index.activeSession = null;
indexManager.write(index);
} catch (indexError) {
// Continue even if index update fails
// This prevents blocking the hook if index is temporarily locked
}
// Inject helpful context message to Claude
const output = {
hookSpecificOutput: {
additionalContext: sessionName
? `📋 Session '${sessionName}' was auto-closed due to /clear command. The conversation context has been cleared.\n\nTo resume your work on this session, use: /session:continue ${sessionName}\nTo view all sessions, use: /session:list`
: 'Previous session was auto-closed due to /clear command. Use /session:list to view available sessions.'
}
};
// Output the context injection
console.log(JSON.stringify(output));
}
// Exit successfully
process.exit(0);
} catch (error) {
// Exit silently on any errors to avoid blocking Claude Code startup
process.exit(0);
}
} catch (error) {
// Outer catch: Handle plugin missing/uninstalled
// Exit silently to avoid blocking Claude Code
process.exit(0);
}

210
hooks/stop.js Executable file
View File

@@ -0,0 +1,210 @@
#!/usr/bin/env node
// Stop Hook - Captures Claude's complete response for self-contained conversation logs
// This hook fires after Claude completes each response
//
// SAFETY: Includes graceful failure handling to avoid blocking Claude Code
// if plugin is uninstalled or dependencies are missing.
const fs = require('fs');
const path = require('path');
// Graceful failure wrapper - protect against plugin uninstallation
try {
// Check if critical dependencies exist (indicates plugin is installed)
const cliLibPath = path.join(__dirname, '../cli/lib');
if (!fs.existsSync(cliLibPath)) {
// Plugin likely uninstalled, exit silently
process.exit(0);
}
const LockManager = require('../cli/lib/lock-manager');
// Read stdin to get transcript path
let stdinData;
try {
const stdinInput = fs.readFileSync(0, 'utf8').trim();
if (!stdinInput) {
process.exit(0);
}
stdinData = JSON.parse(stdinInput);
} catch (stdinErr) {
// Cannot parse stdin, exit silently
process.exit(0);
}
const transcriptPath = stdinData.transcript_path;
if (!transcriptPath || !fs.existsSync(transcriptPath)) {
// No transcript path or file doesn't exist
process.exit(0);
}
// Read transcript file to get Claude's last response (with exponential backoff retry)
// Uses smart retry strategy: fast success path (0-50ms), patient for edge cases (750ms max)
const MAX_RETRIES = 5;
const RETRY_DELAYS = [0, 50, 100, 200, 400]; // Exponential backoff in milliseconds
function tryFindAssistantMessage() {
try {
const transcriptContent = fs.readFileSync(transcriptPath, 'utf8');
const lines = transcriptContent.trim().split('\n');
// Find last assistant message (search backwards for efficiency)
for (let i = lines.length - 1; i >= 0; i--) {
try {
const entry = JSON.parse(lines[i]);
// Claude Code transcript format: {type: 'assistant', message: {role, content}}
if (entry.type === 'assistant' && entry.message) {
return entry.message; // Return the message object which has role and content
}
} catch (parseErr) {
// Skip malformed lines
continue;
}
}
return null;
} catch (readErr) {
return null;
}
}
// Sleep function for retry delays
function sleep(ms) {
const start = Date.now();
while (Date.now() - start < ms) {
// Busy wait (acceptable for short delays in hooks)
}
}
// Try to find assistant message with exponential backoff retries
let lastAssistantMessage = null;
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
lastAssistantMessage = tryFindAssistantMessage();
if (lastAssistantMessage) {
break;
}
// If not found and not last attempt, wait with exponential backoff
if (attempt < MAX_RETRIES) {
const nextDelay = RETRY_DELAYS[attempt]; // Next delay for next attempt
sleep(nextDelay);
}
}
if (!lastAssistantMessage) {
// No assistant message found after all retries
process.exit(0);
}
// Configuration
const SESSIONS_DIR = '.claude/sessions';
const ACTIVE_SESSION_FILE = path.join(SESSIONS_DIR, '.active-session');
// Exit early if no active session
if (!fs.existsSync(ACTIVE_SESSION_FILE)) {
process.exit(0);
}
// Read active session name
let activeSession;
try {
activeSession = fs.readFileSync(ACTIVE_SESSION_FILE, 'utf8').trim();
} catch (err) {
process.exit(0);
}
if (!activeSession) {
process.exit(0);
}
const sessionDir = path.join(SESSIONS_DIR, activeSession);
if (!fs.existsSync(sessionDir)) {
process.exit(0);
}
// Check if auto-capture is enabled
const sessionMd = path.join(sessionDir, 'session.md');
if (fs.existsSync(sessionMd)) {
try {
const content = fs.readFileSync(sessionMd, 'utf8');
if (content.includes('Auto-capture: disabled')) {
process.exit(0);
}
} catch (err) {
// Continue if we can't read the file
}
}
// Use lock to prevent race conditions
const lockManager = new LockManager(SESSIONS_DIR);
const lock = lockManager.acquireLock(`auto-capture-${activeSession}`, {
timeout: 1000,
wait: true
});
if (!lock.acquired) {
// Could not acquire lock - skip this update to avoid blocking
process.exit(0);
}
try {
// Extract tool uses from response
const toolUses = [];
if (lastAssistantMessage.content && Array.isArray(lastAssistantMessage.content)) {
lastAssistantMessage.content.forEach(block => {
if (block.type === 'tool_use') {
toolUses.push({
tool: block.name,
input: block.input,
id: block.id || null
});
}
});
}
// Helper to extract text from content blocks
function extractTextContent(content) {
if (typeof content === 'string') {
return content;
}
if (Array.isArray(content)) {
return content
.filter(block => block.type === 'text')
.map(block => block.text)
.join('\n');
}
return '';
}
const responseText = extractTextContent(lastAssistantMessage.content);
// Log Claude's response
const ConversationLogger = require('../cli/lib/conversation-logger');
const logger = new ConversationLogger(sessionDir);
logger.logAssistantResponse({
timestamp: new Date().toISOString(),
response_text: responseText,
tools_used: toolUses,
message_id: lastAssistantMessage.id || null
});
} catch (error) {
// Silent failure - don't block hook execution
} finally {
// Always release lock
lock.release();
}
process.exit(0);
} catch (error) {
// Outer catch: Handle plugin missing/uninstalled
// Exit silently to avoid blocking Claude Code
process.exit(0);
}

226
hooks/user-prompt-submit.js Executable file
View File

@@ -0,0 +1,226 @@
#!/usr/bin/env node
// Truly Automatic Auto-Capture Hook - Creates snapshots automatically
// This hook creates snapshot files directly via CLI with NO manual intervention
// Snapshots are created every N interactions or when file thresholds are met
//
// SAFETY: Includes graceful failure handling to avoid blocking Claude Code
// if plugin is uninstalled or dependencies are missing.
//
// ORPHAN DETECTION: Periodically checks for orphaned hooks and auto-cleans them
const fs = require('fs');
const path = require('path');
// Graceful failure wrapper - protect against plugin uninstallation
try {
// Check if critical dependencies exist (indicates plugin is installed)
const cliLibPath = path.join(__dirname, '../cli/lib');
if (!fs.existsSync(cliLibPath)) {
// Plugin likely uninstalled, exit silently
process.exit(0);
}
const LockManager = require('../cli/lib/lock-manager');
// Configuration
const SESSIONS_DIR = '.claude/sessions';
const ACTIVE_SESSION_FILE = path.join(SESSIONS_DIR, '.active-session');
const lockManager = new LockManager(SESSIONS_DIR);
// Living Context Configuration
const CONTEXT_UPDATE_THRESHOLD = 2; // Update context every 2 interactions (lightweight)
const SNAPSHOT_THRESHOLD = 5; // Full snapshot every 5 interactions (heavier)
// Exit early if no active session
if (!fs.existsSync(ACTIVE_SESSION_FILE)) {
process.exit(0);
}
// Read active session name
let activeSession;
try {
activeSession = fs.readFileSync(ACTIVE_SESSION_FILE, 'utf8').trim();
} catch (err) {
process.exit(0);
}
if (!activeSession) {
process.exit(0);
}
const sessionDir = path.join(SESSIONS_DIR, activeSession);
if (!fs.existsSync(sessionDir)) {
process.exit(0);
}
// Check if auto-capture is enabled
const sessionMd = path.join(sessionDir, 'session.md');
if (fs.existsSync(sessionMd)) {
try {
const content = fs.readFileSync(sessionMd, 'utf8');
if (content.includes('Auto-capture: disabled')) {
process.exit(0);
}
} catch (err) {
// Continue if we can't read the file
}
}
// File paths
const stateFile = path.join(sessionDir, '.auto-capture-state');
// Use lock to prevent race conditions during state read-modify-write
const lock = lockManager.acquireLock(`auto-capture-${activeSession}`, {
timeout: 1000,
wait: true
});
if (!lock.acquired) {
// Could not acquire lock - skip this update to avoid blocking
// The next interaction will pick up the count
process.exit(0);
}
try {
// Initialize state if doesn't exist
let state = {
file_count: 0,
interaction_count: 0,
interactions_since_context_update: 0,
interactions_since_snapshot: 0,
last_context_update: '',
last_snapshot_timestamp: ''
};
if (fs.existsSync(stateFile)) {
try {
state = JSON.parse(fs.readFileSync(stateFile, 'utf8'));
// Ensure Living Context fields exist
state.interactions_since_context_update = state.interactions_since_context_update || 0;
state.interactions_since_snapshot = state.interactions_since_snapshot || 0;
state.last_context_update = state.last_context_update || '';
state.last_snapshot_timestamp = state.last_snapshot_timestamp || '';
} catch (err) {
// Use default state if parse fails
}
}
// Increment interaction count
state.interaction_count++;
state.interactions_since_context_update++;
state.interactions_since_snapshot++;
// INCREMENTAL LOGGING SYSTEM: Log conversation for later consolidation
// This replaces the blocking snapshot system with fast (~1-2ms) logging
const timestamp = new Date().toISOString();
// Read stdin to get transcript path and user prompt
let transcriptPath = null;
let userPrompt = null;
try {
const stdinData = fs.readFileSync(0, 'utf8').trim();
if (stdinData) {
const eventData = JSON.parse(stdinData);
transcriptPath = eventData.transcript_path || null;
userPrompt = eventData.prompt || null;
}
} catch (stdinErr) {
// If we can't read stdin, continue without transcript path
// This ensures hook doesn't fail if stdin format changes
}
// Log interaction incrementally (non-blocking, ~1-2ms)
try {
const ConversationLogger = require('../cli/lib/conversation-logger');
const logger = new ConversationLogger(sessionDir);
logger.logInteraction({
num: state.interaction_count,
timestamp: timestamp,
transcript_path: transcriptPath,
user_prompt: userPrompt,
state: state,
modified_files: state.modified_files || []
});
} catch (err) {
// Silent failure - don't block hook execution
// Consolidation will work with whatever data is available
}
// Note: Snapshot consolidation now happens at session start/continue
// via consolidate-worker.js running in background
// This eliminates the 10-15 second blocking issue
// Update state file atomically
const tempPath = `${stateFile}.tmp.${Date.now()}`;
try {
fs.writeFileSync(tempPath, JSON.stringify(state, null, 2));
fs.renameSync(tempPath, stateFile);
} catch (writeError) {
// Clean up temp file
if (fs.existsSync(tempPath)) {
try {
fs.unlinkSync(tempPath);
} catch (cleanupError) {
// Ignore
}
}
throw writeError;
}
} finally {
// Always release lock
lock.release();
}
// ORPHAN DETECTION: Check for orphaned hooks every 20 prompts
// This auto-cleans up hooks if plugin was uninstalled without cleanup
try {
const orphanCheckFile = path.join(SESSIONS_DIR, '.orphan-check-counter');
let checkCounter = 0;
if (fs.existsSync(orphanCheckFile)) {
try {
checkCounter = parseInt(fs.readFileSync(orphanCheckFile, 'utf8').trim(), 10) || 0;
} catch (e) {
// Use default
}
}
checkCounter++;
// Check every 20 prompts
if (checkCounter >= 20) {
const HooksManager = require('../cli/lib/hooks-manager');
const pluginRoot = path.dirname(__dirname);
const manager = new HooksManager(process.cwd());
// Detect orphaned hooks
const settings = manager.readSettings();
const orphaned = manager.detectOrphanedHooks(settings, pluginRoot);
if (orphaned.length > 0) {
// Auto-cleanup orphaned hooks
const cleaned = manager.removePluginHooks(settings, pluginRoot);
manager.createBackup();
manager.writeSettings(cleaned);
// NOTE: We cannot inject context here as this is UserPromptSubmit hook
// The cleanup happens silently in the background
}
checkCounter = 0; // Reset counter
}
// Write counter back
fs.writeFileSync(orphanCheckFile, checkCounter.toString());
} catch (orphanError) {
// Silent failure - don't block hook execution
}
process.exit(0);
} catch (error) {
// Outer catch: Handle plugin missing/uninstalled
// Exit silently to avoid blocking Claude Code
process.exit(0);
}

153
plugin.lock.json Normal file
View File

@@ -0,0 +1,153 @@
{
"$schema": "internal://schemas/plugin.lock.v1.json",
"pluginId": "gh:awudevelop/claude-plugins:session",
"normalized": {
"repo": null,
"ref": "refs/tags/v20251128.0",
"commit": "6ec7a588b3153f448ed95229402b71570157359c",
"treeHash": "064dd651da7c4c8e8214c1c6289c9072110d35aa2e92a597f7db105870faca37",
"generatedAt": "2025-11-28T10:14:05.352142Z",
"toolVersion": "publish_plugins.py@0.2.0"
},
"origin": {
"remote": "git@github.com:zhongweili/42plugin-data.git",
"branch": "master",
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
},
"manifest": {
"name": "session",
"description": "v3.17.4 - Advanced session management for Claude Code with intelligent context tracking, automatic snapshots, and git history capture. Features zero-blocking conversation logging, AI-powered analysis, and optimized parallel subagent architecture. Never lose context!",
"version": "3.17.4"
},
"content": {
"files": [
{
"path": "README.md",
"sha256": "3c319320ab963e04cd6c699198b7f6db1b3d89804a940d8f6cf1c12c11abf37c"
},
{
"path": "hooks/stop.js",
"sha256": "37a676c6d29bff787dd6f3d18b86e4e14c92c0699c7ff32a352da3208c59d203"
},
{
"path": "hooks/post-tool-use.js",
"sha256": "4917273a37d71ecda0dc832cd1c452a3e8b7335a9984600301f644d5d9d486da"
},
{
"path": "hooks/session-start.js",
"sha256": "f62f244cb4129d1b67c819e5c6dff01b8b3e4b9b6afe5183132e70bc3f38d23b"
},
{
"path": "hooks/session-end.js",
"sha256": "20a3105b844442ba037bec12db191530e8fc40fb2d0a26336f188e55434a0e7a"
},
{
"path": "hooks/hooks.json",
"sha256": "0f1dbf53520fd253698253ff9486d5ae036d3ca51af5dc9c402e37084d8f50c2"
},
{
"path": "hooks/user-prompt-submit.js",
"sha256": "b1fb6c52127d2f3d9953efef04578f762dd89982f9323ca2b50de63d026edac4"
},
{
"path": ".claude-plugin/plugin.json",
"sha256": "3af37a81dae483514f556399eaba1620a25a8f6a6b9c5a527977adffe6cda128"
},
{
"path": "commands/plan-list.md",
"sha256": "693693eb8e5cd2006b9c4fa1f6b49ecf0633d9266bd2d08f665b293c66f99962"
},
{
"path": "commands/project-maps-stats.md",
"sha256": "a374903c057cba5fecca3d7c74da3f350d69c59ef79c356f54516b9b5d437b95"
},
{
"path": "commands/plan-status.md",
"sha256": "8d16bcb657e39a8511e4ae9aa8e20ddb3b4a33e208d1e19bf97370b3d4a365b7"
},
{
"path": "commands/plan-finalize.md",
"sha256": "454a4840bb50554491864231774d6260f896a1e39955ceda2d1814e770327641"
},
{
"path": "commands/project-maps-load.md",
"sha256": "d1f854feeda94633aa2a0846bb4a1c1cd4193765055f84fda564dd4a211c42b0"
},
{
"path": "commands/plan-save.md",
"sha256": "f3e2eddab439fccbfac377a18834262b0548e3d9ebd95e809bab7089f6035849"
},
{
"path": "commands/continue.md",
"sha256": "5980d87156eecdd37a4457d9e786047a1fe72e6d3fbe9454525897fc7a25d954"
},
{
"path": "commands/setup.md",
"sha256": "2d98544ae5c7de808eb768cca498ef85ffb698a35440d965384687c28345f234"
},
{
"path": "commands/status.md",
"sha256": "cdcfb2408bfced31d88cb0e630f51912a36ce74e90874bf76f06d2062d068381"
},
{
"path": "commands/plan-execute.md",
"sha256": "fbb322c14fdbc6c6f6be144a311e0f85487ffc9ed42902c2ad114d5bd969541a"
},
{
"path": "commands/continue.md.v3.6.4.backup",
"sha256": "2bf5ae7c4e32882a698f7551cad3551f59f6254fef465419ba9b25d1e3359857"
},
{
"path": "commands/project-maps-refresh.md",
"sha256": "e1a33fed3e0663826ec6d7d3ee3d4d9df84d95f6b205a8cc6bc93b02ab850a17"
},
{
"path": "commands/list.md",
"sha256": "1646d0b1670563cd520649efacdf09946a65f48c9d5d2ed49a9723b91d9d56f8"
},
{
"path": "commands/close.md",
"sha256": "888bd9d87e8f2b0a4360ee36f1661a2cfbc0a0f5f8a40aa880ff4b266d7a4c9f"
},
{
"path": "commands/project-maps-query.md",
"sha256": "6abcad95011a19f3f89de02efa5ca0d698abde6c7c7c2f4746c5bb2c16d448b1"
},
{
"path": "commands/git-decompress.md",
"sha256": "eb3585f1fa09c96785d8d6b0ccfcbf0c6e7078b52969b0914a338233ab84b4bd"
},
{
"path": "commands/delete.md",
"sha256": "10aa0161ee9a2dd3b29b02d6b7061f591d64ee9c6810c337ec7c4a7593137561"
},
{
"path": "commands/save.md",
"sha256": "5fc88d41d7c9dd80cfee82cf01f886452bf461557533286841bd8f7bf5f54a10"
},
{
"path": "commands/project-maps-generate.md",
"sha256": "7d1183f203b4fa3f51705c999d66ac4963af275b661129d1f4f61adc9bfe6b76"
},
{
"path": "commands/start.md",
"sha256": "ef5fb5dde77fdaecd887c384c0926c1987822c42f885b40cbe5794a9893439ec"
},
{
"path": "commands/project-maps-list.md",
"sha256": "d01bb7d92e97dae0e09742997dd15c42672ca45e735502f199d6beb899106313"
},
{
"path": "commands/plan-update.md",
"sha256": "9c0bb605c3d31f36999a128cfee4a677c2ec7f2d61c9da178ac3c6cf9fe254a9"
}
],
"dirSha256": "064dd651da7c4c8e8214c1c6289c9072110d35aa2e92a597f7db105870faca37"
},
"security": {
"scannedAt": null,
"scannerVersion": null,
"flags": []
}
}