Initial commit
This commit is contained in:
15
.claude-plugin/plugin.json
Normal file
15
.claude-plugin/plugin.json
Normal 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
3
README.md
Normal 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
187
commands/close.md
Normal 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
359
commands/continue.md
Normal 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}
|
||||||
199
commands/continue.md.v3.6.4.backup
Normal file
199
commands/continue.md.v3.6.4.backup
Normal 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
207
commands/delete.md
Normal 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
124
commands/git-decompress.md
Normal 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
231
commands/list.md
Normal 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
195
commands/plan-execute.md
Normal 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
403
commands/plan-finalize.md
Normal 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
148
commands/plan-list.md
Normal 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
285
commands/plan-save.md
Normal 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
174
commands/plan-status.md
Normal 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
344
commands/plan-update.md
Normal 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
|
||||||
212
commands/project-maps-generate.md
Normal file
212
commands/project-maps-generate.md
Normal 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
|
||||||
|
```
|
||||||
120
commands/project-maps-list.md
Normal file
120
commands/project-maps-list.md
Normal 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
|
||||||
|
```
|
||||||
301
commands/project-maps-load.md
Normal file
301
commands/project-maps-load.md
Normal 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
|
||||||
|
```
|
||||||
297
commands/project-maps-query.md
Normal file
297
commands/project-maps-query.md
Normal 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
|
||||||
|
```
|
||||||
176
commands/project-maps-refresh.md
Normal file
176
commands/project-maps-refresh.md
Normal 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
|
||||||
139
commands/project-maps-stats.md
Normal file
139
commands/project-maps-stats.md
Normal 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
215
commands/save.md
Normal 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
369
commands/setup.md
Normal 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
293
commands/start.md
Normal 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
153
commands/status.md
Normal 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
71
hooks/hooks.json
Normal 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
188
hooks/post-tool-use.js
Executable 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
111
hooks/session-end.js
Executable 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
110
hooks/session-start.js
Executable 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
210
hooks/stop.js
Executable 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
226
hooks/user-prompt-submit.js
Executable 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
153
plugin.lock.json
Normal 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": []
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user