@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.
Files changed (135) hide show
  1. package/dist/cache/LocalSessionStore.d.ts +129 -0
  2. package/dist/cache/LocalSessionStore.js +688 -0
  3. package/dist/cache/capture.d.ts +26 -0
  4. package/dist/cache/capture.js +461 -0
  5. package/dist/cache/index.d.ts +7 -0
  6. package/dist/cache/index.js +23 -0
  7. package/dist/cache/types.d.ts +147 -0
  8. package/dist/cache/types.js +40 -0
  9. package/dist/commands/init.d.ts +9 -0
  10. package/dist/commands/init.js +478 -0
  11. package/dist/commands/run.d.ts +12 -0
  12. package/dist/commands/run.js +829 -0
  13. package/dist/commands/setup.d.ts +6 -0
  14. package/dist/commands/setup.js +658 -0
  15. package/dist/commands/status.d.ts +1 -0
  16. package/dist/commands/status.js +109 -0
  17. package/dist/commands/test.d.ts +1 -0
  18. package/dist/commands/test.js +157 -0
  19. package/dist/deploy/agents.d.ts +15 -0
  20. package/dist/deploy/agents.js +72 -0
  21. package/dist/deploy/hooks.d.ts +16 -0
  22. package/dist/deploy/hooks.js +121 -0
  23. package/dist/deploy/index.d.ts +7 -0
  24. package/dist/deploy/index.js +24 -0
  25. package/dist/deploy/instructions.d.ts +12 -0
  26. package/dist/deploy/instructions.js +36 -0
  27. package/dist/deploy/mcp.d.ts +19 -0
  28. package/dist/deploy/mcp.js +109 -0
  29. package/dist/deploy/plugins.d.ts +19 -0
  30. package/dist/deploy/plugins.js +62 -0
  31. package/dist/deploy/settings.d.ts +8 -0
  32. package/dist/deploy/settings.js +84 -0
  33. package/dist/deploy/skills.d.ts +19 -0
  34. package/dist/deploy/skills.js +60 -0
  35. package/dist/index.d.ts +2 -0
  36. package/dist/index.js +71 -0
  37. package/dist/restore/RestoreOrchestrator.d.ts +48 -0
  38. package/dist/restore/RestoreOrchestrator.js +481 -0
  39. package/dist/restore/index.d.ts +4 -0
  40. package/dist/restore/index.js +20 -0
  41. package/dist/utils/platform.d.ts +29 -0
  42. package/dist/utils/platform.js +65 -0
  43. package/dist/utils/session-words.json +119 -0
  44. package/dist/utils/state.d.ts +57 -0
  45. package/dist/utils/state.js +186 -0
  46. package/dist/utils/templates.d.ts +24 -0
  47. package/dist/utils/templates.js +118 -0
  48. package/package.json +48 -0
  49. package/templates/CLAUDE.md +287 -0
  50. package/templates/README.md +378 -0
  51. package/templates/agents/README.md +182 -0
  52. package/templates/agents/code-reviewer.md +166 -0
  53. package/templates/agents/debug-detective.md +169 -0
  54. package/templates/agents/ekkOS_Vercel.md +99 -0
  55. package/templates/agents/extension-manager.md +229 -0
  56. package/templates/agents/git-companion.md +185 -0
  57. package/templates/agents/github-test-agent.md +321 -0
  58. package/templates/agents/railway-manager.md +179 -0
  59. package/templates/claude-plugins/PHASE2_COMPLETION.md +346 -0
  60. package/templates/claude-plugins/PLUGIN_PROPOSALS.md +1776 -0
  61. package/templates/claude-plugins/README.md +587 -0
  62. package/templates/claude-plugins/agents/code-reviewer.json +14 -0
  63. package/templates/claude-plugins/agents/debug-detective.json +15 -0
  64. package/templates/claude-plugins/agents/git-companion.json +14 -0
  65. package/templates/claude-plugins/blog-manager/.claude-plugin/plugin.json +8 -0
  66. package/templates/claude-plugins/blog-manager/commands/blog.md +691 -0
  67. package/templates/claude-plugins/golden-loop-monitor/.claude-plugin/plugin.json +8 -0
  68. package/templates/claude-plugins/golden-loop-monitor/commands/loop-status.md +434 -0
  69. package/templates/claude-plugins/learning-tracker/.claude-plugin/plugin.json +8 -0
  70. package/templates/claude-plugins/learning-tracker/commands/my-patterns.md +282 -0
  71. package/templates/claude-plugins/memory-lens/.claude-plugin/plugin.json +8 -0
  72. package/templates/claude-plugins/memory-lens/commands/memory-search.md +181 -0
  73. package/templates/claude-plugins/pattern-coach/.claude-plugin/plugin.json +8 -0
  74. package/templates/claude-plugins/pattern-coach/commands/forge.md +365 -0
  75. package/templates/claude-plugins/project-schema-validator/.claude-plugin/plugin.json +8 -0
  76. package/templates/claude-plugins/project-schema-validator/commands/validate-schema.md +582 -0
  77. package/templates/claude-plugins-admin/AGENT_TEAM_PROPOSALS.md +819 -0
  78. package/templates/claude-plugins-admin/README.md +446 -0
  79. package/templates/claude-plugins-admin/autonomous-admin-agent/.claude-plugin/plugin.json +8 -0
  80. package/templates/claude-plugins-admin/autonomous-admin-agent/commands/agent.md +595 -0
  81. package/templates/claude-plugins-admin/backend-agent/.claude-plugin/plugin.json +8 -0
  82. package/templates/claude-plugins-admin/backend-agent/commands/backend.md +798 -0
  83. package/templates/claude-plugins-admin/deploy-guardian/.claude-plugin/plugin.json +8 -0
  84. package/templates/claude-plugins-admin/deploy-guardian/commands/deploy.md +554 -0
  85. package/templates/claude-plugins-admin/frontend-agent/.claude-plugin/plugin.json +8 -0
  86. package/templates/claude-plugins-admin/frontend-agent/commands/frontend.md +881 -0
  87. package/templates/claude-plugins-admin/mcp-server-manager/.claude-plugin/plugin.json +8 -0
  88. package/templates/claude-plugins-admin/mcp-server-manager/commands/mcp.md +85 -0
  89. package/templates/claude-plugins-admin/memory-system-monitor/.claude-plugin/plugin.json +8 -0
  90. package/templates/claude-plugins-admin/memory-system-monitor/commands/memory-health.md +569 -0
  91. package/templates/claude-plugins-admin/qa-agent/.claude-plugin/plugin.json +8 -0
  92. package/templates/claude-plugins-admin/qa-agent/commands/qa.md +863 -0
  93. package/templates/claude-plugins-admin/tech-lead-agent/.claude-plugin/plugin.json +8 -0
  94. package/templates/claude-plugins-admin/tech-lead-agent/commands/lead.md +732 -0
  95. package/templates/commands/continue.md +47 -0
  96. package/templates/cursor-hooks/after-agent-response.sh +117 -0
  97. package/templates/cursor-hooks/before-submit-prompt.sh +419 -0
  98. package/templates/cursor-hooks/hooks.json +20 -0
  99. package/templates/cursor-hooks/lib/contract.sh +320 -0
  100. package/templates/cursor-hooks/stop.sh +75 -0
  101. package/templates/cursor-rules/ekkos-memory.md +187 -0
  102. package/templates/hooks/assistant-response.sh +96 -0
  103. package/templates/hooks/hooks.json +28 -0
  104. package/templates/hooks/lib/contract.sh +320 -0
  105. package/templates/hooks/lib/state.sh +158 -0
  106. package/templates/hooks/session-start.ps1 +41 -0
  107. package/templates/hooks/session-start.sh +318 -0
  108. package/templates/hooks/stop.ps1 +16 -0
  109. package/templates/hooks/stop.sh +989 -0
  110. package/templates/hooks/user-prompt-submit.ps1 +174 -0
  111. package/templates/hooks/user-prompt-submit.sh +587 -0
  112. package/templates/hooks-node/lib/state.js +187 -0
  113. package/templates/hooks-node/stop.js +416 -0
  114. package/templates/hooks-node/user-prompt-submit.js +337 -0
  115. package/templates/plan-template.md +306 -0
  116. package/templates/rules/00-hooks-contract.mdc +89 -0
  117. package/templates/rules/30-ekkos-core.mdc +188 -0
  118. package/templates/rules/31-ekkos-messages.mdc +78 -0
  119. package/templates/skills/continue/SKILL.md +169 -0
  120. package/templates/skills/ekkOS_Deep_Recall/Skill.md +282 -0
  121. package/templates/skills/ekkOS_Learn/Skill.md +265 -0
  122. package/templates/skills/ekkOS_Memory_First/Skill.md +206 -0
  123. package/templates/skills/ekkOS_Plan_Assist/Skill.md +302 -0
  124. package/templates/skills/ekkOS_Preferences/Skill.md +247 -0
  125. package/templates/skills/ekkOS_Reflect/Skill.md +257 -0
  126. package/templates/skills/ekkOS_Safety/Skill.md +265 -0
  127. package/templates/skills/ekkOS_Schema/Skill.md +251 -0
  128. package/templates/skills/ekkOS_Summary/Skill.md +257 -0
  129. package/templates/skills/ekkOS_Vault/Skill.md +287 -0
  130. package/templates/skills/permissions/Skill.md +322 -0
  131. package/templates/spec-template.md +159 -0
  132. package/templates/windsurf-hooks/before-submit-prompt.sh +238 -0
  133. package/templates/windsurf-hooks/hooks.json +10 -0
  134. package/templates/windsurf-hooks/lib/contract.sh +320 -0
  135. 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"