@lumenflow/cli 2.9.0 → 2.11.0
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/README.md +23 -2
- package/dist/__tests__/gates-integration-tests.test.js +112 -0
- package/dist/__tests__/init.test.js +225 -0
- package/dist/__tests__/safe-git.test.js +4 -4
- package/dist/__tests__/wu-create-required-fields.test.js +22 -0
- package/dist/__tests__/wu-create.test.js +72 -0
- package/dist/gates.js +6 -8
- package/dist/hooks/enforcement-generator.js +256 -5
- package/dist/hooks/enforcement-sync.js +52 -6
- package/dist/init.js +195 -2
- package/dist/mem-recover.js +221 -0
- package/dist/orchestrate-initiative.js +19 -1
- package/dist/state-doctor-fix.js +36 -1
- package/dist/state-doctor.js +10 -6
- package/dist/wu-create.js +37 -15
- package/dist/wu-recover.js +53 -2
- package/dist/wu-spawn.js +2 -2
- package/package.json +6 -6
- package/templates/core/.mcp.json.template +8 -0
- package/templates/core/LUMENFLOW.md.template +24 -0
- package/templates/core/ai/onboarding/first-wu-mistakes.md.template +47 -0
- package/templates/core/ai/onboarding/lumenflow-force-usage.md.template +183 -0
- package/templates/core/ai/onboarding/quick-ref-commands.md.template +68 -55
- package/templates/core/ai/onboarding/release-process.md.template +58 -4
- package/templates/core/ai/onboarding/starting-prompt.md.template +67 -3
- package/templates/core/ai/onboarding/vendor-support.md.template +73 -0
- package/templates/core/scripts/safe-git.template +29 -0
- package/templates/vendors/claude/.claude/hooks/pre-compact-checkpoint.sh +102 -0
- package/templates/vendors/claude/.claude/hooks/session-start-recovery.sh +74 -0
- package/templates/vendors/claude/.claude/settings.json.template +42 -0
- package/templates/vendors/claude/.claude/skills/context-management/SKILL.md.template +23 -6
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
#
|
|
3
|
+
# safe-git
|
|
4
|
+
#
|
|
5
|
+
# A wrapper around git that blocks dangerous operations in the LumenFlow environment.
|
|
6
|
+
# Specifically intercepts 'worktree remove' to prevent orphan directories and state corruption.
|
|
7
|
+
# For all other commands, it passes through to the system git.
|
|
8
|
+
#
|
|
9
|
+
|
|
10
|
+
set -e
|
|
11
|
+
|
|
12
|
+
# Block 'worktree remove'
|
|
13
|
+
if [ "$1" = "worktree" ] && [ "$2" = "remove" ]; then
|
|
14
|
+
echo "" >&2
|
|
15
|
+
echo "=== LUMENFLOW SAFETY BLOCK ===" >&2
|
|
16
|
+
echo "" >&2
|
|
17
|
+
echo "BLOCKED: Manual 'git worktree remove' is unsafe in this environment." >&2
|
|
18
|
+
echo "" >&2
|
|
19
|
+
echo "REASON: Manual removal leaves orphan directories and corrupts agent state." >&2
|
|
20
|
+
echo "" >&2
|
|
21
|
+
echo "USE INSTEAD:" >&2
|
|
22
|
+
echo " pnpm wu:done --id <ID> (To complete a task)" >&2
|
|
23
|
+
echo " pnpm wu:cleanup --id <ID> (To discard a task)" >&2
|
|
24
|
+
echo "==============================" >&2
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# Pass through to real git
|
|
29
|
+
exec git "$@"
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# pre-compact-checkpoint.sh
|
|
4
|
+
#
|
|
5
|
+
# PreCompact hook - auto-checkpoint + durable recovery marker (WU-1390)
|
|
6
|
+
#
|
|
7
|
+
# Fires before context compaction to:
|
|
8
|
+
# 1. Save a checkpoint with the current WU progress
|
|
9
|
+
# 2. Write a durable recovery file that survives compaction
|
|
10
|
+
#
|
|
11
|
+
# The recovery file is read by session-start-recovery.sh on the next
|
|
12
|
+
# session start (after compact, resume, or clear) to restore context.
|
|
13
|
+
#
|
|
14
|
+
# Exit codes:
|
|
15
|
+
# 0 = Always allow (cannot block compaction)
|
|
16
|
+
#
|
|
17
|
+
# Uses python3 for JSON parsing (consistent with other hooks)
|
|
18
|
+
#
|
|
19
|
+
|
|
20
|
+
set -euo pipefail
|
|
21
|
+
|
|
22
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
23
|
+
|
|
24
|
+
# Derive repo paths from CLAUDE_PROJECT_DIR
|
|
25
|
+
if [[ -n "${CLAUDE_PROJECT_DIR:-}" ]]; then
|
|
26
|
+
REPO_PATH="$CLAUDE_PROJECT_DIR"
|
|
27
|
+
else
|
|
28
|
+
REPO_PATH=$(git rev-parse --show-toplevel 2>/dev/null || echo "")
|
|
29
|
+
if [[ -z "$REPO_PATH" ]]; then
|
|
30
|
+
exit 0
|
|
31
|
+
fi
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# Read JSON input from stdin
|
|
35
|
+
INPUT=$(cat)
|
|
36
|
+
|
|
37
|
+
# Parse trigger from hook input (defensive - default to "auto")
|
|
38
|
+
# PreCompact provides: { "trigger": "manual" | "auto" }
|
|
39
|
+
TRIGGER=$(python3 -c "
|
|
40
|
+
import json
|
|
41
|
+
import sys
|
|
42
|
+
try:
|
|
43
|
+
data = json.loads('''$INPUT''')
|
|
44
|
+
trigger = data.get('trigger', 'auto')
|
|
45
|
+
print(trigger if trigger else 'auto')
|
|
46
|
+
except:
|
|
47
|
+
print('auto')
|
|
48
|
+
" 2>/dev/null || echo "auto")
|
|
49
|
+
|
|
50
|
+
# Get WU ID from worktree context (wu:status --json)
|
|
51
|
+
# Location.worktreeWuId is set when in a worktree
|
|
52
|
+
WU_ID=$(pnpm wu:status --json 2>/dev/null | python3 -c "
|
|
53
|
+
import json
|
|
54
|
+
import sys
|
|
55
|
+
try:
|
|
56
|
+
data = json.load(sys.stdin)
|
|
57
|
+
location = data.get('location', {})
|
|
58
|
+
wu_id = location.get('worktreeWuId') or ''
|
|
59
|
+
print(wu_id)
|
|
60
|
+
except:
|
|
61
|
+
print('')
|
|
62
|
+
" 2>/dev/null || echo "")
|
|
63
|
+
|
|
64
|
+
# Only proceed if we have a WU ID (working in a worktree)
|
|
65
|
+
if [[ -n "$WU_ID" ]]; then
|
|
66
|
+
# Save checkpoint with pre-compact trigger
|
|
67
|
+
# Note: This may fail if CLI not built, but that's OK - recovery file is more important
|
|
68
|
+
pnpm mem:checkpoint "Auto: pre-${TRIGGER}-compaction" --wu "$WU_ID" --trigger "pre-compact" --quiet 2>/dev/null || true
|
|
69
|
+
|
|
70
|
+
# Write durable recovery marker (survives compaction)
|
|
71
|
+
# This is the key mechanism - file persists and is read by session-start-recovery.sh
|
|
72
|
+
RECOVERY_DIR="${REPO_PATH}/.lumenflow/state"
|
|
73
|
+
RECOVERY_FILE="${RECOVERY_DIR}/recovery-pending-${WU_ID}.md"
|
|
74
|
+
|
|
75
|
+
mkdir -p "$RECOVERY_DIR"
|
|
76
|
+
|
|
77
|
+
# Generate recovery context using mem:recover
|
|
78
|
+
# The --quiet flag outputs only the recovery context without headers
|
|
79
|
+
pnpm mem:recover --wu "$WU_ID" --quiet > "$RECOVERY_FILE" 2>/dev/null || {
|
|
80
|
+
# Fallback minimal recovery if mem:recover fails
|
|
81
|
+
cat > "$RECOVERY_FILE" << EOF
|
|
82
|
+
# POST-COMPACTION RECOVERY
|
|
83
|
+
|
|
84
|
+
You are resuming work after context compaction. Your previous context was lost.
|
|
85
|
+
**WU:** ${WU_ID}
|
|
86
|
+
|
|
87
|
+
## Next Action
|
|
88
|
+
Run \`pnpm wu:spawn --id ${WU_ID}\` to spawn a fresh agent with full context.
|
|
89
|
+
EOF
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
# Output brief warning to stderr (may be compacted away, but recovery file persists)
|
|
93
|
+
echo "" >&2
|
|
94
|
+
echo "═══════════════════════════════════════════════════════" >&2
|
|
95
|
+
echo "⚠️ COMPACTION: Checkpoint saved for ${WU_ID}" >&2
|
|
96
|
+
echo "Recovery context: ${RECOVERY_FILE}" >&2
|
|
97
|
+
echo "Next: pnpm wu:spawn --id ${WU_ID}" >&2
|
|
98
|
+
echo "═══════════════════════════════════════════════════════" >&2
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
# Always exit 0 - cannot block compaction
|
|
102
|
+
exit 0
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# session-start-recovery.sh
|
|
4
|
+
#
|
|
5
|
+
# SessionStart hook - check for pending recovery and inject context (WU-1390)
|
|
6
|
+
#
|
|
7
|
+
# Fires after session start (on compact, resume, or clear) to:
|
|
8
|
+
# 1. Check for recovery-pending-*.md files written by pre-compact-checkpoint.sh
|
|
9
|
+
# 2. Display the recovery context to the agent
|
|
10
|
+
# 3. Remove the recovery file (one-time recovery)
|
|
11
|
+
#
|
|
12
|
+
# This completes the durable recovery pattern:
|
|
13
|
+
# PreCompact writes file → SessionStart reads and deletes it
|
|
14
|
+
#
|
|
15
|
+
# Exit codes:
|
|
16
|
+
# 0 = Always allow (informational hook)
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
set -euo pipefail
|
|
20
|
+
|
|
21
|
+
# Derive repo paths from CLAUDE_PROJECT_DIR
|
|
22
|
+
if [[ -n "${CLAUDE_PROJECT_DIR:-}" ]]; then
|
|
23
|
+
REPO_PATH="$CLAUDE_PROJECT_DIR"
|
|
24
|
+
else
|
|
25
|
+
REPO_PATH=$(git rev-parse --show-toplevel 2>/dev/null || echo "")
|
|
26
|
+
if [[ -z "$REPO_PATH" ]]; then
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
RECOVERY_DIR="${REPO_PATH}/.lumenflow/state"
|
|
32
|
+
|
|
33
|
+
# Check if recovery directory exists
|
|
34
|
+
if [[ ! -d "$RECOVERY_DIR" ]]; then
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# Find any pending recovery files
|
|
39
|
+
FOUND_RECOVERY=false
|
|
40
|
+
|
|
41
|
+
for recovery_file in "$RECOVERY_DIR"/recovery-pending-*.md; do
|
|
42
|
+
# Check if glob matched any files (bash glob returns literal pattern if no match)
|
|
43
|
+
[[ -f "$recovery_file" ]] || continue
|
|
44
|
+
|
|
45
|
+
FOUND_RECOVERY=true
|
|
46
|
+
|
|
47
|
+
# Extract WU ID from filename for display
|
|
48
|
+
WU_ID=$(basename "$recovery_file" | sed 's/recovery-pending-\(.*\)\.md/\1/')
|
|
49
|
+
|
|
50
|
+
echo "" >&2
|
|
51
|
+
echo "═══════════════════════════════════════════════════════" >&2
|
|
52
|
+
echo "⚠️ POST-COMPACTION RECOVERY DETECTED" >&2
|
|
53
|
+
echo "═══════════════════════════════════════════════════════" >&2
|
|
54
|
+
echo "" >&2
|
|
55
|
+
|
|
56
|
+
# Display the recovery context
|
|
57
|
+
cat "$recovery_file" >&2
|
|
58
|
+
|
|
59
|
+
echo "" >&2
|
|
60
|
+
echo "═══════════════════════════════════════════════════════" >&2
|
|
61
|
+
echo "" >&2
|
|
62
|
+
|
|
63
|
+
# Remove after displaying (one-time recovery)
|
|
64
|
+
rm -f "$recovery_file"
|
|
65
|
+
done
|
|
66
|
+
|
|
67
|
+
# Additional context if recovery was displayed
|
|
68
|
+
if [[ "$FOUND_RECOVERY" == "true" ]]; then
|
|
69
|
+
echo "IMPORTANT: Your context was compacted. Review the recovery info above." >&2
|
|
70
|
+
echo "Recommended: Run 'pnpm wu:spawn --id $WU_ID' for fresh full context." >&2
|
|
71
|
+
echo "" >&2
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
exit 0
|
|
@@ -45,5 +45,47 @@
|
|
|
45
45
|
"Bash(/usr/bin/git worktree prune *)"
|
|
46
46
|
],
|
|
47
47
|
"disableBypassPermissionsMode": "disable"
|
|
48
|
+
},
|
|
49
|
+
"hooks": {
|
|
50
|
+
"PreCompact": [
|
|
51
|
+
{
|
|
52
|
+
"matcher": ".*",
|
|
53
|
+
"hooks": [
|
|
54
|
+
{
|
|
55
|
+
"type": "command",
|
|
56
|
+
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/pre-compact-checkpoint.sh"
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"SessionStart": [
|
|
62
|
+
{
|
|
63
|
+
"matcher": "compact",
|
|
64
|
+
"hooks": [
|
|
65
|
+
{
|
|
66
|
+
"type": "command",
|
|
67
|
+
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/session-start-recovery.sh"
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"matcher": "resume",
|
|
73
|
+
"hooks": [
|
|
74
|
+
{
|
|
75
|
+
"type": "command",
|
|
76
|
+
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/session-start-recovery.sh"
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"matcher": "clear",
|
|
82
|
+
"hooks": [
|
|
83
|
+
{
|
|
84
|
+
"type": "command",
|
|
85
|
+
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/session-start-recovery.sh"
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
]
|
|
48
90
|
}
|
|
49
91
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: context-management
|
|
3
3
|
description: Session checkpoint patterns, output bypass for large results, when to spawn fresh sub-agents. Use for long-running sessions, context exhaustion, or agent coordination.
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.0
|
|
5
5
|
source: docs/04-operations/_frameworks/lumenflow/agent/onboarding/agent-invocation-guide.md
|
|
6
6
|
source_sections: Context Tiers, Session Management, Wave Orchestration
|
|
7
7
|
last_updated: {{DATE}}
|
|
@@ -76,16 +76,33 @@ pnpm mem:ready --wu WU-123 # Shows pending work
|
|
|
76
76
|
pnpm mem:inbox --wu WU-123 # Check signals from other agents
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
###
|
|
79
|
+
### Durable Recovery Pattern (WU-1390/1394)
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
LumenFlow implements automatic recovery hooks that preserve context across compaction:
|
|
82
|
+
|
|
83
|
+
**Hook Files** (scaffolded by `lumenflow init --client claude`):
|
|
84
|
+
|
|
85
|
+
- `.claude/hooks/pre-compact-checkpoint.sh` — PreCompact hook: saves checkpoint + writes recovery file
|
|
86
|
+
- `.claude/hooks/session-start-recovery.sh` — SessionStart hook: reads recovery file on compact/resume/clear
|
|
87
|
+
|
|
88
|
+
**How It Works:**
|
|
89
|
+
|
|
90
|
+
1. **Before compaction**: PreCompact hook writes `.lumenflow/state/recovery-pending-WU-XXX.md`
|
|
91
|
+
2. **After session start**: SessionStart hook reads + displays recovery context, then deletes the file
|
|
92
|
+
3. **Recovery file persists** through compaction — this is the durable part
|
|
93
|
+
|
|
94
|
+
**Manual Recovery:**
|
|
82
95
|
|
|
83
96
|
```bash
|
|
84
|
-
|
|
97
|
+
# Generate recovery context manually (if hooks didn't fire)
|
|
98
|
+
pnpm mem:recover --wu WU-XXX
|
|
99
|
+
|
|
100
|
+
# Generate spawn prompt with full context
|
|
101
|
+
pnpm wu:spawn --id WU-XXX
|
|
85
102
|
```
|
|
86
103
|
|
|
87
|
-
|
|
88
|
-
|
|
104
|
+
**Important**: The recovery hooks are a safety net. The recommended approach is still to spawn
|
|
105
|
+
a fresh agent before compaction rather than relying on post-compaction recovery.
|
|
89
106
|
|
|
90
107
|
## Output Bypass Pattern
|
|
91
108
|
|