@ekkos/cli 0.2.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/dist/cache/LocalSessionStore.d.ts +129 -0
- package/dist/cache/LocalSessionStore.js +688 -0
- package/dist/cache/capture.d.ts +26 -0
- package/dist/cache/capture.js +461 -0
- package/dist/cache/index.d.ts +7 -0
- package/dist/cache/index.js +23 -0
- package/dist/cache/types.d.ts +147 -0
- package/dist/cache/types.js +40 -0
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.js +478 -0
- package/dist/commands/run.d.ts +12 -0
- package/dist/commands/run.js +829 -0
- package/dist/commands/setup.d.ts +6 -0
- package/dist/commands/setup.js +658 -0
- package/dist/commands/status.d.ts +1 -0
- package/dist/commands/status.js +109 -0
- package/dist/commands/test.d.ts +1 -0
- package/dist/commands/test.js +157 -0
- package/dist/deploy/agents.d.ts +15 -0
- package/dist/deploy/agents.js +72 -0
- package/dist/deploy/hooks.d.ts +16 -0
- package/dist/deploy/hooks.js +121 -0
- package/dist/deploy/index.d.ts +7 -0
- package/dist/deploy/index.js +24 -0
- package/dist/deploy/instructions.d.ts +12 -0
- package/dist/deploy/instructions.js +36 -0
- package/dist/deploy/mcp.d.ts +19 -0
- package/dist/deploy/mcp.js +109 -0
- package/dist/deploy/plugins.d.ts +19 -0
- package/dist/deploy/plugins.js +62 -0
- package/dist/deploy/settings.d.ts +8 -0
- package/dist/deploy/settings.js +84 -0
- package/dist/deploy/skills.d.ts +19 -0
- package/dist/deploy/skills.js +60 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +71 -0
- package/dist/restore/RestoreOrchestrator.d.ts +48 -0
- package/dist/restore/RestoreOrchestrator.js +481 -0
- package/dist/restore/index.d.ts +4 -0
- package/dist/restore/index.js +20 -0
- package/dist/utils/platform.d.ts +29 -0
- package/dist/utils/platform.js +65 -0
- package/dist/utils/session-words.json +119 -0
- package/dist/utils/state.d.ts +57 -0
- package/dist/utils/state.js +186 -0
- package/dist/utils/templates.d.ts +24 -0
- package/dist/utils/templates.js +118 -0
- package/package.json +48 -0
- package/templates/CLAUDE.md +287 -0
- package/templates/README.md +378 -0
- package/templates/agents/README.md +182 -0
- package/templates/agents/code-reviewer.md +166 -0
- package/templates/agents/debug-detective.md +169 -0
- package/templates/agents/ekkOS_Vercel.md +99 -0
- package/templates/agents/extension-manager.md +229 -0
- package/templates/agents/git-companion.md +185 -0
- package/templates/agents/github-test-agent.md +321 -0
- package/templates/agents/railway-manager.md +179 -0
- package/templates/claude-plugins/PHASE2_COMPLETION.md +346 -0
- package/templates/claude-plugins/PLUGIN_PROPOSALS.md +1776 -0
- package/templates/claude-plugins/README.md +587 -0
- package/templates/claude-plugins/agents/code-reviewer.json +14 -0
- package/templates/claude-plugins/agents/debug-detective.json +15 -0
- package/templates/claude-plugins/agents/git-companion.json +14 -0
- package/templates/claude-plugins/blog-manager/.claude-plugin/plugin.json +8 -0
- package/templates/claude-plugins/blog-manager/commands/blog.md +691 -0
- package/templates/claude-plugins/golden-loop-monitor/.claude-plugin/plugin.json +8 -0
- package/templates/claude-plugins/golden-loop-monitor/commands/loop-status.md +434 -0
- package/templates/claude-plugins/learning-tracker/.claude-plugin/plugin.json +8 -0
- package/templates/claude-plugins/learning-tracker/commands/my-patterns.md +282 -0
- package/templates/claude-plugins/memory-lens/.claude-plugin/plugin.json +8 -0
- package/templates/claude-plugins/memory-lens/commands/memory-search.md +181 -0
- package/templates/claude-plugins/pattern-coach/.claude-plugin/plugin.json +8 -0
- package/templates/claude-plugins/pattern-coach/commands/forge.md +365 -0
- package/templates/claude-plugins/project-schema-validator/.claude-plugin/plugin.json +8 -0
- package/templates/claude-plugins/project-schema-validator/commands/validate-schema.md +582 -0
- package/templates/claude-plugins-admin/AGENT_TEAM_PROPOSALS.md +819 -0
- package/templates/claude-plugins-admin/README.md +446 -0
- package/templates/claude-plugins-admin/autonomous-admin-agent/.claude-plugin/plugin.json +8 -0
- package/templates/claude-plugins-admin/autonomous-admin-agent/commands/agent.md +595 -0
- package/templates/claude-plugins-admin/backend-agent/.claude-plugin/plugin.json +8 -0
- package/templates/claude-plugins-admin/backend-agent/commands/backend.md +798 -0
- package/templates/claude-plugins-admin/deploy-guardian/.claude-plugin/plugin.json +8 -0
- package/templates/claude-plugins-admin/deploy-guardian/commands/deploy.md +554 -0
- package/templates/claude-plugins-admin/frontend-agent/.claude-plugin/plugin.json +8 -0
- package/templates/claude-plugins-admin/frontend-agent/commands/frontend.md +881 -0
- package/templates/claude-plugins-admin/mcp-server-manager/.claude-plugin/plugin.json +8 -0
- package/templates/claude-plugins-admin/mcp-server-manager/commands/mcp.md +85 -0
- package/templates/claude-plugins-admin/memory-system-monitor/.claude-plugin/plugin.json +8 -0
- package/templates/claude-plugins-admin/memory-system-monitor/commands/memory-health.md +569 -0
- package/templates/claude-plugins-admin/qa-agent/.claude-plugin/plugin.json +8 -0
- package/templates/claude-plugins-admin/qa-agent/commands/qa.md +863 -0
- package/templates/claude-plugins-admin/tech-lead-agent/.claude-plugin/plugin.json +8 -0
- package/templates/claude-plugins-admin/tech-lead-agent/commands/lead.md +732 -0
- package/templates/commands/continue.md +47 -0
- package/templates/cursor-hooks/after-agent-response.sh +117 -0
- package/templates/cursor-hooks/before-submit-prompt.sh +419 -0
- package/templates/cursor-hooks/hooks.json +20 -0
- package/templates/cursor-hooks/lib/contract.sh +320 -0
- package/templates/cursor-hooks/stop.sh +75 -0
- package/templates/cursor-rules/ekkos-memory.md +187 -0
- package/templates/hooks/assistant-response.sh +96 -0
- package/templates/hooks/hooks.json +28 -0
- package/templates/hooks/lib/contract.sh +320 -0
- package/templates/hooks/lib/state.sh +158 -0
- package/templates/hooks/session-start.ps1 +41 -0
- package/templates/hooks/session-start.sh +318 -0
- package/templates/hooks/stop.ps1 +16 -0
- package/templates/hooks/stop.sh +989 -0
- package/templates/hooks/user-prompt-submit.ps1 +174 -0
- package/templates/hooks/user-prompt-submit.sh +587 -0
- package/templates/hooks-node/lib/state.js +187 -0
- package/templates/hooks-node/stop.js +416 -0
- package/templates/hooks-node/user-prompt-submit.js +337 -0
- package/templates/plan-template.md +306 -0
- package/templates/rules/00-hooks-contract.mdc +89 -0
- package/templates/rules/30-ekkos-core.mdc +188 -0
- package/templates/rules/31-ekkos-messages.mdc +78 -0
- package/templates/skills/continue/SKILL.md +169 -0
- package/templates/skills/ekkOS_Deep_Recall/Skill.md +282 -0
- package/templates/skills/ekkOS_Learn/Skill.md +265 -0
- package/templates/skills/ekkOS_Memory_First/Skill.md +206 -0
- package/templates/skills/ekkOS_Plan_Assist/Skill.md +302 -0
- package/templates/skills/ekkOS_Preferences/Skill.md +247 -0
- package/templates/skills/ekkOS_Reflect/Skill.md +257 -0
- package/templates/skills/ekkOS_Safety/Skill.md +265 -0
- package/templates/skills/ekkOS_Schema/Skill.md +251 -0
- package/templates/skills/ekkOS_Summary/Skill.md +257 -0
- package/templates/skills/ekkOS_Vault/Skill.md +287 -0
- package/templates/skills/permissions/Skill.md +322 -0
- package/templates/spec-template.md +159 -0
- package/templates/windsurf-hooks/before-submit-prompt.sh +238 -0
- package/templates/windsurf-hooks/hooks.json +10 -0
- package/templates/windsurf-hooks/lib/contract.sh +320 -0
- package/templates/windsurf-rules/ekkos-memory.md +129 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
3
|
+
# ekkOS_ Hook: SessionStart - MINIMAL + AUTO-RESTORE + TIME MACHINE CONTINUE
|
|
4
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
5
|
+
# This hook does THREE things:
|
|
6
|
+
# 1. Check for pending Time Machine "Continue from here" requests
|
|
7
|
+
# 2. Initialize session tracking
|
|
8
|
+
# 3. Auto-restore from L2 if recent turns exist (FAST TRIM support)
|
|
9
|
+
#
|
|
10
|
+
# TIME MACHINE FLOW:
|
|
11
|
+
# User clicks "Continue from here" on web → API queues request →
|
|
12
|
+
# User runs `claude` → This hook detects pending request →
|
|
13
|
+
# Restores THAT session's context → Seamless time travel!
|
|
14
|
+
#
|
|
15
|
+
# FAST TRIM FLOW:
|
|
16
|
+
# User runs /clear → session-start detects fresh session →
|
|
17
|
+
# Checks L2 for recent turns → Auto-injects last 15 turns → Seamless continuity
|
|
18
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
19
|
+
|
|
20
|
+
set +e
|
|
21
|
+
|
|
22
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
23
|
+
PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
|
24
|
+
|
|
25
|
+
INPUT=$(cat)
|
|
26
|
+
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
|
|
27
|
+
TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // ""')
|
|
28
|
+
SOURCE=$(echo "$INPUT" | jq -r '.source // "unknown"') # "startup", "resume", or "clear"
|
|
29
|
+
|
|
30
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
31
|
+
# Load auth
|
|
32
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
33
|
+
EKKOS_CONFIG="$HOME/.ekkos/config.json"
|
|
34
|
+
AUTH_TOKEN=""
|
|
35
|
+
USER_ID=""
|
|
36
|
+
|
|
37
|
+
if [ -f "$EKKOS_CONFIG" ]; then
|
|
38
|
+
AUTH_TOKEN=$(jq -r '.hookApiKey // .apiKey // ""' "$EKKOS_CONFIG" 2>/dev/null || echo "")
|
|
39
|
+
USER_ID=$(jq -r '.userId // ""' "$EKKOS_CONFIG" 2>/dev/null || echo "")
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
if [ -z "$AUTH_TOKEN" ] && [ -f "$PROJECT_ROOT/.env.local" ]; then
|
|
43
|
+
AUTH_TOKEN=$(grep -E "^SUPABASE_SECRET_KEY=" "$PROJECT_ROOT/.env.local" | cut -d'=' -f2- | tr -d '"' | tr -d "'" | tr -d '\r')
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
[ -z "$AUTH_TOKEN" ] && exit 0
|
|
47
|
+
|
|
48
|
+
MEMORY_API_URL="https://mcp.ekkos.dev"
|
|
49
|
+
|
|
50
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
51
|
+
# TIME MACHINE: Check for pending "Continue from here" requests
|
|
52
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
53
|
+
RESTORE_REQUEST_ID="${EKKOS_RESTORE:-}"
|
|
54
|
+
TIME_MACHINE_SESSION=""
|
|
55
|
+
TIME_MACHINE_FROM_TURN=""
|
|
56
|
+
TIME_MACHINE_TO_TURN=""
|
|
57
|
+
|
|
58
|
+
# Check via env var first, then API
|
|
59
|
+
if [ -n "$RESTORE_REQUEST_ID" ]; then
|
|
60
|
+
echo -e "\033[0;35m⏰ Time Machine request detected: $RESTORE_REQUEST_ID\033[0m" >&2
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# Check API for pending requests (if we have user_id)
|
|
64
|
+
if [ -z "$TIME_MACHINE_SESSION" ] && [ -n "$USER_ID" ]; then
|
|
65
|
+
PENDING_RESPONSE=$(curl -s -X GET "$MEMORY_API_URL/api/v1/context/restore-request/pending?user_id=$USER_ID" \
|
|
66
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
67
|
+
--connect-timeout 2 \
|
|
68
|
+
--max-time 3 2>/dev/null || echo '{}')
|
|
69
|
+
|
|
70
|
+
IS_PENDING=$(echo "$PENDING_RESPONSE" | jq -r '.pending // false' 2>/dev/null)
|
|
71
|
+
|
|
72
|
+
if [ "$IS_PENDING" = "true" ]; then
|
|
73
|
+
TIME_MACHINE_SESSION=$(echo "$PENDING_RESPONSE" | jq -r '.request.session_id // ""')
|
|
74
|
+
TIME_MACHINE_FROM_TURN=$(echo "$PENDING_RESPONSE" | jq -r '.request.from_turn // ""')
|
|
75
|
+
TIME_MACHINE_TO_TURN=$(echo "$PENDING_RESPONSE" | jq -r '.request.to_turn // ""')
|
|
76
|
+
RESTORE_REQUEST_ID=$(echo "$PENDING_RESPONSE" | jq -r '.request.request_id // ""')
|
|
77
|
+
|
|
78
|
+
if [ -n "$TIME_MACHINE_SESSION" ]; then
|
|
79
|
+
echo "" >&2
|
|
80
|
+
echo -e "\033[0;35m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\033[0m" >&2
|
|
81
|
+
echo -e "\033[0;35m\033[1m⏰ TIME MACHINE\033[0m \033[2m| Restoring session from web request...\033[0m" >&2
|
|
82
|
+
echo -e "\033[0;35m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\033[0m" >&2
|
|
83
|
+
|
|
84
|
+
# Mark request as consumed
|
|
85
|
+
curl -s -X POST "$MEMORY_API_URL/api/v1/context/restore-request/consume" \
|
|
86
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
87
|
+
-H "Content-Type: application/json" \
|
|
88
|
+
-d "{\"request_id\": \"$RESTORE_REQUEST_ID\"}" \
|
|
89
|
+
--connect-timeout 2 \
|
|
90
|
+
--max-time 3 >/dev/null 2>&1 || true
|
|
91
|
+
fi
|
|
92
|
+
fi
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
96
|
+
# Session ID persistence - PROJECT-LOCAL for isolation
|
|
97
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
98
|
+
STATE_DIR="$PROJECT_ROOT/.claude/state"
|
|
99
|
+
mkdir -p "$STATE_DIR" 2>/dev/null || true
|
|
100
|
+
SESSION_FILE="$STATE_DIR/current-session.json"
|
|
101
|
+
|
|
102
|
+
# Project-local session storage (isolated per project)
|
|
103
|
+
PROJECT_SESSION_DIR="$STATE_DIR/sessions"
|
|
104
|
+
mkdir -p "$PROJECT_SESSION_DIR" 2>/dev/null || true
|
|
105
|
+
|
|
106
|
+
# Use Claude's RAW_SESSION_ID directly (from session_id field)
|
|
107
|
+
CURRENT_SESSION_ID="$SESSION_ID"
|
|
108
|
+
|
|
109
|
+
# Find most recent session in THIS PROJECT for auto-restore
|
|
110
|
+
MOST_RECENT_SESSION=""
|
|
111
|
+
SAVED_TURN_COUNT=0
|
|
112
|
+
|
|
113
|
+
if [ -n "$CURRENT_SESSION_ID" ] && [ "$CURRENT_SESSION_ID" != "unknown" ]; then
|
|
114
|
+
# Check if THIS session has saved turns (for /clear continuity)
|
|
115
|
+
TURN_COUNTER_FILE="$PROJECT_SESSION_DIR/${CURRENT_SESSION_ID}.turn"
|
|
116
|
+
if [ -f "$TURN_COUNTER_FILE" ]; then
|
|
117
|
+
SAVED_TURN_COUNT=$(cat "$TURN_COUNTER_FILE" 2>/dev/null || echo "0")
|
|
118
|
+
MOST_RECENT_SESSION="$CURRENT_SESSION_ID"
|
|
119
|
+
else
|
|
120
|
+
# Fresh start: find most recent session in project
|
|
121
|
+
MOST_RECENT_FILE=$(ls -t "$PROJECT_SESSION_DIR"/*.turn 2>/dev/null | head -1)
|
|
122
|
+
if [ -n "$MOST_RECENT_FILE" ]; then
|
|
123
|
+
MOST_RECENT_SESSION=$(basename "$MOST_RECENT_FILE" .turn)
|
|
124
|
+
SAVED_TURN_COUNT=$(cat "$MOST_RECENT_FILE" 2>/dev/null || echo "0")
|
|
125
|
+
fi
|
|
126
|
+
fi
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
# Save current session info
|
|
130
|
+
if [ -n "$CURRENT_SESSION_ID" ]; then
|
|
131
|
+
cat > "$SESSION_FILE" << EOF
|
|
132
|
+
{
|
|
133
|
+
"session_id": "$CURRENT_SESSION_ID",
|
|
134
|
+
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
135
|
+
"project_root": "$PROJECT_ROOT"
|
|
136
|
+
}
|
|
137
|
+
EOF
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
141
|
+
# 🔄 GOLDEN LOOP: Initialize session tracking file
|
|
142
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
143
|
+
GOLDEN_LOOP_FILE="$PROJECT_ROOT/.ekkos/golden-loop-current.json"
|
|
144
|
+
mkdir -p "$PROJECT_ROOT/.ekkos" 2>/dev/null || true
|
|
145
|
+
|
|
146
|
+
# Initialize with session start state
|
|
147
|
+
jq -n \
|
|
148
|
+
--arg phase "idle" \
|
|
149
|
+
--argjson turn 0 \
|
|
150
|
+
--arg session "${CURRENT_SESSION_ID}" \
|
|
151
|
+
--arg timestamp "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
152
|
+
'{
|
|
153
|
+
phase: $phase,
|
|
154
|
+
turn: $turn,
|
|
155
|
+
session: $session,
|
|
156
|
+
timestamp: $timestamp,
|
|
157
|
+
stats: {
|
|
158
|
+
retrieved: 0,
|
|
159
|
+
applied: 0,
|
|
160
|
+
forged: 0
|
|
161
|
+
}
|
|
162
|
+
}' > "$GOLDEN_LOOP_FILE" 2>/dev/null || true
|
|
163
|
+
|
|
164
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
165
|
+
# COLORS
|
|
166
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
167
|
+
CYAN='\033[0;36m'
|
|
168
|
+
GREEN='\033[0;32m'
|
|
169
|
+
YELLOW='\033[1;33m'
|
|
170
|
+
MAGENTA='\033[0;35m'
|
|
171
|
+
DIM='\033[2m'
|
|
172
|
+
BOLD='\033[1m'
|
|
173
|
+
RESET='\033[0m'
|
|
174
|
+
|
|
175
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
176
|
+
# AUTO-RESTORE REMOVED: Manual /continue only (saves 79% token burn!)
|
|
177
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
178
|
+
# WHY REMOVED:
|
|
179
|
+
# - Auto-restore burned 5,000 tokens per turn on session start
|
|
180
|
+
# - Manual /continue: one-time cost + clean slate (79% token savings!)
|
|
181
|
+
# - Manual /continue is 10x more powerful (Bash + multi-source + narrative)
|
|
182
|
+
#
|
|
183
|
+
# KEPT: Time Machine feature (explicit user request)
|
|
184
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
185
|
+
|
|
186
|
+
# Handle Time Machine requests (explicit user action)
|
|
187
|
+
if [ -n "$TIME_MACHINE_SESSION" ]; then
|
|
188
|
+
echo "" >&2
|
|
189
|
+
echo -e "${MAGENTA}${BOLD}⏰ TIME MACHINE${RESET} ${DIM}| Restoring past session: ${TIME_MACHINE_SESSION:0:12}...${RESET}" >&2
|
|
190
|
+
|
|
191
|
+
# Build recall request with turn range
|
|
192
|
+
RECALL_BODY="{\"session_id\": \"${TIME_MACHINE_SESSION}\", \"last_n\": 15, \"format\": \"summary\"}"
|
|
193
|
+
|
|
194
|
+
if [ -n "$TIME_MACHINE_FROM_TURN" ] && [ -n "$TIME_MACHINE_TO_TURN" ]; then
|
|
195
|
+
RECALL_BODY="{\"session_id\": \"${TIME_MACHINE_SESSION}\", \"from_turn\": ${TIME_MACHINE_FROM_TURN}, \"to_turn\": ${TIME_MACHINE_TO_TURN}, \"format\": \"summary\"}"
|
|
196
|
+
elif [ -n "$TIME_MACHINE_FROM_TURN" ]; then
|
|
197
|
+
RECALL_BODY="{\"session_id\": \"${TIME_MACHINE_SESSION}\", \"from_turn\": ${TIME_MACHINE_FROM_TURN}, \"format\": \"summary\"}"
|
|
198
|
+
fi
|
|
199
|
+
|
|
200
|
+
# Fetch turns from L2
|
|
201
|
+
RESTORE_RESPONSE=$(curl -s -X POST "$MEMORY_API_URL/api/v1/turns/recall" \
|
|
202
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
203
|
+
-H "Content-Type: application/json" \
|
|
204
|
+
-d "$RECALL_BODY" \
|
|
205
|
+
--connect-timeout 3 \
|
|
206
|
+
--max-time 5 2>/dev/null || echo '{"error":"timeout"}')
|
|
207
|
+
|
|
208
|
+
# Check if we got turns back
|
|
209
|
+
RESTORED_COUNT=$(echo "$RESTORE_RESPONSE" | jq '.turns // [] | length' 2>/dev/null || echo "0")
|
|
210
|
+
|
|
211
|
+
if [ "$RESTORED_COUNT" -gt 0 ]; then
|
|
212
|
+
echo -e "${MAGENTA} ✓${RESET} Restored ${RESTORED_COUNT} turns from past session" >&2
|
|
213
|
+
echo "" >&2
|
|
214
|
+
echo -e "${MAGENTA}${BOLD}## Time Machine Context${RESET}" >&2
|
|
215
|
+
echo "" >&2
|
|
216
|
+
|
|
217
|
+
# Output the turns as context (stderr for user, stdout for Claude)
|
|
218
|
+
TURNS_OUTPUT=$(echo "$RESTORE_RESPONSE" | jq -r '.turns[]? | "**Turn \(.turn_number // "?")**: \(.user_query[:100] // "...")...\n> \(.assistant_response[:200] // "...")...\n"' 2>/dev/null || true)
|
|
219
|
+
echo "$TURNS_OUTPUT" >&2
|
|
220
|
+
echo "$TURNS_OUTPUT" # Also to stdout for Claude's context
|
|
221
|
+
|
|
222
|
+
echo "" >&2
|
|
223
|
+
echo -e "${DIM}You've traveled to a past session. Continue from here!${RESET}" >&2
|
|
224
|
+
echo "" >&2
|
|
225
|
+
fi
|
|
226
|
+
fi
|
|
227
|
+
|
|
228
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
229
|
+
# DIRECTIVE RETRIEVAL: Fetch user's MUST/NEVER/PREFER/AVOID rules
|
|
230
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
231
|
+
DIRECTIVES_INJECTED=false
|
|
232
|
+
DIRECTIVE_COUNT=0
|
|
233
|
+
|
|
234
|
+
# Only fetch if we have auth
|
|
235
|
+
if [ -n "$AUTH_TOKEN" ]; then
|
|
236
|
+
# Fetch directives (top 20 by priority to avoid token bloat)
|
|
237
|
+
DIRECTIVES_RESPONSE=$(curl -s -X GET "$MEMORY_API_URL/api/v1/memory/directives?limit=20" \
|
|
238
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
239
|
+
--connect-timeout 2 \
|
|
240
|
+
--max-time 3 2>/dev/null || echo '{}')
|
|
241
|
+
|
|
242
|
+
# Parse response
|
|
243
|
+
DIRECTIVE_COUNT=$(echo "$DIRECTIVES_RESPONSE" | jq '.count // 0' 2>/dev/null || echo "0")
|
|
244
|
+
|
|
245
|
+
if [ "$DIRECTIVE_COUNT" -gt 0 ]; then
|
|
246
|
+
DIRECTIVES_INJECTED=true
|
|
247
|
+
|
|
248
|
+
# Extract MUST/NEVER/PREFER/AVOID arrays
|
|
249
|
+
MUST_RULES=$(echo "$DIRECTIVES_RESPONSE" | jq -r '.MUST[]?.rule // empty' 2>/dev/null | head -5)
|
|
250
|
+
NEVER_RULES=$(echo "$DIRECTIVES_RESPONSE" | jq -r '.NEVER[]?.rule // empty' 2>/dev/null | head -5)
|
|
251
|
+
PREFER_RULES=$(echo "$DIRECTIVES_RESPONSE" | jq -r '.PREFER[]?.rule // empty' 2>/dev/null | head -5)
|
|
252
|
+
AVOID_RULES=$(echo "$DIRECTIVES_RESPONSE" | jq -r '.AVOID[]?.rule // empty' 2>/dev/null | head -5)
|
|
253
|
+
|
|
254
|
+
# Build compact directive block for injection
|
|
255
|
+
echo "<system-reminder>"
|
|
256
|
+
echo "USER DIRECTIVES (FOLLOW THESE):"
|
|
257
|
+
echo ""
|
|
258
|
+
|
|
259
|
+
if [ -n "$MUST_RULES" ]; then
|
|
260
|
+
echo "MUST:"
|
|
261
|
+
echo "$MUST_RULES" | while read -r rule; do
|
|
262
|
+
[ -n "$rule" ] && echo " • $rule"
|
|
263
|
+
done
|
|
264
|
+
fi
|
|
265
|
+
|
|
266
|
+
if [ -n "$NEVER_RULES" ]; then
|
|
267
|
+
echo "NEVER:"
|
|
268
|
+
echo "$NEVER_RULES" | while read -r rule; do
|
|
269
|
+
[ -n "$rule" ] && echo " • $rule"
|
|
270
|
+
done
|
|
271
|
+
fi
|
|
272
|
+
|
|
273
|
+
if [ -n "$PREFER_RULES" ]; then
|
|
274
|
+
echo "PREFER:"
|
|
275
|
+
echo "$PREFER_RULES" | while read -r rule; do
|
|
276
|
+
[ -n "$rule" ] && echo " • $rule"
|
|
277
|
+
done
|
|
278
|
+
fi
|
|
279
|
+
|
|
280
|
+
if [ -n "$AVOID_RULES" ]; then
|
|
281
|
+
echo "AVOID:"
|
|
282
|
+
echo "$AVOID_RULES" | while read -r rule; do
|
|
283
|
+
[ -n "$rule" ] && echo " • $rule"
|
|
284
|
+
done
|
|
285
|
+
fi
|
|
286
|
+
|
|
287
|
+
echo "</system-reminder>"
|
|
288
|
+
|
|
289
|
+
echo -e "${GREEN}📋 ${DIRECTIVE_COUNT} directives loaded${RESET}" >&2
|
|
290
|
+
fi
|
|
291
|
+
fi
|
|
292
|
+
|
|
293
|
+
# Simple status display (no auto-restore)
|
|
294
|
+
if [ "$SAVED_TURN_COUNT" -gt 0 ]; then
|
|
295
|
+
# New session or few turns - just show status
|
|
296
|
+
echo "" >&2
|
|
297
|
+
if [ "$SAVED_TURN_COUNT" -gt 0 ]; then
|
|
298
|
+
echo -e "${CYAN}${BOLD}🧠 ekkOS${RESET} ${DIM}|${RESET} Session: ${CURRENT_SESSION_ID:-$SESSION_ID} ${DIM}|${RESET} ${GREEN}${SAVED_TURN_COUNT} turns${RESET}" >&2
|
|
299
|
+
else
|
|
300
|
+
echo -e "${CYAN}${BOLD}🧠 ekkOS${RESET} ${DIM}|${RESET} Session: ${CURRENT_SESSION_ID:-$SESSION_ID} ${DIM}| New session${RESET}" >&2
|
|
301
|
+
fi
|
|
302
|
+
fi
|
|
303
|
+
|
|
304
|
+
# Final confirmation that's always visible
|
|
305
|
+
if [ -n "$TIME_MACHINE_SESSION" ]; then
|
|
306
|
+
echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" >&2
|
|
307
|
+
echo -e "${MAGENTA}⏰${RESET} Time Machine active · Restored from session ${TIME_MACHINE_SESSION:0:12}..." >&2
|
|
308
|
+
echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" >&2
|
|
309
|
+
elif [ "$SAVED_TURN_COUNT" -gt 0 ]; then
|
|
310
|
+
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" >&2
|
|
311
|
+
echo -e "${GREEN}✓${RESET} Session continued · ${SAVED_TURN_COUNT} turns preserved · Ready to resume" >&2
|
|
312
|
+
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" >&2
|
|
313
|
+
else
|
|
314
|
+
echo -e "${CYAN}✓${RESET} New session started" >&2
|
|
315
|
+
fi
|
|
316
|
+
echo "" >&2
|
|
317
|
+
|
|
318
|
+
exit 0
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
+
# ekkOS_ Hook: Stop - Session cleanup (Windows)
|
|
3
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
4
|
+
|
|
5
|
+
$ErrorActionPreference = "SilentlyContinue"
|
|
6
|
+
|
|
7
|
+
# Read input
|
|
8
|
+
$inputJson = [Console]::In.ReadToEnd()
|
|
9
|
+
|
|
10
|
+
# Clean up state
|
|
11
|
+
$stateFile = Join-Path $env:USERPROFILE ".claude\state\hook-state.json"
|
|
12
|
+
if (Test-Path $stateFile) {
|
|
13
|
+
Remove-Item $stateFile -Force
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
Write-Output "ekkOS session ended"
|