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-management",
|
||||
"description": "Git-native session lifecycle management with context preservation, checkpoint tracking, and seamless handoffs between coding sessions",
|
||||
"version": "0.0.5",
|
||||
"author": {
|
||||
"name": "AnthemFlynn",
|
||||
"email": "AnthemFlynn@users.noreply.github.com"
|
||||
},
|
||||
"skills": [
|
||||
"./skills"
|
||||
],
|
||||
"commands": [
|
||||
"./commands"
|
||||
]
|
||||
}
|
||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# session-management
|
||||
|
||||
Git-native session lifecycle management with context preservation, checkpoint tracking, and seamless handoffs between coding sessions
|
||||
99
commands/checkpoint.md
Normal file
99
commands/checkpoint.md
Normal file
@@ -0,0 +1,99 @@
|
||||
---
|
||||
description: Create session checkpoint with automatic state capture
|
||||
---
|
||||
|
||||
# Checkpoint Workflow
|
||||
|
||||
Execute the session-management skill's checkpoint workflow to save progress.
|
||||
|
||||
## Step 1: Analyze Current State
|
||||
|
||||
The checkpoint manager will automatically analyze:
|
||||
- Git changes (modified, added, deleted files)
|
||||
- TDD metrics (if TDD mode active)
|
||||
- Session metrics (time elapsed, objectives completed)
|
||||
|
||||
## Step 2: Gather Optional Inputs (if desired)
|
||||
|
||||
Use `AskUserQuestion` to ask if the user wants to provide additional context:
|
||||
|
||||
Ask: "Would you like to add notes or create a git commit with this checkpoint?"
|
||||
|
||||
Options:
|
||||
- **Just save checkpoint** - Create checkpoint document only
|
||||
- **Add notes** - Prompt for checkpoint notes (proceed to Question 2a)
|
||||
- **Add notes and commit** - Prompt for notes and create git commit (proceed to Question 2a and 2b)
|
||||
- **Commit without notes** - Skip notes, create commit with auto-generated message (proceed to Question 2b)
|
||||
|
||||
### Question 2a: Checkpoint Notes (if requested)
|
||||
|
||||
Ask: "What notes would you like to add to this checkpoint?"
|
||||
|
||||
Options:
|
||||
- **"Completed [feature/task]"** - Standard completion note
|
||||
- **"Work in progress on [area]"** - WIP note
|
||||
- **"Blocked on [issue]"** - Blocker note
|
||||
- **Other** - Let user type custom notes
|
||||
|
||||
### Question 2b: Git Commit (if requested)
|
||||
|
||||
Ask: "Should we create a git commit for this checkpoint?"
|
||||
|
||||
Options:
|
||||
- **Auto-generate commit message** - Use checkpoint analysis to create message
|
||||
- **Custom commit message** - Let user type custom message
|
||||
- **Skip commit** - Just save checkpoint, no git commit
|
||||
|
||||
## Step 3: Execute Checkpoint
|
||||
|
||||
Based on collected inputs, execute the checkpoint command:
|
||||
|
||||
```bash
|
||||
cd ${CLAUDE_PLUGIN_ROOT}/skills/session-management/scripts
|
||||
|
||||
# Basic checkpoint (no notes, no commit)
|
||||
python session.py checkpoint
|
||||
|
||||
# With notes
|
||||
python session.py checkpoint --notes "[user notes]"
|
||||
|
||||
# With notes and commit
|
||||
python session.py checkpoint --notes "[user notes]" --commit
|
||||
|
||||
# With commit and custom message
|
||||
python session.py checkpoint --commit --message "[custom message]"
|
||||
|
||||
# With TDD phase tracking
|
||||
python session.py checkpoint --tdd-phase [RED|GREEN|REFACTOR]
|
||||
```
|
||||
|
||||
The script will:
|
||||
- Analyze git diff for changes
|
||||
- Capture current metrics
|
||||
- Generate checkpoint document
|
||||
- Save to `.sessions/checkpoints/checkpoint_[timestamp].md`
|
||||
- Optionally create git commit
|
||||
|
||||
## Step 4: Confirm Checkpoint Saved
|
||||
|
||||
Report to user:
|
||||
- Checkpoint file location
|
||||
- Summary of changes captured
|
||||
- Git commit hash (if commit created)
|
||||
- Current session progress
|
||||
|
||||
---
|
||||
|
||||
## Use This Command
|
||||
|
||||
At logical milestones during work:
|
||||
- After completing a sub-task
|
||||
- Before switching contexts
|
||||
- When you want to save progress
|
||||
- After each TDD cycle (RED, GREEN, REFACTOR)
|
||||
|
||||
## Integration Notes
|
||||
|
||||
- Integrates with **tdd-workflow** for automatic phase tracking
|
||||
- Checkpoints saved to `.sessions/checkpoints/` directory
|
||||
- Git commits tagged with checkpoint metadata
|
||||
128
commands/session-end.md
Normal file
128
commands/session-end.md
Normal file
@@ -0,0 +1,128 @@
|
||||
---
|
||||
description: End session with comprehensive handoff generation
|
||||
---
|
||||
|
||||
# Session End Workflow
|
||||
|
||||
Execute the session-management skill's finish workflow to create a comprehensive handoff.
|
||||
|
||||
## Step 1: Create Final Checkpoint
|
||||
|
||||
First, automatically create a final checkpoint to capture the current state:
|
||||
|
||||
```bash
|
||||
cd ${CLAUDE_PLUGIN_ROOT}/skills/session-management/scripts
|
||||
python session.py checkpoint --label "session-end"
|
||||
```
|
||||
|
||||
This captures all uncommitted work and current metrics.
|
||||
|
||||
## Step 2: Gather Handoff Information
|
||||
|
||||
Use `AskUserQuestion` to collect information for the handoff document:
|
||||
|
||||
### Question 1: What Did You Accomplish?
|
||||
|
||||
Ask: "What did you accomplish in this session?"
|
||||
|
||||
Options:
|
||||
- Analyze the session checkpoints and git commits to suggest:
|
||||
- **"Completed [feature/task from objectives]"**
|
||||
- **"Fixed [issues addressed]"**
|
||||
- **"Implemented [components created]"**
|
||||
- **"Refactored [areas improved]"**
|
||||
- **Other** - Let user type custom accomplishments
|
||||
|
||||
### Question 2: What Decisions Were Made?
|
||||
|
||||
Ask: "Were there any important decisions or trade-offs made during this session?"
|
||||
|
||||
Options:
|
||||
- **"Chose [technology/approach] because [reason]"** - Technical decision
|
||||
- **"Decided to defer [feature] due to [constraint]"** - Scope decision
|
||||
- **"No major decisions"** - Skip this section
|
||||
- **Other** - Let user type custom decisions
|
||||
|
||||
### Question 3: What Should Next Session Remember?
|
||||
|
||||
Ask: "What context or next steps should be documented for the next session?"
|
||||
|
||||
Options:
|
||||
- **"Continue with [specific task]"** - Next task note
|
||||
- **"Watch out for [potential issue]"** - Warning note
|
||||
- **"Remember to [action item]"** - Action reminder
|
||||
- **"Review [code/docs] before proceeding"** - Review reminder
|
||||
- **Other** - Let user type custom notes
|
||||
|
||||
### Question 4: Git Push Options
|
||||
|
||||
Ask: "Should we push commits to the remote repository?"
|
||||
|
||||
Options:
|
||||
- **Yes, push to remote** - Push all commits (proceed with confirmation)
|
||||
- **No, keep local** - Don't push (useful for WIP)
|
||||
- **Ask for confirmation first** - Show what will be pushed, then confirm
|
||||
|
||||
## Step 3: Generate Handoff Document
|
||||
|
||||
Based on collected inputs, execute the session end command:
|
||||
|
||||
```bash
|
||||
cd ${CLAUDE_PLUGIN_ROOT}/skills/session-management/scripts
|
||||
|
||||
# Generate handoff and push
|
||||
python session.py end --push
|
||||
|
||||
# Generate handoff without push
|
||||
python session.py end --no-push
|
||||
|
||||
# With merge to main
|
||||
python session.py end --merge-to main --push
|
||||
```
|
||||
|
||||
The script will:
|
||||
- Generate comprehensive handoff document with:
|
||||
- Session summary (start time, duration, objectives)
|
||||
- Accomplishments (from collected inputs)
|
||||
- Decisions made (from collected inputs)
|
||||
- Context for next session (from collected inputs)
|
||||
- Metrics (commits, files changed, tests added)
|
||||
- Git status (branch, uncommitted changes)
|
||||
- Save to `.sessions/handoffs/handoff_[timestamp].md`
|
||||
- Optionally push commits to remote
|
||||
- Update session state to "ended"
|
||||
|
||||
## Step 4: Confirm and Finalize
|
||||
|
||||
Report to user:
|
||||
- Handoff document location
|
||||
- Session summary (time spent, accomplishments)
|
||||
- Git status (commits pushed, branch state)
|
||||
- Next session recommendations
|
||||
|
||||
Optionally ask:
|
||||
|
||||
Ask: "Would you like to merge this branch?"
|
||||
|
||||
Options:
|
||||
- **Merge to main** - Merge current branch to main
|
||||
- **Merge to develop** - Merge to develop branch
|
||||
- **Create pull request** - Guide PR creation
|
||||
- **Keep branch** - Don't merge, keep for next session
|
||||
|
||||
---
|
||||
|
||||
## Use This Command
|
||||
|
||||
When ending a work session:
|
||||
- End of day or before extended break
|
||||
- After completing feature or fix
|
||||
- Before context switching to different project
|
||||
- When wrapping up and need handoff for future you or teammates
|
||||
|
||||
## Integration Notes
|
||||
|
||||
- Integrates with **tdd-workflow** for test metrics in handoff
|
||||
- Uses checkpoint system for comprehensive state capture
|
||||
- Handoffs saved to `.sessions/handoffs/` directory
|
||||
- Session state preserved in `.sessions/state.json`
|
||||
135
commands/session-start.md
Normal file
135
commands/session-start.md
Normal file
@@ -0,0 +1,135 @@
|
||||
---
|
||||
description: Start or resume coding session with AI-guided context loading
|
||||
---
|
||||
|
||||
# Session Start Workflow
|
||||
|
||||
Execute the session-management skill's start workflow using this step-by-step process.
|
||||
|
||||
## Step 1: Generate Project Status Report
|
||||
|
||||
First, generate a comprehensive project status report to understand current state:
|
||||
|
||||
```bash
|
||||
python ${CLAUDE_PLUGIN_ROOT}/skills/project-status-report/scripts/report.py
|
||||
```
|
||||
|
||||
Or invoke the project-status-report skill if available.
|
||||
|
||||
The report will show:
|
||||
- Health indicators (tests, linting, coverage)
|
||||
- Git status (current branch, uncommitted changes, active branches)
|
||||
- Recent session summary
|
||||
- Open work items (TODOs, FIXMEs, objectives)
|
||||
|
||||
## Step 2: Gather User Inputs via AskUserQuestion
|
||||
|
||||
Use the `AskUserQuestion` tool to collect session configuration. Ask the following questions:
|
||||
|
||||
### Question 1: What to Work On
|
||||
|
||||
Ask: "What would you like to work on in this session?"
|
||||
|
||||
Options:
|
||||
- **Resume existing work** - Continue from where you left off
|
||||
- **Start new work** - Begin a new feature or task
|
||||
- **Address health issues** - Fix test failures or other critical issues from the report
|
||||
|
||||
### Question 2: Branch Selection
|
||||
|
||||
Ask: "Which branch would you like to work on?"
|
||||
|
||||
Options should include:
|
||||
- All active branches from the git status (show current branch indicator and last commit date)
|
||||
- **Create new branch** option
|
||||
|
||||
**If user selects "Create new branch"**, proceed to Question 2a and 2b.
|
||||
|
||||
#### Question 2a: Branch Type (if creating new)
|
||||
|
||||
Ask: "What type of branch would you like to create?"
|
||||
|
||||
Options:
|
||||
- **Hotfix branch** (hotfix/...) - For urgent bug fixes
|
||||
- **Feature branch** (feature/...) - For new features
|
||||
- **Bugfix branch** (fix/...) - For non-urgent bug fixes
|
||||
- **Other** - Custom branch prefix
|
||||
|
||||
#### Question 2b: Branch Name (if creating new)
|
||||
|
||||
Ask: "What should we name the branch?"
|
||||
|
||||
Options:
|
||||
- Suggest intelligent defaults based on:
|
||||
- Branch type selected
|
||||
- Health issues from report (e.g., "fix/test-failures")
|
||||
- TODOs from report (e.g., "feature/oauth-integration")
|
||||
- User's stated objective
|
||||
- **Other** - Let user type custom name
|
||||
|
||||
### Question 3: Session Objectives
|
||||
|
||||
Ask: "What are your objectives for this session?"
|
||||
|
||||
Options:
|
||||
- Suggest objectives based on context:
|
||||
- "Fix [specific health issue]"
|
||||
- "Implement [TODO item]"
|
||||
- "Complete [work from last session]"
|
||||
- **Other** - Let user type custom objectives
|
||||
|
||||
## Step 3: Execute Session Start
|
||||
|
||||
Based on the collected inputs, execute the session.py script:
|
||||
|
||||
```bash
|
||||
cd ${CLAUDE_PLUGIN_ROOT}/skills/session-management/scripts
|
||||
python session.py start [branch-name] --objective "[objectives]"
|
||||
```
|
||||
|
||||
**Additional flags:**
|
||||
- Add `--tdd` if objectives involve implementing features or fixing bugs
|
||||
- Add `--resume` if user selected "Resume existing work"
|
||||
|
||||
The script will:
|
||||
- Checkout or create the specified branch
|
||||
- Initialize session state in `.sessions/state.json`
|
||||
- Update plugin coordination state in `.ccmp/state.json`
|
||||
- Load relevant context files (claude.md, architecture docs)
|
||||
|
||||
## Step 4: Load Session Context
|
||||
|
||||
After session initialization:
|
||||
|
||||
1. Check if `.sessions/state.json` was created successfully
|
||||
2. Read any relevant claude.md files for the work area
|
||||
3. Load previous session context if resuming
|
||||
4. Present a summary to the user:
|
||||
- Current branch
|
||||
- Session objectives
|
||||
- Relevant context loaded
|
||||
- Next suggested actions
|
||||
|
||||
## Step 5: Ready to Work
|
||||
|
||||
Confirm to the user:
|
||||
- Session is initialized
|
||||
- Branch is ready
|
||||
- Context is loaded
|
||||
- Ready to begin work on stated objectives
|
||||
|
||||
---
|
||||
|
||||
## Use This Command When
|
||||
|
||||
- Starting work on a project after a break
|
||||
- Returning after context switch between projects
|
||||
- Beginning a new feature or bugfix
|
||||
- Need to load full project context quickly
|
||||
|
||||
## Integration Notes
|
||||
|
||||
This command integrates with:
|
||||
- **project-status-report** - For comprehensive health overview
|
||||
- **claude-context-manager** - Auto-loads relevant claude.md files
|
||||
- **tdd-workflow** - Enables TDD mode tracking if --tdd flag used
|
||||
105
plugin.lock.json
Normal file
105
plugin.lock.json
Normal file
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"$schema": "internal://schemas/plugin.lock.v1.json",
|
||||
"pluginId": "gh:AnthemFlynn/ccmp:plugins/session-management",
|
||||
"normalized": {
|
||||
"repo": null,
|
||||
"ref": "refs/tags/v20251128.0",
|
||||
"commit": "717f716bef947623e2ae573208bdbf7d5c2c898a",
|
||||
"treeHash": "841fddade57f2e447a999df435b365df614f7a544b6313477b2f74e7c9ebb2b6",
|
||||
"generatedAt": "2025-11-28T10:24:51.939630Z",
|
||||
"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-management",
|
||||
"description": "Git-native session lifecycle management with context preservation, checkpoint tracking, and seamless handoffs between coding sessions",
|
||||
"version": "0.0.5"
|
||||
},
|
||||
"content": {
|
||||
"files": [
|
||||
{
|
||||
"path": "README.md",
|
||||
"sha256": "4a69b16c77fcc61583c89fdc3bf1317bef5e8398cb20bdcece177d8fa636f431"
|
||||
},
|
||||
{
|
||||
"path": ".claude-plugin/plugin.json",
|
||||
"sha256": "7a482d185c5dc8cb3f3023f52e8a34f9f35c0a1fe9d07d4fc82cb528f64de0c3"
|
||||
},
|
||||
{
|
||||
"path": "commands/checkpoint.md",
|
||||
"sha256": "630f45de60ca09ad9ffbe3a3e7a4d3b111e7c2250750708eae342a669489a320"
|
||||
},
|
||||
{
|
||||
"path": "commands/session-end.md",
|
||||
"sha256": "b53f13ef8a6b86953959b862457c21d0797833cff2bdc616874068f4a2e2f866"
|
||||
},
|
||||
{
|
||||
"path": "commands/session-start.md",
|
||||
"sha256": "014e22b9721d33cdea53e4894400cbbda13739536a616089b727de1c595a692e"
|
||||
},
|
||||
{
|
||||
"path": "skills/session-management/SKILL.md",
|
||||
"sha256": "cc8f293fd1e611c7d350bb18d83a0fdeabe49dd07f2b2d4a7ec32c428598dc6e"
|
||||
},
|
||||
{
|
||||
"path": "skills/session-management/references/handoff-template.md",
|
||||
"sha256": "e3ff6f85b2b39a02b5599f7124036331eaad8bef0d0296b372729a4969170de3"
|
||||
},
|
||||
{
|
||||
"path": "skills/session-management/references/commands.md",
|
||||
"sha256": "a5f64a4b775b3466f8a11c7e7a86a6f6a71cc53207045744a0ae33757b922113"
|
||||
},
|
||||
{
|
||||
"path": "skills/session-management/references/config-reference.md",
|
||||
"sha256": "645fa8863e0af490b8620bc7104491bb2950e2e2881eabf1aef4c49a38d039f8"
|
||||
},
|
||||
{
|
||||
"path": "skills/session-management/scripts/checkpoint.py",
|
||||
"sha256": "5092d7e016b4f714f537cebbb4f15c2c07f219b19755b54ad072b9d1bb399933"
|
||||
},
|
||||
{
|
||||
"path": "skills/session-management/scripts/handoff.py",
|
||||
"sha256": "7d4a64eb7f5ae8023dc13c66563382656d7d60a94822b0be1249d9eb15debe04"
|
||||
},
|
||||
{
|
||||
"path": "skills/session-management/scripts/session.py",
|
||||
"sha256": "87e5e3fe3bd406a88fc03f07862113c07e9b417acd8546f935cc3b18ade1002a"
|
||||
},
|
||||
{
|
||||
"path": "skills/session-management/scripts/test_handoff.py",
|
||||
"sha256": "8d3c769249f5aae1692035fdc93777223a3bcd8785195d7316a07b53e69acb76"
|
||||
},
|
||||
{
|
||||
"path": "skills/session-management/scripts/init_session.py",
|
||||
"sha256": "154d48a5d549df61ac599835e1068068b38bcdb60e060e4b30ad18e06b03dff7"
|
||||
},
|
||||
{
|
||||
"path": "skills/session-management/scripts/test_checkpoint.py",
|
||||
"sha256": "53bbec8d4d2fbaf4f7f755cccac84fd8baeee23fa8f510e5032397ec46286336"
|
||||
},
|
||||
{
|
||||
"path": "skills/session-management/assets/conventions-template.md",
|
||||
"sha256": "0346227a75ebe2630a495ed2d2ccc4d0e21eff296d8b19c0d716a3a40709413c"
|
||||
},
|
||||
{
|
||||
"path": "skills/session-management/assets/architecture-template.md",
|
||||
"sha256": "2051373aaef9b9a4fb3621e48d4333ccf3f94277067093eb07a650e72aca0e12"
|
||||
},
|
||||
{
|
||||
"path": "skills/session-management/assets/config-template.yaml",
|
||||
"sha256": "cccb8ac956e1a2cb65d52e4678da3e9bbec81f3f783ccab7e9dd244f884f7daf"
|
||||
}
|
||||
],
|
||||
"dirSha256": "841fddade57f2e447a999df435b365df614f7a544b6313477b2f74e7c9ebb2b6"
|
||||
},
|
||||
"security": {
|
||||
"scannedAt": null,
|
||||
"scannerVersion": null,
|
||||
"flags": []
|
||||
}
|
||||
}
|
||||
466
skills/session-management/SKILL.md
Normal file
466
skills/session-management/SKILL.md
Normal file
@@ -0,0 +1,466 @@
|
||||
---
|
||||
name: session-management
|
||||
description: Git-native session lifecycle management for software development. Use when starting/resuming coding sessions, creating checkpoints, tracking objectives and blockers, generating handoffs between sessions, or needing context preservation across work sessions. Provides intelligent onboarding for AI coding agents by loading comprehensive project context.
|
||||
---
|
||||
|
||||
# Session Management
|
||||
|
||||
Manage coding sessions with git-native workflows, intelligent context preservation, and seamless agent onboarding.
|
||||
|
||||
## Core Concept
|
||||
|
||||
**Sessions = Branches + Context**
|
||||
|
||||
Session management enhances git workflows by:
|
||||
- Mapping branches to work sessions with objectives
|
||||
- Creating enhanced commits with decision metadata
|
||||
- Tracking progress, blockers, and architectural decisions
|
||||
- Generating comprehensive handoffs between sessions
|
||||
- Providing instant context loading for AI agents
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Initialize in Project
|
||||
|
||||
```bash
|
||||
python scripts/init_session.py
|
||||
```
|
||||
|
||||
Creates `.sessions/` directory with:
|
||||
- `config.yaml` - Session configuration (optional)
|
||||
- `checkpoints/` - Checkpoint storage
|
||||
- `state.json` - Current session state
|
||||
|
||||
### Core Workflows
|
||||
|
||||
**Important**: All slash commands use the `AskUserQuestion` tool to gather inputs interactively. The Python scripts accept CLI arguments, so commands collect user choices via multiple-choice prompts, then execute scripts with those arguments.
|
||||
|
||||
#### Session Start (`/session-start`)
|
||||
|
||||
**Rapid re-immersion for both human and AI**
|
||||
|
||||
```bash
|
||||
/session-start
|
||||
```
|
||||
|
||||
**What happens:**
|
||||
1. **Project status report generated** - Health, git status, recent work, open items
|
||||
2. **Interactive prompts via AskUserQuestion** - User selects what to work on, which branch, and session objectives through multiple-choice questions
|
||||
3. **Branch selection** - Choose from active branches or create new (hotfix/feature/bugfix)
|
||||
4. **Context loaded** - Architecture, decisions, patterns from last session
|
||||
5. **Session ready** - Both human and AI fully contextualized
|
||||
|
||||
**Use when:**
|
||||
- Starting work on a project
|
||||
- Returning after days away
|
||||
- Context switching between projects
|
||||
|
||||
#### Create Checkpoint (`/checkpoint`)
|
||||
|
||||
**Quick save points during work**
|
||||
|
||||
```bash
|
||||
/checkpoint
|
||||
```
|
||||
|
||||
**What happens:**
|
||||
1. **Automatic capture** - Git diff, metrics, TDD cycles analyzed
|
||||
2. **Interactive prompts via AskUserQuestion** - User chooses whether to add notes, create git commit, or both
|
||||
3. **Checkpoint saved** - Comprehensive snapshot generated
|
||||
4. **Git commit** - Optionally create commit with auto-generated or custom message
|
||||
|
||||
**Use when:**
|
||||
- At logical milestones
|
||||
- Completing sub-tasks
|
||||
- Before switching contexts
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Simple checkpoint
|
||||
python scripts/session.py checkpoint --label "oauth-complete"
|
||||
|
||||
# Checkpoint with notes and git commit
|
||||
python scripts/session.py checkpoint --label "feature-complete" --notes "OAuth flow tested" --commit
|
||||
|
||||
# With custom commit message
|
||||
python scripts/session.py checkpoint --label "bugfix" --commit --message "fix: resolve auth token expiry"
|
||||
```
|
||||
|
||||
#### End Session (`/session-end`)
|
||||
|
||||
**Comprehensive knowledge capture and handoff**
|
||||
|
||||
```bash
|
||||
/session-end
|
||||
```
|
||||
|
||||
**What happens:**
|
||||
1. **Final checkpoint created** - Captures current state
|
||||
2. **Interactive prompts via AskUserQuestion** - User provides session accomplishments, decisions made, and context for next session
|
||||
3. **Handoff generated** - Full session summary with metrics and next steps
|
||||
4. **Git push** - User chooses whether to push commits to remote
|
||||
5. **State saved** - Ready for next session
|
||||
|
||||
**Use when:**
|
||||
- Finishing work session
|
||||
- End of day
|
||||
- Before extended break
|
||||
|
||||
## Session Lifecycle
|
||||
|
||||
**START** → Load full project context with status report
|
||||
**WORK** → Track changes automatically in background
|
||||
**CHECKPOINT** → Save progress with automatic git analysis
|
||||
**END** → Generate handoff with comprehensive session summary
|
||||
|
||||
## Key Features
|
||||
|
||||
### 1. Objectives Management
|
||||
|
||||
Track what you're trying to accomplish:
|
||||
|
||||
```bash
|
||||
# Add objective
|
||||
python scripts/session.py objectives add "Implement OAuth2 integration"
|
||||
|
||||
# Mark complete
|
||||
python scripts/session.py objectives complete obj-1
|
||||
|
||||
# List all
|
||||
python scripts/session.py objectives list
|
||||
```
|
||||
|
||||
### 2. Blocker Tracking
|
||||
|
||||
Record impediments:
|
||||
|
||||
```bash
|
||||
# Add blocker
|
||||
python scripts/session.py blockers add "Waiting on API keys"
|
||||
|
||||
# Resolve
|
||||
python scripts/session.py blockers resolve blk-1
|
||||
```
|
||||
|
||||
### 3. Decision Logging
|
||||
|
||||
Capture architectural decisions with context:
|
||||
|
||||
```bash
|
||||
# Record decision
|
||||
python scripts/session.py decisions add "Using repository pattern for data access" \
|
||||
--rationale "Separates domain logic from persistence" \
|
||||
--alternatives "Active Record: Too coupled to database"
|
||||
```
|
||||
|
||||
### 4. Context Queries
|
||||
|
||||
Check current state:
|
||||
|
||||
```bash
|
||||
# Full status
|
||||
python scripts/session.py status
|
||||
|
||||
# Just objectives
|
||||
python scripts/session.py status --objectives
|
||||
|
||||
# History
|
||||
python scripts/session.py history --count 10
|
||||
```
|
||||
|
||||
## Agent Onboarding
|
||||
|
||||
When AI agents (like Claude Code) start, session management provides instant context:
|
||||
|
||||
```python
|
||||
# Automatically loads on agent start:
|
||||
# - Project architecture pattern
|
||||
# - Code conventions
|
||||
# - Recent decisions
|
||||
# - Current objectives
|
||||
# - Active blockers
|
||||
# - Git history analysis
|
||||
# - File changes summary
|
||||
```
|
||||
|
||||
Agent receives structured brief including:
|
||||
- What we're building (objectives)
|
||||
- How to build it (architecture, patterns, conventions)
|
||||
- What's done (progress)
|
||||
- What's next (next actions)
|
||||
- What to watch for (blockers, TODOs)
|
||||
|
||||
## Storage Structure
|
||||
|
||||
```
|
||||
project/
|
||||
├── .session/ # Git-tracked, shared across team
|
||||
│ ├── config.yaml # Configuration
|
||||
│ ├── architecture.md # Architecture documentation
|
||||
│ ├── conventions.md # Code conventions
|
||||
│ └── decision-log.md # All decisions (auto-generated)
|
||||
│
|
||||
└── .git/
|
||||
└── sessions/ # Local, developer-specific
|
||||
└── <branch>/
|
||||
├── objectives.md
|
||||
├── blockers.md
|
||||
└── context.json
|
||||
```
|
||||
|
||||
**Design principle**: Shared context (architecture, conventions) is git-tracked. Personal workflow data (objectives, notes) stays local.
|
||||
|
||||
## Configuration
|
||||
|
||||
Edit `.session/config.yaml`:
|
||||
|
||||
```yaml
|
||||
session:
|
||||
auto_track: true # Track file changes automatically
|
||||
handoff_on_end: true # Generate handoff when ending
|
||||
|
||||
context:
|
||||
architecture: hexagonal # Your architecture pattern
|
||||
patterns: # Patterns to enforce
|
||||
- repository-pattern
|
||||
- dependency-injection
|
||||
|
||||
tracking:
|
||||
watch_patterns: # Files to monitor
|
||||
- "src/**/*.py"
|
||||
- "tests/**/*.py"
|
||||
```
|
||||
|
||||
## Workflows
|
||||
|
||||
### Daily Development
|
||||
|
||||
```bash
|
||||
# Morning: Resume work
|
||||
python scripts/session.py resume
|
||||
|
||||
# During work: Checkpoint at milestones
|
||||
python scripts/session.py checkpoint --label "api-complete"
|
||||
|
||||
# Evening: End with handoff
|
||||
python scripts/session.py end
|
||||
```
|
||||
|
||||
### Context Switching
|
||||
|
||||
```bash
|
||||
# Urgent bug comes in
|
||||
python scripts/session.py switch hotfix/critical-bug
|
||||
|
||||
# Fix bug
|
||||
python scripts/session.py checkpoint --message "Fix security issue"
|
||||
python scripts/session.py end --merge-to main
|
||||
|
||||
# Back to feature
|
||||
python scripts/session.py resume feature/main-work
|
||||
```
|
||||
|
||||
### Team Handoffs
|
||||
|
||||
```bash
|
||||
# Generate comprehensive handoff
|
||||
python scripts/session.py end --handoff --summary
|
||||
|
||||
# Next developer loads context
|
||||
python scripts/session.py resume <branch>
|
||||
```
|
||||
|
||||
## Enhanced Commits
|
||||
|
||||
Session checkpoints create git commits with rich metadata:
|
||||
|
||||
```
|
||||
feat(auth): Implement OAuth2 provider
|
||||
|
||||
Completed Google OAuth flow with PKCE support.
|
||||
|
||||
Session-Objectives:
|
||||
- [x] OAuth provider interface
|
||||
- [▶] Google OAuth (this commit)
|
||||
- [ ] GitHub OAuth (next)
|
||||
|
||||
Decisions:
|
||||
- Using PKCE flow for enhanced security
|
||||
Rationale: Protection against code interception
|
||||
|
||||
Impact:
|
||||
- Added: src/auth/oauth_provider.py
|
||||
- Tests: +12 unit tests
|
||||
- Coverage: 79% → 84%
|
||||
|
||||
Session-Time: 2h 15m
|
||||
```
|
||||
|
||||
## Advanced Features
|
||||
|
||||
### Session Analysis
|
||||
|
||||
```bash
|
||||
# Analyze session health
|
||||
python scripts/session.py analyze
|
||||
|
||||
# Calculate velocity
|
||||
python scripts/session.py analyze --velocity
|
||||
|
||||
# Pattern detection
|
||||
python scripts/session.py analyze --patterns
|
||||
```
|
||||
|
||||
### Session History
|
||||
|
||||
```bash
|
||||
# Recent sessions with metrics
|
||||
python scripts/session.py history --count 5 --metrics
|
||||
|
||||
# Compare sessions
|
||||
python scripts/session.py compare <session-id>
|
||||
```
|
||||
|
||||
### Reports
|
||||
|
||||
```bash
|
||||
# Weekly summary
|
||||
python scripts/session.py report --weekly
|
||||
|
||||
# Project summary
|
||||
python scripts/session.py report --project --format markdown
|
||||
```
|
||||
|
||||
## Bundled Resources
|
||||
|
||||
### Scripts
|
||||
|
||||
- **`init_session.py`** - Initialize session management in project
|
||||
- **`session.py`** - Main CLI for all session operations
|
||||
- **`analyze_git.py`** - Git history analysis utilities
|
||||
|
||||
### References
|
||||
|
||||
- **`commands.md`** - Complete command reference
|
||||
- **`handoff-template.md`** - Template for session handoffs
|
||||
- **`config-reference.md`** - All configuration options
|
||||
|
||||
### Assets
|
||||
|
||||
- **`config-template.yaml`** - Default configuration
|
||||
- **`architecture-template.md`** - Architecture documentation template
|
||||
- **`conventions-template.md`** - Conventions template
|
||||
|
||||
## Best Practices
|
||||
|
||||
**For Solo Development:**
|
||||
- Start every session with objectives
|
||||
- Checkpoint at logical milestones
|
||||
- Record decisions when making them
|
||||
- End sessions with handoffs (helps future you)
|
||||
|
||||
**For Teams:**
|
||||
- Commit `.session/` directory (shared context)
|
||||
- Keep personal workflow local
|
||||
- Link blockers to issue tracker
|
||||
- Generate handoffs for transitions
|
||||
|
||||
**For AI-Assisted Development:**
|
||||
- Session management provides instant agent context
|
||||
- No need to re-explain project structure
|
||||
- Architectural patterns automatically enforced
|
||||
- Decisions preserved across sessions
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Session not loading?**
|
||||
```bash
|
||||
python scripts/session.py status --verbose
|
||||
python scripts/session.py start --resume
|
||||
```
|
||||
|
||||
**Need to reinitialize?**
|
||||
```bash
|
||||
python scripts/init_session.py --force
|
||||
```
|
||||
|
||||
**View current configuration:**
|
||||
```bash
|
||||
cat .session/config.yaml
|
||||
```
|
||||
|
||||
## CCMP Plugin Integration
|
||||
|
||||
Session management **automatically integrates** with other CCMP plugins:
|
||||
|
||||
### With claude-context-manager 📚
|
||||
**Auto-loads relevant context on session start:**
|
||||
```bash
|
||||
python scripts/session.py start feature/auth
|
||||
# → Automatically loads src/auth/claude.md
|
||||
# → Shows context health warnings
|
||||
# → Includes patterns and gotchas in brief
|
||||
```
|
||||
|
||||
**Checkpoints trigger context health checks:**
|
||||
```bash
|
||||
python scripts/session.py checkpoint --label "api-complete"
|
||||
# → Detects src/api/ changed
|
||||
# → Warns if context is stale
|
||||
# → Offers: "Update context? [y/N]"
|
||||
```
|
||||
|
||||
**Handoffs include context health:**
|
||||
```bash
|
||||
python scripts/session.py end --handoff
|
||||
# → Includes context health score
|
||||
# → Lists files needing updates
|
||||
# → Recommends maintenance for next session
|
||||
```
|
||||
|
||||
### With tdd-workflow 🧪
|
||||
**TDD mode automatically enhances sessions:**
|
||||
```bash
|
||||
python scripts/session.py start feature/auth --tdd
|
||||
# → TDD workflow detects and activates
|
||||
# → Automatic RED-GREEN-REFACTOR checkpoints
|
||||
# → TDD metrics in session status
|
||||
# → Test coverage tracking
|
||||
```
|
||||
|
||||
**Session analysis detects TDD:**
|
||||
```bash
|
||||
python scripts/session.py analyze
|
||||
# → Shows TDD cycles completed
|
||||
# → Detects commits without tests
|
||||
# → Reports discipline violations
|
||||
```
|
||||
|
||||
### Integration API
|
||||
Uses `.ccmp/state.json` for plugin coordination. See `lib/ccmp_integration.py` for details.
|
||||
|
||||
**Developers:** Import the integration library:
|
||||
```python
|
||||
from lib.ccmp_integration import CCMPIntegration
|
||||
|
||||
integration = CCMPIntegration()
|
||||
if integration.is_active("session-management"):
|
||||
session = integration.get_state("session-management")
|
||||
```
|
||||
|
||||
## Integration Notes
|
||||
|
||||
Session management is designed to work with:
|
||||
- **Git** (required) - Source of truth for history
|
||||
- **Issue Trackers** (optional) - Link blockers to tickets
|
||||
- **CI/CD** (optional) - Include build status in briefings
|
||||
- **Coverage Tools** (optional) - Track quality metrics
|
||||
|
||||
For integration guides, see `references/integrations.md`.
|
||||
|
||||
## See Also
|
||||
|
||||
- **Full command reference**: See `references/commands.md`
|
||||
- **Configuration options**: See `references/config-reference.md`
|
||||
- **Handoff format**: See `references/handoff-template.md`
|
||||
- **Integration guides**: See `references/integrations.md`
|
||||
94
skills/session-management/assets/architecture-template.md
Normal file
94
skills/session-management/assets/architecture-template.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Project Architecture
|
||||
|
||||
## Architecture Pattern
|
||||
|
||||
**Pattern**: [Hexagonal / Layered / Microservices / MVC / Clean / DDD]
|
||||
|
||||
### Core Principles
|
||||
- [Principle 1]
|
||||
- [Principle 2]
|
||||
- [Principle 3]
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
[Your project structure here]
|
||||
|
||||
Example for hexagonal:
|
||||
src/
|
||||
├── domain/ # Business logic (no external dependencies)
|
||||
│ ├── models/ # Domain models
|
||||
│ ├── services/ # Business services
|
||||
│ └── exceptions/ # Domain exceptions
|
||||
├── ports/ # Interface definitions (contracts)
|
||||
│ ├── repositories/ # Data access interfaces
|
||||
│ └── providers/ # External service interfaces
|
||||
├── adapters/ # External integrations
|
||||
│ ├── database/ # Database implementations
|
||||
│ ├── api/ # External API clients
|
||||
│ └── messaging/ # Message queue adapters
|
||||
└── application/ # Use case orchestration
|
||||
└── usecases/ # Application use cases
|
||||
```
|
||||
|
||||
## Key Interfaces
|
||||
|
||||
List the important interfaces/contracts in your system:
|
||||
|
||||
- **[IRepository]**: [Description]
|
||||
- **[IService]**: [Description]
|
||||
- **[IProvider]**: [Description]
|
||||
|
||||
## Architectural Decisions
|
||||
|
||||
Document major architectural decisions:
|
||||
|
||||
### Decision 1: [Title]
|
||||
**Date**: [YYYY-MM-DD]
|
||||
**Context**: [Why this was needed]
|
||||
**Decision**: [What was decided]
|
||||
**Rationale**: [Why this approach]
|
||||
|
||||
### Decision 2: [Title]
|
||||
**Date**: [YYYY-MM-DD]
|
||||
**Context**: [Why this was needed]
|
||||
**Decision**: [What was decided]
|
||||
**Rationale**: [Why this approach]
|
||||
|
||||
## Patterns & Practices
|
||||
|
||||
### Design Patterns Used
|
||||
- **[Pattern Name]**: [Where and why used]
|
||||
- **[Pattern Name]**: [Where and why used]
|
||||
|
||||
### Best Practices
|
||||
- [Practice 1]
|
||||
- [Practice 2]
|
||||
- [Practice 3]
|
||||
|
||||
## Dependencies Flow
|
||||
|
||||
Describe how dependencies flow in your architecture:
|
||||
|
||||
```
|
||||
[Dependency flow diagram or description]
|
||||
|
||||
Example for hexagonal:
|
||||
Outside → Adapters → Ports → Domain
|
||||
↑ ↓
|
||||
← Application ←──────
|
||||
```
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
- **Unit Tests**: [What to unit test and how]
|
||||
- **Integration Tests**: [Integration boundaries]
|
||||
- **E2E Tests**: [End-to-end scenarios]
|
||||
|
||||
## Notes for Developers
|
||||
|
||||
Additional guidance for developers working in this codebase:
|
||||
|
||||
- [Important note 1]
|
||||
- [Important note 2]
|
||||
- [Important note 3]
|
||||
74
skills/session-management/assets/config-template.yaml
Normal file
74
skills/session-management/assets/config-template.yaml
Normal file
@@ -0,0 +1,74 @@
|
||||
# Session Management Configuration
|
||||
|
||||
session:
|
||||
# Automatically track file changes during session
|
||||
auto_track: true
|
||||
|
||||
# Create automatic checkpoints at intervals (false = manual only)
|
||||
auto_checkpoint: false
|
||||
checkpoint_interval: 30m
|
||||
|
||||
# Generate handoff document on session end
|
||||
handoff_on_end: true
|
||||
|
||||
# Archive completed sessions after N days
|
||||
archive_after_days: 30
|
||||
|
||||
context:
|
||||
# Primary architecture pattern for this project
|
||||
# Options: hexagonal, layered, microservices, mvc, clean, ddd
|
||||
architecture: hexagonal
|
||||
|
||||
# Code patterns to detect and enforce
|
||||
patterns:
|
||||
- repository-pattern
|
||||
- dependency-injection
|
||||
|
||||
# Project conventions
|
||||
conventions:
|
||||
- type-hints-required
|
||||
- docstrings-required
|
||||
|
||||
tracking:
|
||||
# File patterns to watch for changes
|
||||
watch_patterns:
|
||||
- "src/**/*.py"
|
||||
- "tests/**/*.py"
|
||||
- "docs/**/*.md"
|
||||
|
||||
# Patterns to ignore
|
||||
ignore_patterns:
|
||||
- "**/__pycache__/**"
|
||||
- "**/node_modules/**"
|
||||
- "**/.venv/**"
|
||||
- "**/dist/**"
|
||||
|
||||
# Annotations to track
|
||||
annotations:
|
||||
- "TODO:"
|
||||
- "FIXME:"
|
||||
- "DECISION:"
|
||||
- "BLOCKER:"
|
||||
|
||||
quality:
|
||||
# Minimum test coverage threshold (%)
|
||||
coverage_threshold: 85
|
||||
|
||||
# Require tests for new features
|
||||
require_tests: true
|
||||
|
||||
# Block merge if quality thresholds not met
|
||||
block_merge_on_quality: true
|
||||
|
||||
display:
|
||||
# Use colored terminal output
|
||||
color: true
|
||||
|
||||
# Verbosity level (false, true, debug)
|
||||
verbose: false
|
||||
|
||||
# Use emoji in output
|
||||
emoji: true
|
||||
|
||||
# Date/time format
|
||||
date_format: "%Y-%m-%d %H:%M"
|
||||
258
skills/session-management/assets/conventions-template.md
Normal file
258
skills/session-management/assets/conventions-template.md
Normal file
@@ -0,0 +1,258 @@
|
||||
# Code Conventions
|
||||
|
||||
## Language & Framework
|
||||
|
||||
**Primary Language**: [Python / JavaScript / TypeScript / etc.]
|
||||
**Version**: [Version number]
|
||||
**Framework**: [Framework name and version]
|
||||
|
||||
## Code Style
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
**Variables & Functions**:
|
||||
- Style: [snake_case / camelCase / PascalCase]
|
||||
- Examples: `user_name`, `calculate_total`, `process_payment`
|
||||
|
||||
**Classes**:
|
||||
- Style: [PascalCase / snake_case]
|
||||
- Examples: `UserService`, `PaymentProcessor`, `OrderRepository`
|
||||
|
||||
**Constants**:
|
||||
- Style: [UPPER_SNAKE_CASE / camelCase]
|
||||
- Examples: `MAX_RETRIES`, `API_BASE_URL`, `DEFAULT_TIMEOUT`
|
||||
|
||||
**Files**:
|
||||
- Style: [snake_case / kebab-case]
|
||||
- Examples: `user_service.py`, `payment-processor.ts`
|
||||
|
||||
### Formatting
|
||||
|
||||
- **Line Length**: [80 / 100 / 120] characters maximum
|
||||
- **Indentation**: [2 / 4] spaces (no tabs)
|
||||
- **String Quotes**: [single / double / either] quotes
|
||||
- **Trailing Commas**: [required / optional / never]
|
||||
|
||||
## Type Safety
|
||||
|
||||
**Type Hints/Annotations**: [Required / Encouraged / Optional]
|
||||
|
||||
```python
|
||||
# Example for Python
|
||||
def process_user(user_id: int, name: str) -> User:
|
||||
"""Process user with given ID and name."""
|
||||
pass
|
||||
```
|
||||
|
||||
**Type Checking**: [Tool name: mypy / TypeScript / Flow / None]
|
||||
|
||||
## Documentation
|
||||
|
||||
### Docstrings
|
||||
|
||||
**Style**: [Google / NumPy / Sphinx / JSDoc]
|
||||
|
||||
**Required for**:
|
||||
- [ ] Public functions
|
||||
- [ ] Public classes
|
||||
- [ ] Modules
|
||||
- [ ] Complex algorithms
|
||||
|
||||
**Example**:
|
||||
```python
|
||||
def calculate_total(items: List[Item], tax_rate: float) -> Decimal:
|
||||
"""
|
||||
Calculate total price including tax.
|
||||
|
||||
Args:
|
||||
items: List of items to total
|
||||
tax_rate: Tax rate as decimal (e.g., 0.08 for 8%)
|
||||
|
||||
Returns:
|
||||
Total price including tax
|
||||
|
||||
Raises:
|
||||
ValueError: If tax_rate is negative
|
||||
"""
|
||||
pass
|
||||
```
|
||||
|
||||
### Comments
|
||||
|
||||
**When to Comment**:
|
||||
- Complex algorithms
|
||||
- Non-obvious business logic
|
||||
- Workarounds or hacks
|
||||
- TODOs and FIXMEs
|
||||
|
||||
**What NOT to Comment**:
|
||||
- Self-explanatory code
|
||||
- What code does (let code be self-documenting)
|
||||
- Commented-out code (delete instead)
|
||||
|
||||
## Testing
|
||||
|
||||
### Test Coverage
|
||||
|
||||
- **Minimum Coverage**: [85 / 90 / 95]%
|
||||
- **New Code Coverage**: [90 / 95 / 100]%
|
||||
|
||||
### Test Organization
|
||||
|
||||
```
|
||||
tests/
|
||||
├── unit/ # Unit tests
|
||||
│ └── test_[module].py
|
||||
├── integration/ # Integration tests
|
||||
│ └── test_[feature].py
|
||||
└── e2e/ # End-to-end tests
|
||||
└── test_[scenario].py
|
||||
```
|
||||
|
||||
### Test Naming
|
||||
|
||||
Pattern: `test_[what]_[condition]_[expected]`
|
||||
|
||||
Examples:
|
||||
- `test_user_creation_with_valid_data_succeeds`
|
||||
- `test_payment_processing_with_insufficient_funds_raises_error`
|
||||
- `test_order_total_calculation_with_discount_returns_correct_amount`
|
||||
|
||||
### Test Structure
|
||||
|
||||
```python
|
||||
def test_something():
|
||||
# Arrange - Set up test data
|
||||
user = User(name="John")
|
||||
|
||||
# Act - Perform the action
|
||||
result = process_user(user)
|
||||
|
||||
# Assert - Verify results
|
||||
assert result.processed == True
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Exception Handling
|
||||
|
||||
- **Custom Exceptions**: [Required / Optional] for domain errors
|
||||
- **Logging**: [Always / Sometimes / Never] log exceptions
|
||||
- **Re-raising**: [Wrap / Re-raise / Handle] exceptions appropriately
|
||||
|
||||
**Example**:
|
||||
```python
|
||||
try:
|
||||
result = risky_operation()
|
||||
except SpecificError as e:
|
||||
logger.error(f"Operation failed: {e}")
|
||||
raise DomainError("User-friendly message") from e
|
||||
```
|
||||
|
||||
## Git Conventions
|
||||
|
||||
### Commit Messages
|
||||
|
||||
**Format**: [Conventional Commits / Custom / Free-form]
|
||||
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
|
||||
<body>
|
||||
|
||||
<footer>
|
||||
```
|
||||
|
||||
**Types**:
|
||||
- `feat`: New feature
|
||||
- `fix`: Bug fix
|
||||
- `docs`: Documentation changes
|
||||
- `style`: Code style (formatting, etc.)
|
||||
- `refactor`: Code refactoring
|
||||
- `test`: Test additions or changes
|
||||
- `chore`: Build process or auxiliary tool changes
|
||||
|
||||
**Examples**:
|
||||
```
|
||||
feat(auth): Add JWT token generation
|
||||
fix(payments): Correct tax calculation for international orders
|
||||
docs(api): Update authentication endpoint documentation
|
||||
```
|
||||
|
||||
### Branch Naming
|
||||
|
||||
**Format**: `<type>/<description>`
|
||||
|
||||
**Types**:
|
||||
- `feature/` - New features
|
||||
- `bugfix/` - Bug fixes
|
||||
- `hotfix/` - Urgent production fixes
|
||||
- `refactor/` - Code refactoring
|
||||
- `docs/` - Documentation updates
|
||||
|
||||
**Examples**:
|
||||
- `feature/user-authentication`
|
||||
- `bugfix/payment-calculation-error`
|
||||
- `hotfix/security-vulnerability`
|
||||
|
||||
## Code Review
|
||||
|
||||
### Review Checklist
|
||||
|
||||
- [ ] Code follows style guidelines
|
||||
- [ ] Tests included and passing
|
||||
- [ ] Documentation updated
|
||||
- [ ] No commented-out code
|
||||
- [ ] Error handling appropriate
|
||||
- [ ] Performance considerations addressed
|
||||
- [ ] Security implications reviewed
|
||||
|
||||
### Review Standards
|
||||
|
||||
- **Required Approvals**: [1 / 2 / 3]
|
||||
- **Automated Checks**: [Must pass / Should pass]
|
||||
- **Response Time**: [24 / 48 / 72] hours
|
||||
|
||||
## Security
|
||||
|
||||
### Security Practices
|
||||
|
||||
- [ ] No secrets in code
|
||||
- [ ] Input validation on all external data
|
||||
- [ ] SQL injection prevention
|
||||
- [ ] XSS prevention (for web apps)
|
||||
- [ ] CSRF protection (for web apps)
|
||||
- [ ] Proper authentication and authorization
|
||||
|
||||
### Sensitive Data
|
||||
|
||||
- Use environment variables for secrets
|
||||
- Never log sensitive information
|
||||
- Sanitize error messages sent to users
|
||||
|
||||
## Performance
|
||||
|
||||
### Performance Guidelines
|
||||
|
||||
- [ ] Avoid N+1 queries
|
||||
- [ ] Use appropriate data structures
|
||||
- [ ] Cache when beneficial
|
||||
- [ ] Profile before optimizing
|
||||
- [ ] Document performance-critical code
|
||||
|
||||
## Accessibility (for web projects)
|
||||
|
||||
- [ ] Semantic HTML
|
||||
- [ ] ARIA labels where needed
|
||||
- [ ] Keyboard navigation support
|
||||
- [ ] Screen reader compatibility
|
||||
- [ ] Color contrast compliance
|
||||
|
||||
## Additional Guidelines
|
||||
|
||||
[Add any project-specific conventions here]
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: [YYYY-MM-DD]
|
||||
**Maintained By**: [Team/Person]
|
||||
486
skills/session-management/references/commands.md
Normal file
486
skills/session-management/references/commands.md
Normal file
@@ -0,0 +1,486 @@
|
||||
# Session Management Command Reference
|
||||
|
||||
Complete reference for all session management commands.
|
||||
|
||||
## Session Lifecycle Commands
|
||||
|
||||
### `start` - Start New Session
|
||||
|
||||
```bash
|
||||
python scripts/session.py start <branch-name> [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
- `--objective "text"` - Set primary objective for this session
|
||||
- `--resume` - Resume if session already exists on this branch
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Start new feature
|
||||
python scripts/session.py start feature/user-auth --objective "Implement JWT authentication"
|
||||
|
||||
# Start with resume fallback
|
||||
python scripts/session.py start feature/payments --resume
|
||||
```
|
||||
|
||||
**Behavior:**
|
||||
1. Creates/checks out git branch
|
||||
2. Initializes session directory (`.git/sessions/<branch>/`)
|
||||
3. Loads project context from `.session/`
|
||||
4. Generates agent brief
|
||||
5. Displays user brief with status
|
||||
|
||||
---
|
||||
|
||||
### `resume` - Resume Existing Session
|
||||
|
||||
```bash
|
||||
python scripts/session.py resume [branch-name]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
- `branch-name` (optional) - Specific branch to resume; defaults to current
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Resume current branch
|
||||
python scripts/session.py resume
|
||||
|
||||
# Resume specific branch
|
||||
python scripts/session.py resume feature/oauth-integration
|
||||
```
|
||||
|
||||
**Behavior:**
|
||||
1. Checks out specified branch (if provided)
|
||||
2. Loads session context
|
||||
3. Analyzes git history since last session
|
||||
4. Generates comprehensive brief
|
||||
5. Displays current status
|
||||
|
||||
---
|
||||
|
||||
### `checkpoint` - Create Checkpoint
|
||||
|
||||
```bash
|
||||
python scripts/session.py checkpoint [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
- `--label "text"` - Checkpoint label for easy reference
|
||||
- `--message "text"` - Git commit message
|
||||
- `--decision "text"` - Record architectural decision
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Simple checkpoint
|
||||
python scripts/session.py checkpoint --label "oauth-complete"
|
||||
|
||||
# With decision
|
||||
python scripts/session.py checkpoint \
|
||||
--label "auth-interface" \
|
||||
--decision "Using interface segregation for auth providers"
|
||||
|
||||
# With custom message
|
||||
python scripts/session.py checkpoint \
|
||||
--label "tests-passing" \
|
||||
--message "feat(auth): Add comprehensive test suite"
|
||||
```
|
||||
|
||||
**Behavior:**
|
||||
1. Captures current git state
|
||||
2. Analyzes code changes
|
||||
3. Updates progress toward objectives
|
||||
4. Creates enhanced git commit with metadata
|
||||
5. Saves checkpoint metadata
|
||||
|
||||
---
|
||||
|
||||
### `end` - End Session
|
||||
|
||||
```bash
|
||||
python scripts/session.py end [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
- `--handoff` - Generate handoff document (default: true)
|
||||
- `--merge-to <branch>` - Merge to target branch after ending
|
||||
- `--summary` - Generate session summary (default: true)
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# End with handoff
|
||||
python scripts/session.py end
|
||||
|
||||
# End and merge
|
||||
python scripts/session.py end --merge-to main
|
||||
|
||||
# End without handoff
|
||||
python scripts/session.py end --no-handoff
|
||||
```
|
||||
|
||||
**Behavior:**
|
||||
1. Final comprehensive state capture
|
||||
2. Calculates session metrics
|
||||
3. Generates handoff document
|
||||
4. Archives session data
|
||||
5. Optional: merges to target branch
|
||||
6. Displays accomplishments summary
|
||||
|
||||
---
|
||||
|
||||
### `switch` - Switch Sessions
|
||||
|
||||
```bash
|
||||
python scripts/session.py switch <branch-name>
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
- `branch-name` - Target session/branch to switch to
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Switch to hotfix
|
||||
python scripts/session.py switch hotfix/critical-bug
|
||||
|
||||
# Back to feature
|
||||
python scripts/session.py switch feature/main-work
|
||||
```
|
||||
|
||||
**Behavior:**
|
||||
1. Saves current session state
|
||||
2. Checks out target branch
|
||||
3. Loads target session context
|
||||
4. Displays quick brief
|
||||
5. Highlights differences
|
||||
|
||||
---
|
||||
|
||||
## Context Query Commands
|
||||
|
||||
### `status` - Session Status
|
||||
|
||||
```bash
|
||||
python scripts/session.py status [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
- `--verbose` - Include detailed information
|
||||
- `--objectives` - Show only objectives
|
||||
- `--blockers` - Show only blockers
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Quick status
|
||||
python scripts/session.py status
|
||||
|
||||
# Detailed status
|
||||
python scripts/session.py status --verbose
|
||||
|
||||
# Just objectives
|
||||
python scripts/session.py status --objectives
|
||||
```
|
||||
|
||||
**Output includes:**
|
||||
- Current objectives and progress
|
||||
- Active blockers
|
||||
- Recent changes summary
|
||||
- Time in session
|
||||
- Quality metrics (if available)
|
||||
- Next recommended actions
|
||||
|
||||
---
|
||||
|
||||
### `history` - Session History
|
||||
|
||||
```bash
|
||||
python scripts/session.py history [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
- `--count N` - Number of sessions to show (default: 10)
|
||||
- `--metrics` - Include velocity and quality metrics
|
||||
- `--since <date>` - Filter by date (YYYY-MM-DD format)
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Last 10 sessions
|
||||
python scripts/session.py history
|
||||
|
||||
# Last 5 with metrics
|
||||
python scripts/session.py history --count 5 --metrics
|
||||
|
||||
# Since specific date
|
||||
python scripts/session.py history --since 2025-10-01
|
||||
```
|
||||
|
||||
**Output includes:**
|
||||
- Session timeline
|
||||
- Objectives completed per session
|
||||
- Velocity trends (if --metrics)
|
||||
- Quality progression (if --metrics)
|
||||
|
||||
---
|
||||
|
||||
## Management Commands
|
||||
|
||||
### `objectives` - Manage Objectives
|
||||
|
||||
```bash
|
||||
python scripts/session.py objectives <action> [options]
|
||||
```
|
||||
|
||||
**Actions:**
|
||||
- `add "text"` - Add new objective
|
||||
- `complete <id>` - Mark objective complete
|
||||
- `list` - Show all objectives
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Add objective
|
||||
python scripts/session.py objectives add "Implement webhook handlers"
|
||||
|
||||
# Complete objective
|
||||
python scripts/session.py objectives complete obj-1
|
||||
|
||||
# List objectives
|
||||
python scripts/session.py objectives list
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `blockers` - Manage Blockers
|
||||
|
||||
```bash
|
||||
python scripts/session.py blockers <action> [options]
|
||||
```
|
||||
|
||||
**Actions:**
|
||||
- `add "text"` - Add new blocker
|
||||
- `resolve <id>` - Mark blocker resolved
|
||||
- `list` - Show all blockers
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Add blocker
|
||||
python scripts/session.py blockers add "Waiting on API keys"
|
||||
|
||||
# Resolve blocker
|
||||
python scripts/session.py blockers resolve blk-1
|
||||
|
||||
# List blockers
|
||||
python scripts/session.py blockers list
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `decisions` - Log Decisions
|
||||
|
||||
```bash
|
||||
python scripts/session.py decisions <action> [options]
|
||||
```
|
||||
|
||||
**Actions:**
|
||||
- `add "text"` - Record architectural decision
|
||||
- `list` - Show decision log
|
||||
|
||||
**Options (for add):**
|
||||
- `--rationale "text"` - Decision rationale
|
||||
- `--alternatives "text"` - Alternatives considered
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Record decision
|
||||
python scripts/session.py decisions add "Using JWT over sessions" \
|
||||
--rationale "Stateless auth for microservices"
|
||||
|
||||
# With alternatives
|
||||
python scripts/session.py decisions add "Repository pattern for data access" \
|
||||
--rationale "Separates domain from persistence" \
|
||||
--alternatives "Active Record: Too coupled to database"
|
||||
|
||||
# List decisions
|
||||
python scripts/session.py decisions list
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Analysis Commands
|
||||
|
||||
### `analyze` - Session Analysis
|
||||
|
||||
```bash
|
||||
python scripts/session.py analyze [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
- `--velocity` - Calculate velocity metrics
|
||||
- `--patterns` - Detect coding patterns
|
||||
- `--recommendations` - Generate recommendations
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Basic analysis
|
||||
python scripts/session.py analyze
|
||||
|
||||
# With velocity
|
||||
python scripts/session.py analyze --velocity
|
||||
|
||||
# Full analysis
|
||||
python scripts/session.py analyze --velocity --patterns --recommendations
|
||||
```
|
||||
|
||||
**Output includes:**
|
||||
- Session health score
|
||||
- Pattern compliance
|
||||
- Code quality trends
|
||||
- Velocity calculations (if --velocity)
|
||||
- Recommended actions (if --recommendations)
|
||||
|
||||
---
|
||||
|
||||
### `compare` - Compare Sessions
|
||||
|
||||
```bash
|
||||
python scripts/session.py compare <session-id> [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
- `--changes` - Show code changes
|
||||
- `--metrics` - Compare metrics
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Compare with previous session
|
||||
python scripts/session.py compare session-2025-10-30
|
||||
|
||||
# With detailed changes
|
||||
python scripts/session.py compare session-2025-10-30 --changes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `report` - Generate Reports
|
||||
|
||||
```bash
|
||||
python scripts/session.py report [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
- `--weekly` - Weekly summary
|
||||
- `--project` - Complete project summary
|
||||
- `--format <type>` - Output format (markdown, json, html)
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Weekly report
|
||||
python scripts/session.py report --weekly
|
||||
|
||||
# Project summary
|
||||
python scripts/session.py report --project --format markdown
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Workflows
|
||||
|
||||
### Starting Your Day
|
||||
|
||||
```bash
|
||||
# Resume where you left off
|
||||
python scripts/session.py resume
|
||||
|
||||
# Check what needs to be done
|
||||
python scripts/session.py status
|
||||
```
|
||||
|
||||
### During Development
|
||||
|
||||
```bash
|
||||
# Checkpoint at milestones
|
||||
python scripts/session.py checkpoint --label "api-implemented"
|
||||
|
||||
# Record important decisions
|
||||
python scripts/session.py decisions add "Using Redis for caching" \
|
||||
--rationale "Fast, simple, proven for this use case"
|
||||
|
||||
# Track blockers
|
||||
python scripts/session.py blockers add "Need database credentials"
|
||||
```
|
||||
|
||||
### Ending Your Day
|
||||
|
||||
```bash
|
||||
# End with comprehensive handoff
|
||||
python scripts/session.py end
|
||||
|
||||
# Or end and merge
|
||||
python scripts/session.py end --merge-to main
|
||||
```
|
||||
|
||||
### Context Switching
|
||||
|
||||
```bash
|
||||
# Urgent issue
|
||||
python scripts/session.py switch hotfix/prod-issue
|
||||
|
||||
# Back to feature work
|
||||
python scripts/session.py switch feature/current-work
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Exit Codes
|
||||
|
||||
All commands return standard exit codes:
|
||||
- `0` - Success
|
||||
- `1` - Error (check output for details)
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Session management respects these environment variables:
|
||||
|
||||
- `SESSION_CONFIG` - Path to custom config file
|
||||
- `SESSION_VERBOSE` - Enable verbose output (true/false)
|
||||
- `GIT_DIR` - Custom git directory location
|
||||
|
||||
---
|
||||
|
||||
## Integration with Git
|
||||
|
||||
Session management integrates with git through:
|
||||
|
||||
**Git Hooks:**
|
||||
- `post-checkout` - Auto-load session on branch switch
|
||||
- `prepare-commit-msg` - Inject session metadata
|
||||
- `post-commit` - Update progress tracking
|
||||
|
||||
**Git Configuration:**
|
||||
- Uses `user.name` and `user.email` for session attribution
|
||||
- Respects `.gitignore` for file tracking
|
||||
- Works with all git workflows (merge, rebase, etc.)
|
||||
|
||||
---
|
||||
|
||||
## Tips & Tricks
|
||||
|
||||
**Aliases:**
|
||||
Add to your shell profile for quick access:
|
||||
```bash
|
||||
alias ss='python scripts/session.py status'
|
||||
alias sc='python scripts/session.py checkpoint'
|
||||
alias se='python scripts/session.py end'
|
||||
```
|
||||
|
||||
**Quick Checkpoints:**
|
||||
```bash
|
||||
# Label-only checkpoint (uses current time as message)
|
||||
python scripts/session.py checkpoint --label "milestone"
|
||||
```
|
||||
|
||||
**Verbose Troubleshooting:**
|
||||
```bash
|
||||
# Any command can use --verbose for detailed output
|
||||
python scripts/session.py status --verbose
|
||||
```
|
||||
228
skills/session-management/references/config-reference.md
Normal file
228
skills/session-management/references/config-reference.md
Normal file
@@ -0,0 +1,228 @@
|
||||
# Configuration Reference
|
||||
|
||||
Complete reference for `.session/config.yaml` configuration options.
|
||||
|
||||
## Session Configuration
|
||||
|
||||
```yaml
|
||||
session:
|
||||
auto_track: true
|
||||
auto_checkpoint: false
|
||||
checkpoint_interval: 30m
|
||||
handoff_on_end: true
|
||||
archive_after_days: 30
|
||||
```
|
||||
|
||||
### `auto_track`
|
||||
**Type:** boolean
|
||||
**Default:** `true`
|
||||
**Description:** Automatically track file changes during session
|
||||
|
||||
### `auto_checkpoint`
|
||||
**Type:** boolean
|
||||
**Default:** `false`
|
||||
**Description:** Create automatic checkpoints at intervals
|
||||
|
||||
### `checkpoint_interval`
|
||||
**Type:** string
|
||||
**Default:** `30m`
|
||||
**Description:** Interval for automatic checkpoints (30m, 1h, etc.)
|
||||
|
||||
### `handoff_on_end`
|
||||
**Type:** boolean
|
||||
**Default:** `true`
|
||||
**Description:** Generate handoff document when ending session
|
||||
|
||||
### `archive_after_days`
|
||||
**Type:** integer
|
||||
**Default:** `30`
|
||||
**Description:** Archive completed sessions after N days
|
||||
|
||||
---
|
||||
|
||||
## Context Configuration
|
||||
|
||||
```yaml
|
||||
context:
|
||||
architecture: hexagonal
|
||||
patterns:
|
||||
- ports-and-adapters
|
||||
- repository-pattern
|
||||
conventions:
|
||||
- type-hints-required
|
||||
- docstrings-required
|
||||
```
|
||||
|
||||
### `architecture`
|
||||
**Type:** string
|
||||
**Options:** `hexagonal`, `layered`, `microservices`, `mvc`, `clean`, `ddd`
|
||||
**Description:** Primary architecture pattern for the project
|
||||
|
||||
### `patterns`
|
||||
**Type:** list of strings
|
||||
**Description:** Code patterns to detect and enforce
|
||||
**Common values:**
|
||||
- `ports-and-adapters`
|
||||
- `repository-pattern`
|
||||
- `dependency-injection`
|
||||
- `factory-pattern`
|
||||
- `cqrs`
|
||||
- `event-sourcing`
|
||||
|
||||
### `conventions`
|
||||
**Type:** list of strings
|
||||
**Description:** Project conventions
|
||||
**Common values:**
|
||||
- `type-hints-required`
|
||||
- `docstrings-required`
|
||||
- `snake-case`
|
||||
- `pep8-compliant`
|
||||
- `test-coverage-required`
|
||||
|
||||
---
|
||||
|
||||
## Tracking Configuration
|
||||
|
||||
```yaml
|
||||
tracking:
|
||||
watch_patterns:
|
||||
- "src/**/*.py"
|
||||
- "tests/**/*.py"
|
||||
ignore_patterns:
|
||||
- "**/__pycache__/**"
|
||||
- "**/node_modules/**"
|
||||
annotations:
|
||||
- "TODO:"
|
||||
- "FIXME:"
|
||||
- "DECISION:"
|
||||
```
|
||||
|
||||
### `watch_patterns`
|
||||
**Type:** list of glob patterns
|
||||
**Description:** Files to watch for changes
|
||||
|
||||
### `ignore_patterns`
|
||||
**Type:** list of glob patterns
|
||||
**Description:** Files to ignore
|
||||
|
||||
### `annotations`
|
||||
**Type:** list of strings
|
||||
**Description:** Code annotations to track
|
||||
|
||||
---
|
||||
|
||||
## Quality Configuration
|
||||
|
||||
```yaml
|
||||
quality:
|
||||
coverage_threshold: 85
|
||||
new_code_coverage_threshold: 90
|
||||
require_tests: true
|
||||
block_merge_on_quality: true
|
||||
```
|
||||
|
||||
### `coverage_threshold`
|
||||
**Type:** integer (0-100)
|
||||
**Default:** `85`
|
||||
**Description:** Minimum overall test coverage percentage
|
||||
|
||||
### `new_code_coverage_threshold`
|
||||
**Type:** integer (0-100)
|
||||
**Default:** `90`
|
||||
**Description:** Minimum coverage for new code
|
||||
|
||||
### `require_tests`
|
||||
**Type:** boolean
|
||||
**Default:** `true`
|
||||
**Description:** Require tests for new features
|
||||
|
||||
### `block_merge_on_quality`
|
||||
**Type:** boolean
|
||||
**Default:** `true`
|
||||
**Description:** Prevent merge if quality thresholds not met
|
||||
|
||||
---
|
||||
|
||||
## Display Configuration
|
||||
|
||||
```yaml
|
||||
display:
|
||||
color: true
|
||||
verbose: false
|
||||
emoji: true
|
||||
date_format: "%Y-%m-%d %H:%M"
|
||||
```
|
||||
|
||||
### `color`
|
||||
**Type:** boolean
|
||||
**Default:** `true`
|
||||
**Description:** Use colored terminal output
|
||||
|
||||
### `verbose`
|
||||
**Type:** boolean
|
||||
**Default:** `false`
|
||||
**Description:** Enable verbose output by default
|
||||
|
||||
### `emoji`
|
||||
**Type:** boolean
|
||||
**Default:** `true`
|
||||
**Description:** Use emoji in output
|
||||
|
||||
### `date_format`
|
||||
**Type:** string
|
||||
**Default:** `"%Y-%m-%d %H:%M"`
|
||||
**Description:** Date/time format string (Python strftime format)
|
||||
|
||||
---
|
||||
|
||||
## Complete Example
|
||||
|
||||
```yaml
|
||||
# Session Management Configuration
|
||||
|
||||
session:
|
||||
auto_track: true
|
||||
auto_checkpoint: false
|
||||
checkpoint_interval: 30m
|
||||
handoff_on_end: true
|
||||
archive_after_days: 30
|
||||
|
||||
context:
|
||||
architecture: hexagonal
|
||||
patterns:
|
||||
- ports-and-adapters
|
||||
- repository-pattern
|
||||
- dependency-injection
|
||||
conventions:
|
||||
- type-hints-required
|
||||
- docstrings-required
|
||||
- snake-case
|
||||
- max-line-length-100
|
||||
|
||||
tracking:
|
||||
watch_patterns:
|
||||
- "src/**/*.py"
|
||||
- "tests/**/*.py"
|
||||
- "docs/**/*.md"
|
||||
ignore_patterns:
|
||||
- "**/__pycache__/**"
|
||||
- "**/.venv/**"
|
||||
- "**/dist/**"
|
||||
annotations:
|
||||
- "TODO:"
|
||||
- "FIXME:"
|
||||
- "DECISION:"
|
||||
- "BLOCKER:"
|
||||
|
||||
quality:
|
||||
coverage_threshold: 85
|
||||
new_code_coverage_threshold: 90
|
||||
require_tests: true
|
||||
block_merge_on_quality: true
|
||||
|
||||
display:
|
||||
color: true
|
||||
verbose: false
|
||||
emoji: true
|
||||
date_format: "%Y-%m-%d %H:%M"
|
||||
```
|
||||
264
skills/session-management/references/handoff-template.md
Normal file
264
skills/session-management/references/handoff-template.md
Normal file
@@ -0,0 +1,264 @@
|
||||
# Session Handoff Template
|
||||
|
||||
This template shows the structure and content of session handoff documents generated by `session.py end --handoff`.
|
||||
|
||||
---
|
||||
|
||||
# Session Handoff: [Feature/Branch Name]
|
||||
|
||||
**Session ID**: [branch-name]-[date]
|
||||
**Branch**: [branch-name]
|
||||
**Date**: [YYYY-MM-DD HH:MM UTC]
|
||||
**Duration**: [X hours Y minutes]
|
||||
**Commit**: [SHA] "[commit message]"
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Session Objective
|
||||
|
||||
**Primary Goal**: [Primary objective description]
|
||||
|
||||
**Success Criteria**:
|
||||
- [x] [Completed criterion 1]
|
||||
- [x] [Completed criterion 2]
|
||||
- [ ] [Incomplete criterion]
|
||||
|
||||
**Achievement**: [✅ Complete / 🚧 Partial / ❌ Not met]
|
||||
|
||||
---
|
||||
|
||||
## ✅ Completed Work
|
||||
|
||||
### Features Implemented
|
||||
|
||||
**1. [Feature Name]** (Commit: [SHA])
|
||||
- [Implementation detail 1]
|
||||
- [Implementation detail 2]
|
||||
- [Implementation detail 3]
|
||||
|
||||
**2. [Feature Name]** (Commit: [SHA])
|
||||
- [Implementation detail 1]
|
||||
- [Implementation detail 2]
|
||||
|
||||
### Tests Added
|
||||
|
||||
**Unit Tests**: [N] new tests
|
||||
- `test_[module].py`: [N] tests
|
||||
- `test_[module].py`: [N] tests
|
||||
|
||||
**Integration Tests**: [N] new tests
|
||||
- [Description of integration tests]
|
||||
|
||||
**Coverage**: [XX.X]% → [YY.Y]% **(+Z.Z%)**
|
||||
|
||||
### Documentation
|
||||
|
||||
- [Documentation item 1]
|
||||
- [Documentation item 2]
|
||||
- [Documentation item 3]
|
||||
|
||||
---
|
||||
|
||||
## 🚧 Work In Progress
|
||||
|
||||
**[Feature/Task Name]**
|
||||
- Current state: [X]% complete
|
||||
- Remaining work: [Description]
|
||||
- Next steps: [Action items]
|
||||
|
||||
---
|
||||
|
||||
## 🚫 Blockers
|
||||
|
||||
### Blocker 1: [Blocker Name]
|
||||
**Issue**: [Issue ID if applicable]
|
||||
**Status**: [Active / Resolved]
|
||||
**Duration**: [Time blocked]
|
||||
**Resolution**: [How resolved or path to resolution]
|
||||
**Impact**: [Impact description]
|
||||
|
||||
### Blocker 2: [Blocker Name]
|
||||
**Status**: [Active]
|
||||
**Blocking**: [What is blocked]
|
||||
**Next Steps**: [What needs to happen]
|
||||
|
||||
---
|
||||
|
||||
## 📋 Decisions Made
|
||||
|
||||
### D-[DATE]-1: [Decision Title]
|
||||
**Context**: [Why this decision was needed]
|
||||
**Decision**: [What was decided]
|
||||
**Rationale**: [Why this approach was chosen]
|
||||
|
||||
**Alternatives Considered**:
|
||||
- [Alternative 1]: [Why not chosen]
|
||||
- [Alternative 2]: [Why not chosen]
|
||||
|
||||
**Impact**:
|
||||
- [Impact item 1]
|
||||
- [Impact item 2]
|
||||
|
||||
**Consequences**:
|
||||
- [Consequence 1]
|
||||
- [Consequence 2]
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Architecture & Patterns
|
||||
|
||||
### Patterns Applied
|
||||
|
||||
**[Pattern Name]**
|
||||
- [How pattern was applied]
|
||||
- [Benefits realized]
|
||||
- [Considerations]
|
||||
|
||||
### Pattern Compliance
|
||||
|
||||
**Compliance Score**: [XX]%
|
||||
|
||||
**Violations** (if any):
|
||||
- `[file]:[line]`: [Violation description] - [Status]
|
||||
|
||||
**Improvements**:
|
||||
- [Improvement made 1]
|
||||
- [Improvement made 2]
|
||||
|
||||
---
|
||||
|
||||
## 📊 Session Metrics
|
||||
|
||||
### Time Breakdown
|
||||
- **Active Coding**: [X hours Y minutes]
|
||||
- **Testing**: [X hours Y minutes]
|
||||
- **Documentation**: [X minutes]
|
||||
- **Blocked Time**: [X hours] ([Reason])
|
||||
|
||||
### Code Changes
|
||||
- **Files Modified**: [N]
|
||||
- **Files Added**: [N]
|
||||
- **Lines Added**: [N]
|
||||
- **Lines Removed**: [N]
|
||||
- **Net Change**: [+/-N] lines
|
||||
|
||||
### Commits
|
||||
- **Total Commits**: [N]
|
||||
- **Feature Commits**: [N]
|
||||
- **Test Commits**: [N]
|
||||
- **Documentation Commits**: [N]
|
||||
|
||||
### Quality Metrics
|
||||
- **Tests Added**: [N]
|
||||
- **Tests Passing**: [N] ([X]%)
|
||||
- **Coverage**: [XX.X]% (+[Z.Z]%, [above/below] threshold)
|
||||
- **Build Status**: [✅ Passing / ❌ Failing]
|
||||
- **Linter Warnings**: [N]
|
||||
|
||||
---
|
||||
|
||||
## 📁 Key Files
|
||||
|
||||
### Core Implementation
|
||||
- `[path/to/file]` - [Description]
|
||||
- `[path/to/file]` - [Description]
|
||||
|
||||
### Tests
|
||||
- `[path/to/test]` - [Description]
|
||||
- `[path/to/test]` - [Description]
|
||||
|
||||
### Documentation
|
||||
- `[path/to/doc]` - [Description]
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Important Notes
|
||||
|
||||
### For Next Developer
|
||||
|
||||
**Critical Points**:
|
||||
1. [Critical point 1]
|
||||
2. [Critical point 2]
|
||||
|
||||
**Testing**:
|
||||
- [Testing consideration 1]
|
||||
- [Testing consideration 2]
|
||||
|
||||
**Deployment**:
|
||||
- [Deployment consideration 1]
|
||||
- [Deployment consideration 2]
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Next Steps (If Continuing)
|
||||
|
||||
1. [Next action item 1]
|
||||
2. [Next action item 2]
|
||||
3. [Next action item 3]
|
||||
|
||||
**Estimated**: [Time estimate]
|
||||
|
||||
**Potential Enhancements** (Future work):
|
||||
- [Enhancement 1]
|
||||
- [Enhancement 2]
|
||||
|
||||
---
|
||||
|
||||
## 🎓 Learnings & Insights
|
||||
|
||||
### What Went Well
|
||||
- [Success 1]
|
||||
- [Success 2]
|
||||
|
||||
### Challenges Overcome
|
||||
- [Challenge 1]: [How overcome]
|
||||
- [Challenge 2]: [How overcome]
|
||||
|
||||
### What Could Be Improved
|
||||
- [Improvement opportunity 1]
|
||||
- [Improvement opportunity 2]
|
||||
|
||||
### Recommendations for Similar Work
|
||||
- [Recommendation 1]
|
||||
- [Recommendation 2]
|
||||
|
||||
---
|
||||
|
||||
## 📊 Session Summary
|
||||
|
||||
**Objective Achievement**: [✅ 100% / 🚧 XX% / ❌ Not met]
|
||||
**Quality Score**: [A+ / A / B / C / D]
|
||||
**Velocity**: [N] lines/hour (net code)
|
||||
**Decision Points**: [N] architectural decisions recorded
|
||||
**Blockers**: [N] encountered, [N] resolved
|
||||
|
||||
**Overall Assessment**: [Brief assessment]
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Related Resources
|
||||
|
||||
- **Pull Request**: #[N]
|
||||
- **Issue Tracker**: [Issue IDs]
|
||||
- **Build**: [Build link] ([Status])
|
||||
- **Documentation**: [Doc links]
|
||||
|
||||
---
|
||||
|
||||
## 📝 Handoff Checklist
|
||||
|
||||
- [ ] All code committed and pushed
|
||||
- [ ] Tests passing
|
||||
- [ ] Coverage above threshold
|
||||
- [ ] Documentation updated
|
||||
- [ ] Decisions recorded
|
||||
- [ ] Branch merged (if applicable)
|
||||
- [ ] Issues updated
|
||||
- [ ] Session metrics recorded
|
||||
|
||||
**Status**: [✅ Ready / 🚧 Pending / ❌ Incomplete]
|
||||
|
||||
---
|
||||
|
||||
**Generated by Session Manager**
|
||||
**Session Archive**: `.git/sessions/history/[session-id].json`
|
||||
224
skills/session-management/scripts/checkpoint.py
Executable file
224
skills/session-management/scripts/checkpoint.py
Executable file
@@ -0,0 +1,224 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Checkpoint Manager
|
||||
|
||||
Handles automatic checkpoint generation with git diff analysis.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional
|
||||
|
||||
|
||||
class CheckpointManager:
|
||||
"""Manage session checkpoints"""
|
||||
|
||||
def __init__(self, project_path: str = "."):
|
||||
"""Initialize manager with project path"""
|
||||
self.project_path = Path(project_path)
|
||||
self.checkpoints_dir = self.project_path / ".sessions" / "checkpoints"
|
||||
self.checkpoints_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
def _run_git(self, args: List[str]) -> Optional[str]:
|
||||
"""Run git command"""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["git"] + args,
|
||||
cwd=self.project_path,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True
|
||||
)
|
||||
return result.stdout.strip()
|
||||
except subprocess.CalledProcessError:
|
||||
return None
|
||||
|
||||
def analyze_git_changes(self) -> Dict[str, List[str]]:
|
||||
"""Analyze git diff for file changes"""
|
||||
# Get modified files with stats
|
||||
diff_output = self._run_git(["diff", "--stat"])
|
||||
|
||||
modified = []
|
||||
added = []
|
||||
deleted = []
|
||||
|
||||
if diff_output:
|
||||
for line in diff_output.split("\n"):
|
||||
if "|" in line:
|
||||
filename = line.split("|")[0].strip()
|
||||
modified.append(filename)
|
||||
|
||||
# Get staged files
|
||||
staged_output = self._run_git(["diff", "--cached", "--name-status"])
|
||||
if staged_output:
|
||||
for line in staged_output.split("\n"):
|
||||
if not line:
|
||||
continue
|
||||
parts = line.split("\t")
|
||||
if len(parts) == 2:
|
||||
status, filename = parts
|
||||
if status == "A":
|
||||
added.append(filename)
|
||||
elif status == "D":
|
||||
deleted.append(filename)
|
||||
elif status == "M":
|
||||
if filename not in modified:
|
||||
modified.append(filename)
|
||||
|
||||
return {
|
||||
"modified": modified,
|
||||
"added": added,
|
||||
"deleted": deleted
|
||||
}
|
||||
|
||||
def get_recent_commits(self, since_checkpoint: Optional[str] = None) -> List[str]:
|
||||
"""Get commits since last checkpoint"""
|
||||
if since_checkpoint:
|
||||
# Load checkpoint file to get commit hash
|
||||
checkpoint_file = self.checkpoints_dir / f"{since_checkpoint}.md"
|
||||
if checkpoint_file.exists():
|
||||
try:
|
||||
with open(checkpoint_file) as f:
|
||||
content = f.read()
|
||||
# Look for commit hash in checkpoint metadata
|
||||
for line in content.split("\n"):
|
||||
if line.startswith("**Commit**:"):
|
||||
commit_hash = line.split(":", 1)[1].strip()
|
||||
# Get commits since that hash
|
||||
log_output = self._run_git(["log", f"{commit_hash}..HEAD", "--oneline"])
|
||||
if log_output:
|
||||
return log_output.split("\n")
|
||||
return []
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
# Get last 5 commits
|
||||
log_output = self._run_git(["log", "--oneline", "-5"])
|
||||
if log_output:
|
||||
return log_output.split("\n")
|
||||
return []
|
||||
|
||||
def load_tdd_metrics(self) -> Optional[Dict]:
|
||||
"""Load TDD metrics from .ccmp/state.json"""
|
||||
state_file = self.project_path / ".ccmp" / "state.json"
|
||||
|
||||
if not state_file.exists():
|
||||
return None
|
||||
|
||||
try:
|
||||
with open(state_file) as f:
|
||||
state = json.load(f)
|
||||
|
||||
tdd_state = state.get("tdd-workflow", {})
|
||||
if tdd_state.get("active"):
|
||||
return {
|
||||
"cycles_today": tdd_state.get("cycles_today", 0),
|
||||
"current_phase": tdd_state.get("current_phase", "N/A"),
|
||||
"discipline_score": tdd_state.get("discipline_score", 100)
|
||||
}
|
||||
except (json.JSONDecodeError, IOError):
|
||||
pass
|
||||
|
||||
return None
|
||||
|
||||
def generate_checkpoint(self, notes: Optional[str] = None, label: Optional[str] = None) -> str:
|
||||
"""Generate checkpoint document"""
|
||||
timestamp = datetime.now()
|
||||
checkpoint_id = timestamp.strftime("%Y-%m-%dT%H-%M-%S")
|
||||
|
||||
changes = self.analyze_git_changes()
|
||||
commits = self.get_recent_commits()
|
||||
tdd_metrics = self.load_tdd_metrics()
|
||||
|
||||
# Get current commit hash for tracking
|
||||
current_commit = self._run_git(["rev-parse", "HEAD"])
|
||||
|
||||
lines = []
|
||||
lines.append(f"# Checkpoint: {checkpoint_id}")
|
||||
if label:
|
||||
lines.append(f"**Label**: {label}")
|
||||
lines.append(f"**Time**: {timestamp.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
if current_commit:
|
||||
lines.append(f"**Commit**: {current_commit}")
|
||||
lines.append("")
|
||||
|
||||
# What Changed
|
||||
lines.append("## What Changed")
|
||||
lines.append("")
|
||||
if changes["modified"]:
|
||||
lines.append("**Modified**:")
|
||||
for file in changes["modified"][:10]:
|
||||
lines.append(f"- {file}")
|
||||
if changes["added"]:
|
||||
lines.append("**Added**:")
|
||||
for file in changes["added"][:10]:
|
||||
lines.append(f"- {file}")
|
||||
if changes["deleted"]:
|
||||
lines.append("**Deleted**:")
|
||||
for file in changes["deleted"][:10]:
|
||||
lines.append(f"- {file}")
|
||||
|
||||
if not any([changes["modified"], changes["added"], changes["deleted"]]):
|
||||
lines.append("*No changes detected*")
|
||||
|
||||
lines.append("")
|
||||
|
||||
# Commits
|
||||
if commits:
|
||||
lines.append("## Commits Since Last Checkpoint")
|
||||
lines.append("")
|
||||
for commit in commits:
|
||||
lines.append(f"- {commit}")
|
||||
lines.append("")
|
||||
|
||||
# TDD Metrics
|
||||
if tdd_metrics:
|
||||
lines.append("## TDD Metrics")
|
||||
lines.append("")
|
||||
lines.append(f"- Cycles today: {tdd_metrics['cycles_today']}")
|
||||
lines.append(f"- Current phase: {tdd_metrics['current_phase']}")
|
||||
lines.append(f"- Discipline score: {tdd_metrics['discipline_score']}/100")
|
||||
lines.append("")
|
||||
|
||||
# Notes
|
||||
if notes:
|
||||
lines.append("## Notes")
|
||||
lines.append("")
|
||||
lines.append(notes)
|
||||
lines.append("")
|
||||
|
||||
checkpoint_content = "\n".join(lines)
|
||||
|
||||
# Save checkpoint
|
||||
checkpoint_file = self.checkpoints_dir / f"{checkpoint_id}.md"
|
||||
with open(checkpoint_file, 'w') as f:
|
||||
f.write(checkpoint_content)
|
||||
|
||||
return checkpoint_content
|
||||
|
||||
def get_latest_checkpoint(self) -> Optional[Path]:
|
||||
"""Get most recent checkpoint file"""
|
||||
checkpoints = sorted(self.checkpoints_dir.glob("*.md"), reverse=True)
|
||||
return checkpoints[0] if checkpoints else None
|
||||
|
||||
|
||||
def main():
|
||||
"""CLI entry point"""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="Create session checkpoint")
|
||||
parser.add_argument("--label", help="Checkpoint label")
|
||||
parser.add_argument("--notes", help="Checkpoint notes")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
manager = CheckpointManager()
|
||||
checkpoint = manager.generate_checkpoint(notes=args.notes, label=args.label)
|
||||
print(checkpoint)
|
||||
print(f"\nCheckpoint saved to .sessions/checkpoints/")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
133
skills/session-management/scripts/handoff.py
Executable file
133
skills/session-management/scripts/handoff.py
Executable file
@@ -0,0 +1,133 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Handoff Generator
|
||||
|
||||
Generates comprehensive session handoff documents.
|
||||
"""
|
||||
|
||||
import json
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Optional, Dict, List
|
||||
|
||||
from checkpoint import CheckpointManager
|
||||
|
||||
|
||||
class HandoffGenerator:
|
||||
"""Generate session handoff documents"""
|
||||
|
||||
def __init__(self, project_path: str = "."):
|
||||
"""Initialize generator"""
|
||||
self.project_path = Path(project_path)
|
||||
self.checkpoint_manager = CheckpointManager(project_path)
|
||||
|
||||
def load_session_state(self) -> Dict:
|
||||
"""Load current session state"""
|
||||
state_file = self.project_path / ".sessions" / "state.json"
|
||||
|
||||
if state_file.exists():
|
||||
try:
|
||||
with open(state_file) as f:
|
||||
return json.load(f)
|
||||
except (json.JSONDecodeError, IOError):
|
||||
pass
|
||||
|
||||
return {}
|
||||
|
||||
def generate_handoff(self, session_notes: str) -> str:
|
||||
"""Generate comprehensive handoff document"""
|
||||
timestamp = datetime.now()
|
||||
handoff_id = timestamp.strftime("%Y-%m-%dT%H-%M-%S") + "-HANDOFF"
|
||||
|
||||
state = self.load_session_state()
|
||||
changes = self.checkpoint_manager.analyze_git_changes()
|
||||
|
||||
lines = []
|
||||
lines.append(f"# Session Handoff: {timestamp.strftime('%Y-%m-%d')}")
|
||||
lines.append("")
|
||||
lines.append(f"**Branch**: {state.get('branch', 'Unknown')}")
|
||||
lines.append(f"**Date**: {timestamp.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
lines.append("")
|
||||
|
||||
# Session Summary
|
||||
lines.append("## Session Summary")
|
||||
lines.append("")
|
||||
lines.append(session_notes)
|
||||
lines.append("")
|
||||
|
||||
# What Changed
|
||||
lines.append("## What Changed (This Session)")
|
||||
lines.append("")
|
||||
|
||||
total_modified = len(changes["modified"])
|
||||
total_added = len(changes["added"])
|
||||
total_deleted = len(changes["deleted"])
|
||||
|
||||
lines.append(f"**Files modified**: {total_modified}")
|
||||
lines.append(f"**Files added**: {total_added}")
|
||||
lines.append(f"**Files deleted**: {total_deleted}")
|
||||
lines.append("")
|
||||
|
||||
if changes["modified"]:
|
||||
lines.append("### Modified Files")
|
||||
for file in changes["modified"][:10]:
|
||||
lines.append(f"- {file}")
|
||||
if len(changes["modified"]) > 10:
|
||||
lines.append(f"- ... and {len(changes['modified']) - 10} more")
|
||||
lines.append("")
|
||||
|
||||
# Open Work
|
||||
lines.append("## What's Next (Open Work)")
|
||||
lines.append("")
|
||||
|
||||
objectives = state.get("objectives", [])
|
||||
if objectives:
|
||||
lines.append("**Objectives**:")
|
||||
for obj in objectives:
|
||||
if isinstance(obj, dict):
|
||||
status = "[x]" if obj.get("completed") else "[ ]"
|
||||
lines.append(f"- {status} {obj.get('text')}")
|
||||
else:
|
||||
lines.append(f"- [ ] {obj}")
|
||||
lines.append("")
|
||||
|
||||
# Context Health
|
||||
lines.append("## Context Health")
|
||||
lines.append("")
|
||||
lines.append("✅ Session state saved")
|
||||
lines.append("")
|
||||
|
||||
# Next Steps (AI Suggestions placeholder)
|
||||
lines.append("## Next Steps (Suggested)")
|
||||
lines.append("")
|
||||
lines.append("1. Review changes since last session")
|
||||
lines.append("2. Continue work on open objectives")
|
||||
lines.append("")
|
||||
|
||||
handoff_content = "\n".join(lines)
|
||||
|
||||
# Save handoff
|
||||
handoff_file = self.checkpoint_manager.checkpoints_dir / f"{handoff_id}.md"
|
||||
with open(handoff_file, 'w') as f:
|
||||
f.write(handoff_content)
|
||||
|
||||
return handoff_content
|
||||
|
||||
|
||||
def main():
|
||||
"""CLI entry point"""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="Generate session handoff")
|
||||
parser.add_argument("--notes", required=True, help="Session summary notes")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
generator = HandoffGenerator()
|
||||
handoff = generator.generate_handoff(session_notes=args.notes)
|
||||
print(handoff)
|
||||
print(f"\nHandoff saved to .sessions/checkpoints/")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
86
skills/session-management/scripts/init_session.py
Executable file
86
skills/session-management/scripts/init_session.py
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Session Management Initialization Script
|
||||
|
||||
Initializes session management in a git repository by creating the .session/
|
||||
directory with configuration and template files.
|
||||
|
||||
Usage:
|
||||
python init_session.py [--force]
|
||||
|
||||
Options:
|
||||
--force Overwrite existing .session/ directory
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Initialize session management")
|
||||
parser.add_argument("--force", action="store_true", help="Overwrite existing files")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Check if we're in a git repository
|
||||
if not Path(".git").exists():
|
||||
print("Error: Not in a git repository")
|
||||
print("Run 'git init' first")
|
||||
return 1
|
||||
|
||||
# Check if .session/ already exists
|
||||
session_dir = Path(".session")
|
||||
if session_dir.exists() and not args.force:
|
||||
print("Session management already initialized")
|
||||
print("Use --force to reinitialize")
|
||||
return 1
|
||||
|
||||
# Create .session/ directory
|
||||
session_dir.mkdir(exist_ok=True)
|
||||
print(f"✅ Created {session_dir}/")
|
||||
|
||||
# Copy template files from assets/
|
||||
# Note: This assumes the skill is installed and assets are available
|
||||
# In production, these would be copied from the skill's assets/ directory
|
||||
|
||||
# Create basic files
|
||||
files_created = []
|
||||
|
||||
# config.yaml
|
||||
config_path = session_dir / "config.yaml"
|
||||
if args.force or not config_path.exists():
|
||||
# In production: copy from assets/config-template.yaml
|
||||
print(f"✅ Created {config_path}")
|
||||
files_created.append(str(config_path))
|
||||
|
||||
# architecture.md
|
||||
arch_path = session_dir / "architecture.md"
|
||||
if args.force or not arch_path.exists():
|
||||
# In production: copy from assets/architecture-template.md
|
||||
print(f"✅ Created {arch_path}")
|
||||
files_created.append(str(arch_path))
|
||||
|
||||
# conventions.md
|
||||
conv_path = session_dir / "conventions.md"
|
||||
if args.force or not conv_path.exists():
|
||||
# In production: copy from assets/conventions-template.md
|
||||
print(f"✅ Created {conv_path}")
|
||||
files_created.append(str(conv_path))
|
||||
|
||||
# Create .git/sessions/ directory for local session data
|
||||
git_sessions_dir = Path(".git/sessions")
|
||||
git_sessions_dir.mkdir(exist_ok=True)
|
||||
print(f"✅ Created {git_sessions_dir}/")
|
||||
|
||||
print("\n🎉 Session management initialized!")
|
||||
print("\nNext steps:")
|
||||
print("1. Edit .session/architecture.md with your project's architecture")
|
||||
print("2. Edit .session/conventions.md with your code conventions")
|
||||
print("3. Customize .session/config.yaml as needed")
|
||||
print("4. Commit .session/ to git: git add .session/ && git commit -m 'Initialize session management'")
|
||||
print("5. Start your first session: python scripts/session.py start <branch-name>")
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit(main())
|
||||
700
skills/session-management/scripts/session.py
Executable file
700
skills/session-management/scripts/session.py
Executable file
@@ -0,0 +1,700 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Session Management CLI
|
||||
|
||||
Main command-line interface for managing coding sessions.
|
||||
|
||||
Usage:
|
||||
python session.py <command> [options]
|
||||
|
||||
Commands:
|
||||
start - Start new or resume existing session
|
||||
resume - Resume current session
|
||||
checkpoint - Create checkpoint
|
||||
end - End session with handoff
|
||||
switch - Switch to different session
|
||||
status - Show session status
|
||||
history - Show session history
|
||||
objectives - Manage session objectives
|
||||
blockers - Manage session blockers
|
||||
decisions - Log architectural decisions
|
||||
analyze - Analyze session metrics
|
||||
compare - Compare sessions
|
||||
report - Generate reports
|
||||
|
||||
For detailed command reference, see references/commands.md
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
|
||||
# Add lib to path for integration imports
|
||||
repo_root = Path(__file__).resolve().parents[5] # Go up to repo root
|
||||
sys.path.insert(0, str(repo_root / "lib"))
|
||||
|
||||
try:
|
||||
from session_integration import SessionIntegration
|
||||
from ccmp_integration import CCMPIntegration, is_session_active, is_tdd_mode
|
||||
from tdd_analyzer import TDDAnalyzer
|
||||
INTEGRATION_AVAILABLE = True
|
||||
except ImportError:
|
||||
INTEGRATION_AVAILABLE = False
|
||||
print("⚠️ Integration libraries not found. Running in standalone mode.")
|
||||
|
||||
def check_session_initialized():
|
||||
"""Check if session management is initialized"""
|
||||
# Check for either .session or .sessions directory
|
||||
if not (Path(".session").exists() or Path(".sessions").exists()):
|
||||
print("❌ Session management not initialized")
|
||||
print("Run: python scripts/init_session.py")
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_current_branch():
|
||||
"""Get current git branch"""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["git", "rev-parse", "--abbrev-ref", "HEAD"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True
|
||||
)
|
||||
return result.stdout.strip()
|
||||
except subprocess.CalledProcessError:
|
||||
return None
|
||||
|
||||
def get_changed_directories():
|
||||
"""Get directories with changes since last commit"""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["git", "diff", "--name-only", "HEAD"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True
|
||||
)
|
||||
files = result.stdout.strip().split('\n')
|
||||
directories = set()
|
||||
for file in files:
|
||||
if file:
|
||||
directories.add(Path(file).parent)
|
||||
return list(directories)
|
||||
except subprocess.CalledProcessError:
|
||||
return []
|
||||
|
||||
def cmd_start(args):
|
||||
"""Start new session"""
|
||||
if not check_session_initialized():
|
||||
return 1
|
||||
|
||||
# Generate project status report
|
||||
print("📊 Generating project status report...\n")
|
||||
|
||||
# Import from project-status-report plugin
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
# Add project-status-report to path
|
||||
report_plugin_path = Path(__file__).parents[5] / "plugins" / "project-status-report" / "skills" / "project-status-report" / "scripts"
|
||||
if report_plugin_path not in sys.path:
|
||||
sys.path.insert(0, str(report_plugin_path))
|
||||
|
||||
try:
|
||||
from report import ReportGenerator
|
||||
|
||||
generator = ReportGenerator()
|
||||
report = generator.generate()
|
||||
print(report)
|
||||
print("\n" + "=" * 60 + "\n")
|
||||
except ImportError:
|
||||
print("⚠️ project-status-report plugin not found, skipping report\n")
|
||||
|
||||
# Handle branch selection
|
||||
branch = args.branch
|
||||
|
||||
# Only present interactive prompts if branch not provided
|
||||
if not branch:
|
||||
print("What would you like to work on?")
|
||||
print()
|
||||
print("1. Resume existing work (if available)")
|
||||
print("2. Start new work")
|
||||
print("3. Address health issues first")
|
||||
print()
|
||||
|
||||
choice = input("Choice [1/2/3]: ")
|
||||
|
||||
if choice == "1":
|
||||
# Load branch from last session
|
||||
state_file = Path(".sessions") / "state.json"
|
||||
last_branch = None
|
||||
if state_file.exists():
|
||||
try:
|
||||
with open(state_file) as f:
|
||||
last_state = json.load(f)
|
||||
last_branch = last_state.get("branch")
|
||||
except (json.JSONDecodeError, IOError):
|
||||
pass
|
||||
|
||||
if last_branch:
|
||||
print(f"\nLast session was on branch: {last_branch}")
|
||||
resume_choice = input(f"Resume '{last_branch}'? [Y/n]: ").strip().lower()
|
||||
if resume_choice in ['', 'y', 'yes']:
|
||||
branch = last_branch
|
||||
else:
|
||||
branch = input("Enter branch name to resume: ")
|
||||
else:
|
||||
print("\nNo previous session found.")
|
||||
branch = input("Enter branch name to resume: ")
|
||||
else:
|
||||
branch = input("Enter new branch name: ")
|
||||
|
||||
# Checkout or create branch
|
||||
try:
|
||||
subprocess.run(["git", "checkout", branch], check=True, capture_output=True)
|
||||
print(f"✅ Switched to branch: {branch}")
|
||||
except subprocess.CalledProcessError:
|
||||
# Branch doesn't exist, create it
|
||||
try:
|
||||
subprocess.run(["git", "checkout", "-b", branch], check=True, capture_output=True)
|
||||
print(f"✅ Created new branch: {branch}")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"❌ Failed to create branch: {e}")
|
||||
return 1
|
||||
|
||||
# Parse objectives
|
||||
objectives = []
|
||||
if args.objective:
|
||||
objectives = [obj.strip() for obj in args.objective.split(',')]
|
||||
else:
|
||||
print("\nEnter session objectives (comma-separated):")
|
||||
obj_input = input("> ")
|
||||
if obj_input:
|
||||
objectives = [obj.strip() for obj in obj_input.split(',')]
|
||||
|
||||
# Save session state
|
||||
mode = "tdd" if args.tdd else "normal"
|
||||
state = {
|
||||
"branch": branch,
|
||||
"objectives": objectives,
|
||||
"started_at": datetime.now().isoformat(),
|
||||
"mode": mode
|
||||
}
|
||||
|
||||
state_file = Path(".sessions") / "state.json"
|
||||
with open(state_file, 'w') as f:
|
||||
json.dump(state, f, indent=2)
|
||||
|
||||
# Update .ccmp/state.json if available
|
||||
ccmp_state_file = Path(".ccmp") / "state.json"
|
||||
if ccmp_state_file.parent.exists():
|
||||
try:
|
||||
if ccmp_state_file.exists():
|
||||
with open(ccmp_state_file) as f:
|
||||
ccmp_state = json.load(f)
|
||||
else:
|
||||
ccmp_state = {}
|
||||
|
||||
ccmp_state["session-management"] = {
|
||||
"active": True,
|
||||
"branch": branch,
|
||||
"objectives": objectives,
|
||||
"mode": state["mode"]
|
||||
}
|
||||
|
||||
with open(ccmp_state_file, 'w') as f:
|
||||
json.dump(ccmp_state, f, indent=2)
|
||||
except (json.JSONDecodeError, IOError):
|
||||
pass
|
||||
|
||||
# Display session ready message
|
||||
print("\n" + "=" * 60)
|
||||
print("🚀 SESSION READY")
|
||||
print("=" * 60)
|
||||
print(f"Branch: {branch}")
|
||||
print(f"Mode: {state['mode'].upper()}")
|
||||
if objectives:
|
||||
print("\n📋 OBJECTIVES:")
|
||||
for i, obj in enumerate(objectives, 1):
|
||||
print(f" {i}. {obj}")
|
||||
print("=" * 60)
|
||||
|
||||
return 0
|
||||
|
||||
def cmd_resume(args):
|
||||
"""Resume existing session"""
|
||||
if not check_session_initialized():
|
||||
return 1
|
||||
|
||||
# Get branch to resume
|
||||
branch = args.branch if args.branch else get_current_branch()
|
||||
if not branch:
|
||||
print("❌ Not in a git repository")
|
||||
return 1
|
||||
|
||||
# Checkout branch if specified
|
||||
if args.branch:
|
||||
try:
|
||||
subprocess.run(["git", "checkout", branch], check=True, capture_output=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"❌ Failed to checkout branch: {e}")
|
||||
return 1
|
||||
|
||||
if INTEGRATION_AVAILABLE:
|
||||
# Load session state from integration
|
||||
integration = CCMPIntegration()
|
||||
session_state = integration.get_state("session-management")
|
||||
|
||||
if session_state and session_state.get("active"):
|
||||
# Resume with full context
|
||||
session_int = SessionIntegration()
|
||||
brief = session_int.start_session(
|
||||
branch,
|
||||
session_state.get("objectives", []),
|
||||
session_state.get("mode", "normal")
|
||||
)
|
||||
print(brief)
|
||||
else:
|
||||
print(f"⚠️ No active session found for {branch}")
|
||||
print("Start a new session with: python session.py start <branch> --objective \"...\"")
|
||||
else:
|
||||
print(f"Resuming session on branch: {branch}")
|
||||
|
||||
return 0
|
||||
|
||||
def cmd_checkpoint(args):
|
||||
"""Create checkpoint"""
|
||||
if not check_session_initialized():
|
||||
return 1
|
||||
|
||||
# Use new CheckpointManager
|
||||
from checkpoint import CheckpointManager
|
||||
|
||||
manager = CheckpointManager()
|
||||
label = args.label or "checkpoint"
|
||||
notes = args.notes if hasattr(args, 'notes') else None
|
||||
|
||||
checkpoint = manager.generate_checkpoint(
|
||||
notes=notes,
|
||||
label=label
|
||||
)
|
||||
|
||||
print(checkpoint)
|
||||
print(f"\n✅ Checkpoint saved")
|
||||
|
||||
# Git commit handling (if requested)
|
||||
if hasattr(args, 'commit') and args.commit:
|
||||
# Check for uncommitted changes
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["git", "diff", "--quiet"],
|
||||
capture_output=True
|
||||
)
|
||||
if result.returncode != 0: # There are changes
|
||||
# Stage all changes
|
||||
subprocess.run(["git", "add", "."], check=True)
|
||||
|
||||
# Generate commit message
|
||||
commit_msg = args.message if hasattr(args, 'message') and args.message else None
|
||||
|
||||
# If no custom message, use git-commit skill to analyze and suggest
|
||||
if not commit_msg:
|
||||
try:
|
||||
# Run analyze-diff.py from git-commit plugin
|
||||
analyzer_script = repo_root / "plugins" / "git-commit" / "skills" / "git-commit" / "scripts" / "analyze-diff.py"
|
||||
|
||||
if analyzer_script.exists():
|
||||
result = subprocess.run(
|
||||
["python3", str(analyzer_script), "--json"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True
|
||||
)
|
||||
|
||||
analysis = json.loads(result.stdout)
|
||||
|
||||
if analysis and 'error' not in analysis:
|
||||
# Build commit message from analysis
|
||||
msg_type = analysis['type']
|
||||
scope = f"({analysis['scope']})" if analysis['scope'] else ""
|
||||
breaking = "!" if analysis['breaking'] else ""
|
||||
desc = analysis['description']
|
||||
|
||||
commit_msg = f"{msg_type}{scope}{breaking}: {desc}"
|
||||
|
||||
# Add notes as body if provided
|
||||
if notes:
|
||||
commit_msg = f"{commit_msg}\n\n{notes}"
|
||||
|
||||
print(f"\n📊 Analyzed changes: {msg_type} ({analysis['confidence']:.0%} confidence)")
|
||||
print(f"📝 Suggested commit:\n {commit_msg.split(chr(10))[0]}")
|
||||
else:
|
||||
# Fallback to checkpoint label
|
||||
commit_msg = f"checkpoint: {label}"
|
||||
if notes:
|
||||
commit_msg = f"{commit_msg}\n\n{notes}"
|
||||
else:
|
||||
# git-commit skill not found, use simple message
|
||||
commit_msg = f"checkpoint: {label}"
|
||||
if notes:
|
||||
commit_msg = f"{commit_msg}\n\n{notes}"
|
||||
except Exception as e:
|
||||
# On any error, fall back to simple message
|
||||
print(f"⚠️ Commit analysis failed ({e}), using simple message")
|
||||
commit_msg = f"checkpoint: {label}"
|
||||
if notes:
|
||||
commit_msg = f"{commit_msg}\n\n{notes}"
|
||||
else:
|
||||
# Custom message provided, add notes if present
|
||||
if notes:
|
||||
commit_msg = f"{commit_msg}\n\n{notes}"
|
||||
|
||||
# Create commit
|
||||
subprocess.run(["git", "commit", "-m", commit_msg], check=True)
|
||||
print("📝 Git commit created")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"⚠️ Git commit failed: {e}")
|
||||
|
||||
# Legacy integration support
|
||||
if INTEGRATION_AVAILABLE and is_tdd_mode() and hasattr(args, 'tdd_phase') and args.tdd_phase:
|
||||
integration = CCMPIntegration()
|
||||
tdd_state = integration.get_state("tdd-workflow") or {}
|
||||
|
||||
if args.tdd_phase == "GREEN":
|
||||
cycles = tdd_state.get("cycles_today", 0) + 1
|
||||
integration.update_state("tdd-workflow", {
|
||||
"active": True,
|
||||
"cycles_today": cycles,
|
||||
"current_phase": "GREEN",
|
||||
"discipline_score": 100
|
||||
})
|
||||
print(f"\n🎯 TDD Cycles completed today: {cycles}")
|
||||
else:
|
||||
integration.update_state("tdd-workflow", {
|
||||
"active": True,
|
||||
"cycles_today": tdd_state.get("cycles_today", 0),
|
||||
"current_phase": args.tdd_phase,
|
||||
"discipline_score": 100
|
||||
})
|
||||
print(f"\n🧪 TDD: {args.tdd_phase} phase checkpoint created")
|
||||
|
||||
return 0
|
||||
|
||||
def cmd_end(args):
|
||||
"""End session"""
|
||||
if not check_session_initialized():
|
||||
return 1
|
||||
|
||||
# Gather session notes - use args if provided, otherwise prompt
|
||||
accomplished = args.accomplished if hasattr(args, 'accomplished') and args.accomplished else None
|
||||
decisions = args.decisions if hasattr(args, 'decisions') and args.decisions else None
|
||||
remember = args.remember if hasattr(args, 'remember') and args.remember else None
|
||||
|
||||
# Only prompt if not provided via arguments
|
||||
if not accomplished or not decisions or not remember:
|
||||
print("\nSession Summary Notes:")
|
||||
if not accomplished:
|
||||
print("\nWhat did you accomplish?")
|
||||
accomplished = input("> ")
|
||||
if not decisions:
|
||||
print("\nKey decisions made?")
|
||||
decisions = input("> ")
|
||||
if not remember:
|
||||
print("\nWhat to remember for next session?")
|
||||
remember = input("> ")
|
||||
|
||||
session_notes = f"""**Accomplished**: {accomplished}
|
||||
|
||||
**Decisions**: {decisions}
|
||||
|
||||
**Remember**: {remember}
|
||||
"""
|
||||
|
||||
# Generate handoff
|
||||
from handoff import HandoffGenerator
|
||||
|
||||
generator = HandoffGenerator()
|
||||
handoff = generator.generate_handoff(session_notes=session_notes)
|
||||
|
||||
print("\n" + handoff)
|
||||
print(f"\n✅ Session ended. Handoff generated.")
|
||||
|
||||
# Git push handling
|
||||
should_push = False
|
||||
if hasattr(args, 'no_push') and args.no_push:
|
||||
should_push = False
|
||||
elif hasattr(args, 'push') and args.push:
|
||||
should_push = True
|
||||
else:
|
||||
# Default behavior: ask user
|
||||
try:
|
||||
# Check for commits to push
|
||||
result = subprocess.run(
|
||||
["git", "log", "@{u}..", "--oneline"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True
|
||||
)
|
||||
commits = result.stdout.strip().split("\n")
|
||||
|
||||
if commits and commits[0]:
|
||||
print(f"\nCommits to push: {len(commits)}")
|
||||
for commit in commits[:5]:
|
||||
print(f" - {commit}")
|
||||
|
||||
response = input(f"\nPush {len(commits)} commits to remote? [Y/n]: ")
|
||||
should_push = response.lower() != 'n'
|
||||
except subprocess.CalledProcessError:
|
||||
print("⚠️ No commits to push")
|
||||
should_push = False
|
||||
|
||||
# Execute push if decided
|
||||
if should_push:
|
||||
try:
|
||||
subprocess.run(["git", "push"], check=True)
|
||||
print("📤 Pushed to remote")
|
||||
except subprocess.CalledProcessError:
|
||||
print("⚠️ Git push failed")
|
||||
|
||||
# Optional: merge to target branch
|
||||
if hasattr(args, 'merge_to') and args.merge_to:
|
||||
try:
|
||||
current_branch = get_current_branch()
|
||||
subprocess.run(["git", "checkout", args.merge_to], check=True)
|
||||
subprocess.run(["git", "merge", current_branch], check=True)
|
||||
print(f"\n✅ Merged to {args.merge_to}")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"\n❌ Merge failed: {e}")
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
def cmd_status(args):
|
||||
"""Show session status"""
|
||||
if not check_session_initialized():
|
||||
return 1
|
||||
|
||||
branch = get_current_branch()
|
||||
print("📊 Session Status")
|
||||
print("=" * 60)
|
||||
print(f"Branch: {branch}")
|
||||
|
||||
if INTEGRATION_AVAILABLE:
|
||||
integration = CCMPIntegration()
|
||||
session_state = integration.get_state("session-management")
|
||||
|
||||
if session_state and session_state.get("active"):
|
||||
print(f"Status: ✅ Active")
|
||||
print(f"Mode: {session_state.get('mode', 'normal').upper()}")
|
||||
|
||||
# Show objectives
|
||||
objectives = session_state.get("objectives", [])
|
||||
if objectives:
|
||||
print("\n📋 OBJECTIVES:")
|
||||
for i, obj in enumerate(objectives, 1):
|
||||
print(f" {i}. {obj}")
|
||||
|
||||
# Show TDD metrics if in TDD mode
|
||||
if is_tdd_mode():
|
||||
tdd_state = integration.get_state("tdd-workflow")
|
||||
if tdd_state:
|
||||
print("\n🧪 TDD METRICS:")
|
||||
print(f" Cycles today: {tdd_state.get('cycles_today', 0)}")
|
||||
print(f" Current phase: {tdd_state.get('current_phase', 'N/A')}")
|
||||
print(f" Discipline score: {tdd_state.get('discipline_score', 100)}/100")
|
||||
|
||||
# Show context health
|
||||
context_state = integration.get_state("claude-context-manager")
|
||||
if context_state:
|
||||
health_score = context_state.get("health_score")
|
||||
if health_score is not None:
|
||||
print("\n🏥 CONTEXT HEALTH:")
|
||||
print(f" Overall score: {health_score}/100")
|
||||
critical = context_state.get("critical_files", [])
|
||||
if critical:
|
||||
print(f" ⚠️ {len(critical)} files need attention")
|
||||
else:
|
||||
print("Status: ⚪ No active session")
|
||||
print("Start a session with: python session.py start <branch> --objective \"...\"")
|
||||
else:
|
||||
print("Status: ⚠️ Integration not available")
|
||||
|
||||
print("=" * 60)
|
||||
return 0
|
||||
|
||||
def cmd_history(args):
|
||||
"""Show session history"""
|
||||
if not check_session_initialized():
|
||||
return 1
|
||||
|
||||
print(f"Showing last {args.count} sessions...")
|
||||
|
||||
# Implementation would:
|
||||
# 1. Load archived sessions
|
||||
# 2. Display timeline
|
||||
# 3. Show metrics if requested
|
||||
# 4. Calculate trends
|
||||
|
||||
return 0
|
||||
|
||||
def cmd_objectives(args):
|
||||
"""Manage objectives"""
|
||||
if not check_session_initialized():
|
||||
return 1
|
||||
|
||||
if args.action == "add":
|
||||
print(f"Adding objective: {args.text}")
|
||||
elif args.action == "complete":
|
||||
print(f"Completing objective: {args.id}")
|
||||
elif args.action == "list":
|
||||
print("Current Objectives:")
|
||||
# List objectives
|
||||
|
||||
return 0
|
||||
|
||||
def cmd_blockers(args):
|
||||
"""Manage blockers"""
|
||||
if not check_session_initialized():
|
||||
return 1
|
||||
|
||||
if args.action == "add":
|
||||
print(f"Adding blocker: {args.text}")
|
||||
elif args.action == "resolve":
|
||||
print(f"Resolving blocker: {args.id}")
|
||||
elif args.action == "list":
|
||||
print("Active Blockers:")
|
||||
# List blockers
|
||||
|
||||
return 0
|
||||
|
||||
def cmd_decisions(args):
|
||||
"""Log decisions"""
|
||||
if not check_session_initialized():
|
||||
return 1
|
||||
|
||||
if args.action == "add":
|
||||
print(f"Recording decision: {args.text}")
|
||||
if args.rationale:
|
||||
print(f"Rationale: {args.rationale}")
|
||||
elif args.action == "list":
|
||||
print("Decisions:")
|
||||
# List decisions
|
||||
|
||||
return 0
|
||||
|
||||
def cmd_analyze(args):
|
||||
"""Analyze session metrics"""
|
||||
if not check_session_initialized():
|
||||
return 1
|
||||
|
||||
if INTEGRATION_AVAILABLE and is_tdd_mode():
|
||||
# Run TDD analysis
|
||||
analyzer = TDDAnalyzer()
|
||||
|
||||
print("🔍 Analyzing TDD discipline...")
|
||||
print()
|
||||
|
||||
# Analyze commits
|
||||
commit_analysis = analyzer.analyze_session_commits()
|
||||
print(analyzer.generate_violation_report(commit_analysis))
|
||||
|
||||
# Analyze cycle timing
|
||||
cycle_analysis = analyzer.analyze_tdd_cycle_timing()
|
||||
if cycle_analysis["total_cycles"] > 0:
|
||||
print("⏱️ TDD Cycle Timing:")
|
||||
print(f" • Total cycles: {cycle_analysis['total_cycles']}")
|
||||
print(f" • Average cycle time: {cycle_analysis['average_cycle_time']:.1f} minutes")
|
||||
print(f" • Fastest cycle: {cycle_analysis['fastest_cycle']:.1f} minutes")
|
||||
print(f" • Slowest cycle: {cycle_analysis['slowest_cycle']:.1f} minutes")
|
||||
print()
|
||||
else:
|
||||
print("Session Analysis")
|
||||
print("=" * 50)
|
||||
print("Analysis features available in TDD mode with integration enabled")
|
||||
|
||||
return 0
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Session Management CLI")
|
||||
subparsers = parser.add_subparsers(dest="command", help="Command to execute")
|
||||
|
||||
# start command
|
||||
start_parser = subparsers.add_parser("start", help="Start new session")
|
||||
start_parser.add_argument("branch", nargs="?", help="Branch name (optional, will prompt if not provided)")
|
||||
start_parser.add_argument("--objective", help="Session objective (comma-separated for multiple)")
|
||||
start_parser.add_argument("--tdd", action="store_true", help="Enable TDD mode")
|
||||
start_parser.add_argument("--resume", action="store_true", help="Resume if exists")
|
||||
start_parser.set_defaults(func=cmd_start)
|
||||
|
||||
# resume command
|
||||
resume_parser = subparsers.add_parser("resume", help="Resume session")
|
||||
resume_parser.add_argument("branch", nargs="?", help="Branch to resume")
|
||||
resume_parser.set_defaults(func=cmd_resume)
|
||||
|
||||
# checkpoint command
|
||||
checkpoint_parser = subparsers.add_parser("checkpoint", help="Create checkpoint")
|
||||
checkpoint_parser.add_argument("--label", help="Checkpoint label")
|
||||
checkpoint_parser.add_argument("--notes", help="Checkpoint notes")
|
||||
checkpoint_parser.add_argument("--commit", action="store_true", help="Create git commit")
|
||||
checkpoint_parser.add_argument("--message", help="Commit message")
|
||||
checkpoint_parser.add_argument("--decision", help="Record decision")
|
||||
checkpoint_parser.add_argument("--tdd-phase", choices=["RED", "GREEN", "REFACTOR"], help="TDD phase for this checkpoint")
|
||||
checkpoint_parser.set_defaults(func=cmd_checkpoint)
|
||||
|
||||
# end command
|
||||
end_parser = subparsers.add_parser("end", help="End session")
|
||||
end_parser.add_argument("--handoff", action="store_true", default=True, help="Generate handoff")
|
||||
end_parser.add_argument("--push", action="store_true", help="Push commits to remote")
|
||||
end_parser.add_argument("--no-push", action="store_true", help="Don't push commits to remote")
|
||||
end_parser.add_argument("--accomplished", help="What was accomplished in this session")
|
||||
end_parser.add_argument("--decisions", help="Key decisions made")
|
||||
end_parser.add_argument("--remember", help="What to remember for next session")
|
||||
end_parser.add_argument("--merge-to", help="Merge to branch")
|
||||
end_parser.set_defaults(func=cmd_end)
|
||||
|
||||
# status command
|
||||
status_parser = subparsers.add_parser("status", help="Show status")
|
||||
status_parser.add_argument("--verbose", action="store_true", help="Verbose output")
|
||||
status_parser.set_defaults(func=cmd_status)
|
||||
|
||||
# history command
|
||||
history_parser = subparsers.add_parser("history", help="Show history")
|
||||
history_parser.add_argument("--count", type=int, default=10, help="Number of sessions")
|
||||
history_parser.add_argument("--metrics", action="store_true", help="Include metrics")
|
||||
history_parser.set_defaults(func=cmd_history)
|
||||
|
||||
# objectives command
|
||||
objectives_parser = subparsers.add_parser("objectives", help="Manage objectives")
|
||||
objectives_parser.add_argument("action", choices=["add", "complete", "list"])
|
||||
objectives_parser.add_argument("text", nargs="?", help="Objective text")
|
||||
objectives_parser.add_argument("--id", help="Objective ID")
|
||||
objectives_parser.set_defaults(func=cmd_objectives)
|
||||
|
||||
# blockers command
|
||||
blockers_parser = subparsers.add_parser("blockers", help="Manage blockers")
|
||||
blockers_parser.add_argument("action", choices=["add", "resolve", "list"])
|
||||
blockers_parser.add_argument("text", nargs="?", help="Blocker description")
|
||||
blockers_parser.add_argument("--id", help="Blocker ID")
|
||||
blockers_parser.set_defaults(func=cmd_blockers)
|
||||
|
||||
# decisions command
|
||||
decisions_parser = subparsers.add_parser("decisions", help="Log decisions")
|
||||
decisions_parser.add_argument("action", choices=["add", "list"])
|
||||
decisions_parser.add_argument("text", nargs="?", help="Decision text")
|
||||
decisions_parser.add_argument("--rationale", help="Decision rationale")
|
||||
decisions_parser.set_defaults(func=cmd_decisions)
|
||||
|
||||
# analyze command
|
||||
analyze_parser = subparsers.add_parser("analyze", help="Analyze session metrics")
|
||||
analyze_parser.set_defaults(func=cmd_analyze)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.command:
|
||||
parser.print_help()
|
||||
return 1
|
||||
|
||||
return args.func(args)
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
20
skills/session-management/scripts/test_checkpoint.py
Executable file
20
skills/session-management/scripts/test_checkpoint.py
Executable file
@@ -0,0 +1,20 @@
|
||||
import pytest
|
||||
from pathlib import Path
|
||||
from checkpoint import CheckpointManager
|
||||
|
||||
def test_analyze_git_changes():
|
||||
"""Test analyzing git diff for changes"""
|
||||
manager = CheckpointManager()
|
||||
changes = manager.analyze_git_changes()
|
||||
assert isinstance(changes, dict)
|
||||
assert "modified" in changes
|
||||
assert "added" in changes
|
||||
assert "deleted" in changes
|
||||
|
||||
def test_generate_checkpoint():
|
||||
"""Test generating checkpoint document"""
|
||||
manager = CheckpointManager()
|
||||
checkpoint = manager.generate_checkpoint(notes="Test notes")
|
||||
assert isinstance(checkpoint, str)
|
||||
assert "Checkpoint:" in checkpoint
|
||||
assert "What Changed" in checkpoint
|
||||
12
skills/session-management/scripts/test_handoff.py
Executable file
12
skills/session-management/scripts/test_handoff.py
Executable file
@@ -0,0 +1,12 @@
|
||||
import pytest
|
||||
from handoff import HandoffGenerator
|
||||
|
||||
def test_generate_handoff():
|
||||
"""Test generating session handoff document"""
|
||||
generator = HandoffGenerator()
|
||||
handoff = generator.generate_handoff(
|
||||
session_notes="Test session notes"
|
||||
)
|
||||
assert isinstance(handoff, str)
|
||||
assert "Session Handoff" in handoff
|
||||
assert "Test session notes" in handoff
|
||||
Reference in New Issue
Block a user