claude-context-auto-handoff 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +28 -0
- package/.claude-plugin/plugin.json +5 -3
- package/README.ko.md +7 -1
- package/README.md +7 -1
- package/build/index.js +14 -14
- package/hooks/hooks.json +2 -2
- package/package.json +3 -2
- package/scripts/setup.ps1 +10 -10
- package/scripts/setup.sh +10 -10
- package/skills/handoff/SKILL.md +37 -0
- package/skills/resume/SKILL.md +16 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "context-handoff",
|
|
3
|
+
"description": "Claude Code plugin for automatic session context handoff across compactions and stops.",
|
|
4
|
+
"owner": {
|
|
5
|
+
"name": "Ethualo",
|
|
6
|
+
"email": "lkh0926ym@naver.com"
|
|
7
|
+
},
|
|
8
|
+
"plugins": [
|
|
9
|
+
{
|
|
10
|
+
"name": "claude-context-handoff",
|
|
11
|
+
"displayName": "Context Auto-Handoff",
|
|
12
|
+
"description": "Automatically saves session context and generates handoff manifests before Claude compacts or stops.",
|
|
13
|
+
"source": {
|
|
14
|
+
"source": "npm",
|
|
15
|
+
"package": "claude-context-auto-handoff"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/Ethualo/claude-context-auto-handoff",
|
|
18
|
+
"repository": "https://github.com/Ethualo/claude-context-auto-handoff",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"author": {
|
|
21
|
+
"name": "Ethualo",
|
|
22
|
+
"email": "lkh0926ym@naver.com"
|
|
23
|
+
},
|
|
24
|
+
"keywords": ["context", "handoff", "session", "memory", "compaction", "claude-code"],
|
|
25
|
+
"category": "productivity"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
@@ -6,9 +6,11 @@
|
|
|
6
6
|
"name": "Ethualo",
|
|
7
7
|
"email": "lkh0926ym@naver.com"
|
|
8
8
|
},
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
"homepage": "https://github.com/Ethualo/claude-context-auto-handoff",
|
|
10
|
+
"repository": "https://github.com/Ethualo/claude-context-auto-handoff",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": ["context", "handoff", "session", "memory", "compaction", "claude-code"],
|
|
13
|
+
"category": "productivity",
|
|
12
14
|
"mcpServers": {
|
|
13
15
|
"context-handoff-manager": {
|
|
14
16
|
"command": "node",
|
package/README.ko.md
CHANGED
|
@@ -6,7 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|

|
|
8
8
|

|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 필수 요구사항
|
|
13
|
+
|
|
14
|
+
- **Node.js 18+** — `node` 명령어가 `PATH`에 있어야 함
|
|
15
|
+
- **Claude Code** 또는 **Codex** — 플러그인 및 훅 실행에 Claude Code CLI 또는 Codex CLI 필요
|
|
10
16
|
|
|
11
17
|
---
|
|
12
18
|
|
package/README.md
CHANGED
|
@@ -6,7 +6,13 @@ Claude Code plugin that automatically saves session context and generates token-
|
|
|
6
6
|
|
|
7
7
|

|
|
8
8
|

|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Requirements
|
|
13
|
+
|
|
14
|
+
- **Node.js 18+** — must be on `PATH` as `node`
|
|
15
|
+
- **Claude Code** or **Codex** — plugin and hooks require Claude Code CLI or Codex CLI
|
|
10
16
|
|
|
11
17
|
---
|
|
12
18
|
|
package/build/index.js
CHANGED
|
@@ -9,23 +9,23 @@ const server = new McpServer({
|
|
|
9
9
|
version: '1.0.0'
|
|
10
10
|
});
|
|
11
11
|
server.tool('generate_handoff_manifest', {
|
|
12
|
-
summary: z.string().optional().describe('Detailed session recap — omit if other fields cover it'),
|
|
13
|
-
nextSteps: z.array(z.string()).describe('Tasks to continue immediately in the next session'),
|
|
14
|
-
taskDescription: z.string().optional().describe('High-level goal + core intent (why this matters). Use telegraphese — drop articles/pronouns.'),
|
|
15
|
-
currentStatus: z.string().optional().describe('What is done vs what remains. State why, not just what.'),
|
|
16
|
-
keyDecisions: z.array(z.string()).optional().describe('Architecture choices and why — prevents post-compaction amnesia. Format: "Decision: X — Reason: Y"'),
|
|
17
|
-
failedApproaches: z.array(z.string()).optional().describe('Already-failed attempts. Format each: "Approach: X → Result: Y → Lesson: Z". Prevents repeating mistakes.'),
|
|
18
|
-
blockers: z.string().optional().describe('Unresolved errors or blockers'),
|
|
12
|
+
summary: z.string().optional().describe('Detailed session recap in English — omit if other fields cover it'),
|
|
13
|
+
nextSteps: z.array(z.string()).describe('Tasks to continue immediately in the next session. Write in English.'),
|
|
14
|
+
taskDescription: z.string().optional().describe('High-level goal + core intent (why this matters). Use telegraphese — drop articles/pronouns. Write in English.'),
|
|
15
|
+
currentStatus: z.string().optional().describe('What is done vs what remains. State why, not just what. Write in English.'),
|
|
16
|
+
keyDecisions: z.array(z.string()).optional().describe('Architecture choices and why — prevents post-compaction amnesia. Format: "Decision: X — Reason: Y". Write in English.'),
|
|
17
|
+
failedApproaches: z.array(z.string()).optional().describe('Already-failed attempts. Format each: "Approach: X → Result: Y → Lesson: Z". Prevents repeating mistakes. Write in English.'),
|
|
18
|
+
blockers: z.string().optional().describe('Unresolved errors or blockers. Write in English.'),
|
|
19
19
|
modifiedFiles: z.array(z.string()).optional().describe('Changed files with delta notes. Format: "path/to/file: what changed" — NO code snippets, path+delta only.'),
|
|
20
|
-
implicitRules: z.array(z.string()).optional().describe('Tech stack, naming conventions, env vars, implicit project rules — anything not derivable from reading code')
|
|
21
|
-
|
|
20
|
+
implicitRules: z.array(z.string()).optional().describe('Tech stack, naming conventions, env vars, implicit project rules — anything not derivable from reading code. Write in English.'),
|
|
21
|
+
workingDirectory: z.string().optional().describe('Absolute path to the project root where handoff.md should be written. Required on Windows where process.cwd() may return System32.')
|
|
22
|
+
}, async ({ summary, nextSteps, taskDescription, currentStatus, keyDecisions, failedApproaches, blockers, modifiedFiles, implicitRules, workingDirectory }) => {
|
|
22
23
|
try {
|
|
23
|
-
const
|
|
24
|
+
const projectRoot = workingDirectory || process.env['CLAUDE_PROJECT_DIR'] || process.cwd();
|
|
25
|
+
const claudeDir = path.join(projectRoot, '.claude');
|
|
24
26
|
const handoffsDir = path.join(claudeDir, 'handoffs');
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (!fs.existsSync(handoffsDir))
|
|
28
|
-
fs.mkdirSync(handoffsDir, { recursive: true });
|
|
27
|
+
fs.mkdirSync(claudeDir, { recursive: true });
|
|
28
|
+
fs.mkdirSync(handoffsDir, { recursive: true });
|
|
29
29
|
const now = new Date();
|
|
30
30
|
const displayTime = now.toLocaleString();
|
|
31
31
|
const timestamp = now.toISOString().replace(/[:.]/g, '-');
|
package/hooks/hooks.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"hooks": [
|
|
6
6
|
{
|
|
7
7
|
"type": "prompt",
|
|
8
|
-
"prompt": "CRITICAL: Context compaction imminent. Call 'generate_handoff_manifest' NOW before compaction. Fill all fields: summary (full session recap), taskDescription (goal), currentStatus (done vs remaining), keyDecisions (architecture choices + why), failedApproaches (already-failed — do NOT retry), nextSteps (next session tasks), blockers (unresolved errors). Do NOT allow compaction without calling this tool."
|
|
8
|
+
"prompt": "CRITICAL: Context compaction imminent. Call 'generate_handoff_manifest' NOW before compaction. Fill all fields: summary (full session recap), taskDescription (goal), currentStatus (done vs remaining), keyDecisions (architecture choices + why), failedApproaches (already-failed — do NOT retry), nextSteps (next session tasks), blockers (unresolved errors). Write ALL field values in English. Do NOT allow compaction without calling this tool."
|
|
9
9
|
}
|
|
10
10
|
]
|
|
11
11
|
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"hooks": [
|
|
16
16
|
{
|
|
17
17
|
"type": "prompt",
|
|
18
|
-
"prompt": "If a work unit just completed (feature done, tests passed, commit made), call 'generate_handoff_manifest'. Fill taskDescription, keyDecisions, and failedApproaches so the next session has full context."
|
|
18
|
+
"prompt": "If a work unit just completed (feature done, tests passed, commit made), call 'generate_handoff_manifest'. Fill taskDescription, keyDecisions, and failedApproaches so the next session has full context. Write ALL field values in English."
|
|
19
19
|
}
|
|
20
20
|
]
|
|
21
21
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-context-auto-handoff",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "A Claude Code plugin to automate session handoffs before context compaction.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "build/index.js",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"build",
|
|
13
13
|
".claude-plugin",
|
|
14
14
|
"hooks",
|
|
15
|
+
"skills",
|
|
15
16
|
"templates",
|
|
16
17
|
"scripts",
|
|
17
18
|
"README.md",
|
|
@@ -33,4 +34,4 @@
|
|
|
33
34
|
"@types/node": "^20.11.0",
|
|
34
35
|
"typescript": "^5.3.3"
|
|
35
36
|
}
|
|
36
|
-
}
|
|
37
|
+
}
|
package/scripts/setup.ps1
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# context-handoff-mcp-server
|
|
1
|
+
# context-handoff-mcp-server -- one-line setup for Windows (PowerShell)
|
|
2
2
|
# Usage: irm https://raw.githubusercontent.com/Ethualo/context-handoff-mcp-server/main/scripts/setup.ps1 | iex
|
|
3
3
|
|
|
4
4
|
$ErrorActionPreference = "Stop"
|
|
@@ -11,25 +11,25 @@ Write-Host "[Handoff Setup] Installing $PluginName..."
|
|
|
11
11
|
# 1. npm global install (builds TypeScript)
|
|
12
12
|
npm install -g claude-context-auto-handoff
|
|
13
13
|
|
|
14
|
-
# 2. hooks.json
|
|
14
|
+
# 2. Register hooks.json (warn if already exists)
|
|
15
15
|
$NpmRoot = (npm root -g).Trim()
|
|
16
16
|
$HooksSrc = Join-Path $NpmRoot "claude-context-auto-handoff\hooks\hooks.json"
|
|
17
17
|
|
|
18
18
|
if (Test-Path $HooksTarget) {
|
|
19
|
-
Write-Host "[Handoff Setup] WARNING: $HooksTarget
|
|
20
|
-
Write-Host "
|
|
19
|
+
Write-Host "[Handoff Setup] WARNING: $HooksTarget already exists."
|
|
20
|
+
Write-Host " Manually merge contents from: $HooksSrc"
|
|
21
21
|
} else {
|
|
22
22
|
$HooksDir = Split-Path $HooksTarget
|
|
23
23
|
if (-not (Test-Path $HooksDir)) { New-Item -ItemType Directory -Force $HooksDir | Out-Null }
|
|
24
24
|
Copy-Item $HooksSrc $HooksTarget
|
|
25
|
-
Write-Host "[Handoff Setup] hooks.json
|
|
25
|
+
Write-Host "[Handoff Setup] hooks.json registered: $HooksTarget"
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
Write-Host ""
|
|
29
|
-
Write-Host "[Handoff Setup]
|
|
29
|
+
Write-Host "[Handoff Setup] Done!"
|
|
30
30
|
Write-Host ""
|
|
31
|
-
Write-Host "
|
|
32
|
-
Write-Host " /handoff
|
|
33
|
-
Write-Host " /resume
|
|
31
|
+
Write-Host " Usage:"
|
|
32
|
+
Write-Host " /handoff -- save current session"
|
|
33
|
+
Write-Host " /resume -- restore previous session"
|
|
34
34
|
Write-Host ""
|
|
35
|
-
Write-Host " SessionStart
|
|
35
|
+
Write-Host " SessionStart hook auto-restores previous context on session open."
|
package/scripts/setup.sh
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# context-handoff-mcp-server
|
|
2
|
+
# context-handoff-mcp-server -- one-line setup for Linux/macOS
|
|
3
3
|
# Usage: curl -fsSL https://raw.githubusercontent.com/Ethualo/context-handoff-mcp-server/main/scripts/setup.sh | bash
|
|
4
4
|
|
|
5
5
|
set -e
|
|
@@ -12,23 +12,23 @@ echo "[Handoff Setup] Installing $PLUGIN_NAME..."
|
|
|
12
12
|
# 1. npm global install (builds TypeScript)
|
|
13
13
|
npm install -g claude-context-auto-handoff
|
|
14
14
|
|
|
15
|
-
# 2. hooks.json
|
|
15
|
+
# 2. Register hooks.json (warn if already exists)
|
|
16
16
|
HOOKS_SRC="$(npm root -g)/claude-context-auto-handoff/hooks/hooks.json"
|
|
17
17
|
|
|
18
18
|
if [ -f "$HOOKS_TARGET" ]; then
|
|
19
|
-
echo "[Handoff Setup] WARNING: $HOOKS_TARGET
|
|
20
|
-
echo "
|
|
19
|
+
echo "[Handoff Setup] WARNING: $HOOKS_TARGET already exists."
|
|
20
|
+
echo " Manually merge contents from: $HOOKS_SRC"
|
|
21
21
|
else
|
|
22
22
|
mkdir -p "$(dirname "$HOOKS_TARGET")"
|
|
23
23
|
cp "$HOOKS_SRC" "$HOOKS_TARGET"
|
|
24
|
-
echo "[Handoff Setup] hooks.json
|
|
24
|
+
echo "[Handoff Setup] hooks.json registered: $HOOKS_TARGET"
|
|
25
25
|
fi
|
|
26
26
|
|
|
27
27
|
echo ""
|
|
28
|
-
echo "[Handoff Setup]
|
|
28
|
+
echo "[Handoff Setup] Done!"
|
|
29
29
|
echo ""
|
|
30
|
-
echo "
|
|
31
|
-
echo " /handoff
|
|
32
|
-
echo " /resume
|
|
30
|
+
echo " Usage:"
|
|
31
|
+
echo " /handoff -- save current session"
|
|
32
|
+
echo " /resume -- restore previous session"
|
|
33
33
|
echo ""
|
|
34
|
-
echo " SessionStart
|
|
34
|
+
echo " SessionStart hook auto-restores previous context on session open."
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Save current session context to handoff file. Use when user runs /handoff or asks to save session state before ending.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Save session context to `.claude/handoff.md` and timestamped archive to `.claude/handoffs/`.
|
|
6
|
+
|
|
7
|
+
## Content Generation Rules (STRICT)
|
|
8
|
+
|
|
9
|
+
Write all field values using telegraphese — drop articles, pronouns, polite words. Maximize density.
|
|
10
|
+
|
|
11
|
+
- **NO code snippets** in any field. Reference file paths + line-level delta notes only.
|
|
12
|
+
- **WHY over WHAT**: Every decision/status must state the reason, not just the action.
|
|
13
|
+
- **failedApproaches**: Format each entry as `"Approach: X → Result: Y → Lesson: Z"`. This prevents the next session from repeating mistakes.
|
|
14
|
+
- **taskDescription**: Include both Goal and Core Intent (why this matters to the project).
|
|
15
|
+
- **implicitRules**: Capture tech stack, naming conventions, env vars — anything not derivable from reading the code.
|
|
16
|
+
|
|
17
|
+
## Steps
|
|
18
|
+
|
|
19
|
+
1. Gather from current session:
|
|
20
|
+
- taskDescription: final goal + core intent (why)
|
|
21
|
+
- summary: terse session recap (telegraphese)
|
|
22
|
+
- currentStatus: done vs remaining
|
|
23
|
+
- keyDecisions: architecture choices + why (prevents post-compaction amnesia)
|
|
24
|
+
- failedApproaches: already-failed attempts in `Approach→Result→Lesson` format
|
|
25
|
+
- blockers: unresolved errors
|
|
26
|
+
- modifiedFiles: changed files with delta notes (no code, path + what changed)
|
|
27
|
+
- implicitRules: stack, conventions, env vars
|
|
28
|
+
|
|
29
|
+
2. Call `generate_handoff_manifest`:
|
|
30
|
+
- `summary`, `nextSteps` — required
|
|
31
|
+
- `taskDescription`, `currentStatus`, `keyDecisions`, `failedApproaches`, `modifiedFiles`, `implicitRules` — recommended
|
|
32
|
+
- `blockers` — optional
|
|
33
|
+
|
|
34
|
+
3. Confirm to user:
|
|
35
|
+
- Latest: `.claude/handoff.md`
|
|
36
|
+
- Archive: `.claude/handoffs/handoff-{timestamp}.md`
|
|
37
|
+
- Next session: run `/resume` or SessionStart hook auto-restores
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Restore previous session context from handoff file. Use when user runs /resume or asks to continue from last session.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Reads `.claude/handoff.md`. Falls back to latest file in `.claude/handoffs/`.
|
|
6
|
+
|
|
7
|
+
## Steps
|
|
8
|
+
|
|
9
|
+
1. Read `.claude/handoff.md`
|
|
10
|
+
2. If missing, find latest `handoff-*.md` in `.claude/handoffs/`
|
|
11
|
+
3. If neither found: tell user "No handoff file. Run /handoff first."
|
|
12
|
+
4. If found:
|
|
13
|
+
- Parse: Task Description, Current Status, Key Decisions, Failed Approaches, Blockers, Next Steps
|
|
14
|
+
- Brief user in their language
|
|
15
|
+
- Never retry Failed Approaches
|
|
16
|
+
- Start from first Next Step immediately
|