@ekkos/cli 1.2.17 → 1.3.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/capture.js +0 -0
- package/dist/commands/dashboard.js +57 -49
- package/dist/commands/hooks.d.ts +25 -36
- package/dist/commands/hooks.js +43 -615
- package/dist/commands/init.js +7 -23
- package/dist/commands/run.js +97 -11
- package/dist/commands/setup.js +10 -352
- package/dist/deploy/hooks.d.ts +8 -5
- package/dist/deploy/hooks.js +12 -105
- package/dist/deploy/settings.d.ts +8 -2
- package/dist/deploy/settings.js +22 -51
- package/dist/index.js +17 -39
- package/dist/utils/state.js +7 -2
- package/package.json +1 -1
- package/templates/CLAUDE.md +82 -292
- package/templates/cursor-rules/ekkos-memory.md +48 -108
- package/templates/windsurf-rules/ekkos-memory.md +62 -64
- package/templates/cursor-hooks/after-agent-response.sh +0 -117
- package/templates/cursor-hooks/before-submit-prompt.sh +0 -419
- package/templates/cursor-hooks/hooks.json +0 -20
- package/templates/cursor-hooks/lib/contract.sh +0 -320
- package/templates/cursor-hooks/stop.sh +0 -75
- package/templates/hooks/assistant-response.ps1 +0 -256
- package/templates/hooks/assistant-response.sh +0 -160
- package/templates/hooks/hooks.json +0 -40
- package/templates/hooks/lib/contract.sh +0 -332
- package/templates/hooks/lib/count-tokens.cjs +0 -86
- package/templates/hooks/lib/ekkos-reminders.sh +0 -98
- package/templates/hooks/lib/state.sh +0 -210
- package/templates/hooks/session-start.ps1 +0 -146
- package/templates/hooks/session-start.sh +0 -353
- package/templates/hooks/stop.ps1 +0 -349
- package/templates/hooks/stop.sh +0 -382
- package/templates/hooks/user-prompt-submit.ps1 +0 -419
- package/templates/hooks/user-prompt-submit.sh +0 -516
- package/templates/project-stubs/session-start.ps1 +0 -63
- package/templates/project-stubs/session-start.sh +0 -55
- package/templates/project-stubs/stop.ps1 +0 -63
- package/templates/project-stubs/stop.sh +0 -55
- package/templates/project-stubs/user-prompt-submit.ps1 +0 -63
- package/templates/project-stubs/user-prompt-submit.sh +0 -55
- package/templates/windsurf-hooks/README.md +0 -212
- package/templates/windsurf-hooks/hooks.json +0 -17
- package/templates/windsurf-hooks/install.sh +0 -148
- package/templates/windsurf-hooks/lib/contract.sh +0 -322
- package/templates/windsurf-hooks/post-cascade-response.sh +0 -251
- package/templates/windsurf-hooks/pre-user-prompt.sh +0 -435
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
3
|
-
# ekkOS Tool Usage Reminders - Inject proactive tool usage hints
|
|
4
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
5
|
-
|
|
6
|
-
# Detect if user query suggests using specific ekkOS tools
|
|
7
|
-
# Returns markdown reminders to inject into Claude's context
|
|
8
|
-
|
|
9
|
-
get_ekkos_reminders() {
|
|
10
|
-
local query="$1"
|
|
11
|
-
local prev_response="$2"
|
|
12
|
-
local reminders=""
|
|
13
|
-
|
|
14
|
-
# Convert to lowercase for matching
|
|
15
|
-
query_lower=$(echo "$query" | tr '[:upper:]' '[:lower:]')
|
|
16
|
-
response_lower=$(echo "$prev_response" | tr '[:upper:]' '[:lower:]')
|
|
17
|
-
|
|
18
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
19
|
-
# ekkOS_Search - Before answering technical questions
|
|
20
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
21
|
-
if echo "$query_lower" | grep -qE "(how do|how to|what is|why|explain|security|authentication|database|rls|deployment|error|bug|fix)"; then
|
|
22
|
-
reminders+="🧠 **ekkOS_Search Required**: Search memory before answering technical questions\n"
|
|
23
|
-
fi
|
|
24
|
-
|
|
25
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
26
|
-
# ekkOS_Forge - When fixing bugs or learning
|
|
27
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
28
|
-
if echo "$response_lower" | grep -qE "(fixed|solved|resolved|bug|issue|error|migration|implemented|created|updated)"; then
|
|
29
|
-
reminders+="🔨 **ekkOS_Forge Recommended**: Forge pattern after fixing bugs or implementing solutions\n"
|
|
30
|
-
fi
|
|
31
|
-
|
|
32
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
33
|
-
# ekkOS_Directive - User preferences
|
|
34
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
35
|
-
if echo "$query_lower" | grep -qE "(always|never|dont|don't|prefer|avoid|should not|shouldn't)"; then
|
|
36
|
-
directive_type="PREFER"
|
|
37
|
-
if echo "$query_lower" | grep -qE "(always|must)"; then
|
|
38
|
-
directive_type="MUST"
|
|
39
|
-
elif echo "$query_lower" | grep -qE "(never|dont|don't|avoid|should not)"; then
|
|
40
|
-
directive_type="NEVER"
|
|
41
|
-
fi
|
|
42
|
-
reminders+="📋 **ekkOS_Directive Required**: User stated a preference - save as ${directive_type} directive\n"
|
|
43
|
-
fi
|
|
44
|
-
|
|
45
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
46
|
-
# ekkOS_Conflict - Destructive operations
|
|
47
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
48
|
-
if echo "$query_lower" | grep -qE "(delete|remove|drop|truncate|destroy|wipe)"; then
|
|
49
|
-
reminders+="⚠️ **ekkOS_Conflict Required**: Check for conflicts before destructive operations\n"
|
|
50
|
-
fi
|
|
51
|
-
|
|
52
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
53
|
-
# ekkOS_Plan - Complex multi-step tasks
|
|
54
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
55
|
-
if echo "$query_lower" | grep -qE "(implement|build|create.*feature|add.*functionality|refactor|migrate)"; then
|
|
56
|
-
reminders+="📝 **ekkOS_Plan Recommended**: Create structured plan for multi-step implementation\n"
|
|
57
|
-
fi
|
|
58
|
-
|
|
59
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
60
|
-
# ekkOS_StoreSecret - Credentials shared
|
|
61
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
62
|
-
if echo "$query_lower" | grep -qE "(api.?key|token|password|secret|credential|github.*key|openai.*key)"; then
|
|
63
|
-
reminders+="🔐 **ekkOS_StoreSecret Available**: Use to securely store credentials (AES-256-GCM)\n"
|
|
64
|
-
fi
|
|
65
|
-
|
|
66
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
67
|
-
# ekkOS_Recall - Past conversations
|
|
68
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
69
|
-
if echo "$query_lower" | grep -qE "(yesterday|last week|previously|we discussed|earlier|before)"; then
|
|
70
|
-
reminders+="🕐 **ekkOS_Recall Available**: Retrieve past conversations by time\n"
|
|
71
|
-
fi
|
|
72
|
-
|
|
73
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
74
|
-
# ekkOS_Codebase - Project-specific search
|
|
75
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
76
|
-
if echo "$query_lower" | grep -qE "(in this project|in our codebase|where is.*defined|find.*file)"; then
|
|
77
|
-
reminders+="📂 **ekkOS_Codebase Available**: Search project-specific memory\n"
|
|
78
|
-
fi
|
|
79
|
-
|
|
80
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
81
|
-
# ekkOS_Export - Backup request
|
|
82
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
83
|
-
if echo "$query_lower" | grep -qE "(export|backup|download|save.*memory|portable)"; then
|
|
84
|
-
reminders+="💾 **ekkOS_Export Available**: Export all patterns/directives as portable JSON\n"
|
|
85
|
-
fi
|
|
86
|
-
|
|
87
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
88
|
-
# ekkOS_Summary - Show activity
|
|
89
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
90
|
-
if echo "$query_lower" | grep -qE "(what did.*do|ekkos.*activity|memory.*stats|show.*patterns)"; then
|
|
91
|
-
reminders+="📊 **ekkOS_Summary Available**: Show recent ekkOS activity\n"
|
|
92
|
-
fi
|
|
93
|
-
|
|
94
|
-
echo "$reminders"
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
# Export function
|
|
98
|
-
export -f get_ekkos_reminders
|
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
3
|
-
# ekkOS™ Hook State Management Library (Portable)
|
|
4
|
-
# Shared state functions for coordinating between hooks
|
|
5
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
6
|
-
|
|
7
|
-
# Get project root (where .claude directory lives)
|
|
8
|
-
get_project_root() {
|
|
9
|
-
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
10
|
-
echo "$(dirname "$(dirname "$script_dir")")"
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
PROJECT_ROOT=$(get_project_root)
|
|
14
|
-
STATE_DIR="$PROJECT_ROOT/.claude/state"
|
|
15
|
-
|
|
16
|
-
# Ensure state directory exists
|
|
17
|
-
mkdir -p "$STATE_DIR"
|
|
18
|
-
|
|
19
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
20
|
-
# State File Management
|
|
21
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
22
|
-
|
|
23
|
-
# Save patterns for session (with retrieval_token for verified tracking)
|
|
24
|
-
save_patterns() {
|
|
25
|
-
local session_id="$1"
|
|
26
|
-
local patterns="$2"
|
|
27
|
-
local model_used="$3"
|
|
28
|
-
local retrieval_token="${4:-}" # Optional retrieval_token for verified applications
|
|
29
|
-
|
|
30
|
-
local state_file="$STATE_DIR/patterns-${session_id}.json"
|
|
31
|
-
|
|
32
|
-
jq -n \
|
|
33
|
-
--argjson patterns "$patterns" \
|
|
34
|
-
--arg model "$model_used" \
|
|
35
|
-
--arg token "$retrieval_token" \
|
|
36
|
-
--arg timestamp "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
37
|
-
'{
|
|
38
|
-
patterns: $patterns,
|
|
39
|
-
model_used: $model,
|
|
40
|
-
retrieval_token: $token,
|
|
41
|
-
saved_at: $timestamp
|
|
42
|
-
}' > "$state_file"
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
# Get retrieval token from saved patterns
|
|
46
|
-
get_retrieval_token() {
|
|
47
|
-
local session_id="$1"
|
|
48
|
-
local state_file="$STATE_DIR/patterns-${session_id}.json"
|
|
49
|
-
|
|
50
|
-
if [ -f "$state_file" ]; then
|
|
51
|
-
jq -r '.retrieval_token // ""' "$state_file" 2>/dev/null
|
|
52
|
-
else
|
|
53
|
-
echo ""
|
|
54
|
-
fi
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
# Load patterns for session
|
|
58
|
-
load_patterns() {
|
|
59
|
-
local session_id="$1"
|
|
60
|
-
local state_file="$STATE_DIR/patterns-${session_id}.json"
|
|
61
|
-
|
|
62
|
-
if [ -f "$state_file" ]; then
|
|
63
|
-
cat "$state_file"
|
|
64
|
-
else
|
|
65
|
-
echo '{}'
|
|
66
|
-
fi
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
# Clear patterns for session (after capture)
|
|
70
|
-
clear_patterns() {
|
|
71
|
-
local session_id="$1"
|
|
72
|
-
rm -f "$STATE_DIR/patterns-${session_id}.json"
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
76
|
-
# Conversation Context (for Golden Loop MEASURE phase)
|
|
77
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
78
|
-
|
|
79
|
-
# Save current conversation context for pattern tracking
|
|
80
|
-
# Called by user-prompt-submit.sh when new query is submitted
|
|
81
|
-
save_conversation_context() {
|
|
82
|
-
local session_id="$1"
|
|
83
|
-
local user_query="$2"
|
|
84
|
-
local prev_response="$3"
|
|
85
|
-
|
|
86
|
-
local context_file="$STATE_DIR/conversation-${session_id}.json"
|
|
87
|
-
|
|
88
|
-
jq -n \
|
|
89
|
-
--arg query "$user_query" \
|
|
90
|
-
--arg response "$prev_response" \
|
|
91
|
-
--arg timestamp "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
92
|
-
'{
|
|
93
|
-
query: $query,
|
|
94
|
-
response: $response,
|
|
95
|
-
saved_at: $timestamp
|
|
96
|
-
}' > "$context_file" 2>/dev/null || true
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
# Load current conversation context
|
|
100
|
-
# Called by post-tool-use.sh when tracking pattern applications
|
|
101
|
-
load_conversation_context() {
|
|
102
|
-
local session_id="$1"
|
|
103
|
-
local context_file="$STATE_DIR/conversation-${session_id}.json"
|
|
104
|
-
|
|
105
|
-
if [ -f "$context_file" ]; then
|
|
106
|
-
cat "$context_file"
|
|
107
|
-
else
|
|
108
|
-
echo '{"query":"","response":""}'
|
|
109
|
-
fi
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
113
|
-
# Capture Deduplication
|
|
114
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
115
|
-
|
|
116
|
-
# Generate hash for conversation turn
|
|
117
|
-
generate_turn_hash() {
|
|
118
|
-
local user_query="$1"
|
|
119
|
-
local assistant_response="$2"
|
|
120
|
-
|
|
121
|
-
echo "${user_query}${assistant_response}" | md5sum | cut -d' ' -f1 2>/dev/null || \
|
|
122
|
-
echo "${user_query}${assistant_response}" | md5 2>/dev/null
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
# Check if turn was already captured
|
|
126
|
-
was_turn_captured() {
|
|
127
|
-
local session_id="$1"
|
|
128
|
-
local turn_hash="$2"
|
|
129
|
-
|
|
130
|
-
local capture_log="$STATE_DIR/captures-${session_id}.log"
|
|
131
|
-
|
|
132
|
-
if [ -f "$capture_log" ]; then
|
|
133
|
-
grep -q "^${turn_hash}$" "$capture_log"
|
|
134
|
-
return $?
|
|
135
|
-
fi
|
|
136
|
-
|
|
137
|
-
return 1 # Not captured
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
# Mark turn as captured
|
|
141
|
-
mark_turn_captured() {
|
|
142
|
-
local session_id="$1"
|
|
143
|
-
local turn_hash="$2"
|
|
144
|
-
|
|
145
|
-
local capture_log="$STATE_DIR/captures-${session_id}.log"
|
|
146
|
-
|
|
147
|
-
echo "$turn_hash" >> "$capture_log"
|
|
148
|
-
|
|
149
|
-
# Keep only last 100 hashes
|
|
150
|
-
if [ $(wc -l < "$capture_log" 2>/dev/null || echo 0) -gt 100 ]; then
|
|
151
|
-
tail -100 "$capture_log" > "${capture_log}.tmp"
|
|
152
|
-
mv "${capture_log}.tmp" "$capture_log"
|
|
153
|
-
fi
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
157
|
-
# Hook Coordination
|
|
158
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
159
|
-
|
|
160
|
-
# Lock for preventing race conditions
|
|
161
|
-
acquire_lock() {
|
|
162
|
-
local session_id="$1"
|
|
163
|
-
local lock_file="$STATE_DIR/lock-${session_id}.lock"
|
|
164
|
-
local timeout=5
|
|
165
|
-
local waited=0
|
|
166
|
-
|
|
167
|
-
while [ -f "$lock_file" ] && [ $waited -lt $timeout ]; do
|
|
168
|
-
sleep 0.1
|
|
169
|
-
waited=$((waited + 1))
|
|
170
|
-
done
|
|
171
|
-
|
|
172
|
-
if [ -f "$lock_file" ]; then
|
|
173
|
-
# Stale lock (older than 10 seconds)
|
|
174
|
-
local lock_age=$(($(date +%s) - $(stat -f %m "$lock_file" 2>/dev/null || stat -c %Y "$lock_file" 2>/dev/null || echo 0)))
|
|
175
|
-
if [ $lock_age -gt 10 ]; then
|
|
176
|
-
rm -f "$lock_file"
|
|
177
|
-
else
|
|
178
|
-
return 1 # Failed to acquire
|
|
179
|
-
fi
|
|
180
|
-
fi
|
|
181
|
-
|
|
182
|
-
# Acquire lock
|
|
183
|
-
echo $$ > "$lock_file"
|
|
184
|
-
return 0
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
# Release lock
|
|
188
|
-
release_lock() {
|
|
189
|
-
local session_id="$1"
|
|
190
|
-
local lock_file="$STATE_DIR/lock-${session_id}.lock"
|
|
191
|
-
|
|
192
|
-
if [ -f "$lock_file" ] && [ "$(cat "$lock_file")" = "$$" ]; then
|
|
193
|
-
rm -f "$lock_file"
|
|
194
|
-
fi
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
198
|
-
# Cleanup
|
|
199
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
200
|
-
|
|
201
|
-
# Clean up old state files
|
|
202
|
-
cleanup_old_state() {
|
|
203
|
-
# Remove files older than 24 hours
|
|
204
|
-
find "$STATE_DIR" -name "*.json" -mtime +1 -delete 2>/dev/null || true
|
|
205
|
-
find "$STATE_DIR" -name "*.log" -mtime +1 -delete 2>/dev/null || true
|
|
206
|
-
find "$STATE_DIR" -name "*.lock" -mtime +1 -delete 2>/dev/null || true
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
# Cleanup on exit
|
|
210
|
-
trap cleanup_old_state EXIT
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
-
# ekkOS_ Hook: SessionStart - Initialize session (Windows)
|
|
3
|
-
# MANAGED BY ekkos-connect - DO NOT EDIT DIRECTLY
|
|
4
|
-
# EKKOS_MANAGED=1
|
|
5
|
-
# EKKOS_MANIFEST_SHA256=<computed-at-build>
|
|
6
|
-
# EKKOS_TEMPLATE_VERSION=1.0.0
|
|
7
|
-
#
|
|
8
|
-
# Per ekkOS Onboarding Spec v1.2 FINAL + ADDENDUM:
|
|
9
|
-
# - All persisted records MUST include: instanceId, sessionId, sessionName
|
|
10
|
-
# - Uses EKKOS_INSTANCE_ID env var for multi-session isolation
|
|
11
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
12
|
-
|
|
13
|
-
$ErrorActionPreference = "SilentlyContinue"
|
|
14
|
-
|
|
15
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
16
|
-
# CONFIG PATHS - No hardcoded word arrays per spec v1.2 Addendum
|
|
17
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
18
|
-
$EkkosConfigDir = if ($env:EKKOS_CONFIG_DIR) { $env:EKKOS_CONFIG_DIR } else { "$env:USERPROFILE\.ekkos" }
|
|
19
|
-
$SessionWordsJson = "$EkkosConfigDir\session-words.json"
|
|
20
|
-
$SessionWordsDefault = "$EkkosConfigDir\.defaults\session-words.json"
|
|
21
|
-
|
|
22
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
23
|
-
# INSTANCE ID - Multi-session isolation per v1.2 ADDENDUM
|
|
24
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
25
|
-
$EkkosInstanceId = if ($env:EKKOS_INSTANCE_ID) { $env:EKKOS_INSTANCE_ID } else { "default" }
|
|
26
|
-
|
|
27
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
28
|
-
# Load session words from JSON file - NO HARDCODED ARRAYS
|
|
29
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
30
|
-
$script:SessionWords = $null
|
|
31
|
-
|
|
32
|
-
function Load-SessionWords {
|
|
33
|
-
$wordsFile = $SessionWordsJson
|
|
34
|
-
|
|
35
|
-
if (-not (Test-Path $wordsFile)) {
|
|
36
|
-
$wordsFile = $SessionWordsDefault
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (-not (Test-Path $wordsFile)) {
|
|
40
|
-
return $null
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
$script:SessionWords = Get-Content $wordsFile -Raw | ConvertFrom-Json
|
|
45
|
-
} catch {
|
|
46
|
-
return $null
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function Convert-UuidToWords {
|
|
51
|
-
param([string]$uuid)
|
|
52
|
-
|
|
53
|
-
if (-not $script:SessionWords) {
|
|
54
|
-
Load-SessionWords
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (-not $script:SessionWords) {
|
|
58
|
-
return "unknown-session"
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
$adjectives = $script:SessionWords.adjectives
|
|
62
|
-
$nouns = $script:SessionWords.nouns
|
|
63
|
-
$verbs = $script:SessionWords.verbs
|
|
64
|
-
|
|
65
|
-
if (-not $adjectives -or -not $nouns -or -not $verbs) {
|
|
66
|
-
return "unknown-session"
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (-not $uuid -or $uuid -eq "unknown") { return "unknown-session" }
|
|
70
|
-
|
|
71
|
-
$clean = $uuid -replace "-", ""
|
|
72
|
-
if ($clean.Length -lt 12) { return "unknown-session" }
|
|
73
|
-
|
|
74
|
-
try {
|
|
75
|
-
$a = [Convert]::ToInt32($clean.Substring(0,4), 16) % $adjectives.Length
|
|
76
|
-
$n = [Convert]::ToInt32($clean.Substring(4,4), 16) % $nouns.Length
|
|
77
|
-
$an = [Convert]::ToInt32($clean.Substring(8,4), 16) % $verbs.Length
|
|
78
|
-
|
|
79
|
-
return "$($adjectives[$a])-$($nouns[$n])-$($verbs[$an])"
|
|
80
|
-
} catch {
|
|
81
|
-
return "unknown-session"
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
86
|
-
# READ INPUT
|
|
87
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
88
|
-
$inputJson = [Console]::In.ReadToEnd()
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
$input = $inputJson | ConvertFrom-Json
|
|
92
|
-
$sessionId = $input.session_id
|
|
93
|
-
} catch {
|
|
94
|
-
$sessionId = "unknown"
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
$sessionName = Convert-UuidToWords $sessionId
|
|
98
|
-
|
|
99
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
100
|
-
# INITIALIZE STATE DIRECTORY
|
|
101
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
102
|
-
$stateDir = Join-Path $env:USERPROFILE ".claude\state"
|
|
103
|
-
if (-not (Test-Path $stateDir)) {
|
|
104
|
-
New-Item -ItemType Directory -Path $stateDir -Force | Out-Null
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
# Reset turn counter for new session
|
|
108
|
-
$stateFile = Join-Path $stateDir "hook-state.json"
|
|
109
|
-
$state = @{
|
|
110
|
-
turn = 0
|
|
111
|
-
session_id = $sessionId
|
|
112
|
-
session_name = $sessionName
|
|
113
|
-
instance_id = $EkkosInstanceId
|
|
114
|
-
started_at = (Get-Date).ToString("o")
|
|
115
|
-
} | ConvertTo-Json -Depth 10
|
|
116
|
-
|
|
117
|
-
Set-Content -Path $stateFile -Value $state -Force
|
|
118
|
-
|
|
119
|
-
# Save session ID for other hooks
|
|
120
|
-
$sessionFile = Join-Path $stateDir "current-session.json"
|
|
121
|
-
$sessionData = @{
|
|
122
|
-
session_id = $sessionId
|
|
123
|
-
session_name = $sessionName
|
|
124
|
-
instance_id = $EkkosInstanceId
|
|
125
|
-
} | ConvertTo-Json -Depth 10
|
|
126
|
-
|
|
127
|
-
Set-Content -Path $sessionFile -Value $sessionData -Force
|
|
128
|
-
|
|
129
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
130
|
-
# LOCAL CACHE: Initialize session in Tier 0 cache
|
|
131
|
-
# Per v1.2 ADDENDUM: Pass instanceId for namespacing
|
|
132
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
133
|
-
$captureCmd = Get-Command "ekkos-capture" -ErrorAction SilentlyContinue
|
|
134
|
-
if ($captureCmd -and $sessionId -ne "unknown") {
|
|
135
|
-
try {
|
|
136
|
-
# NEW format: ekkos-capture init <instance_id> <session_id> <session_name>
|
|
137
|
-
Start-Job -ScriptBlock {
|
|
138
|
-
param($instanceId, $sessId, $sessName)
|
|
139
|
-
try {
|
|
140
|
-
& ekkos-capture init $instanceId $sessId $sessName 2>&1 | Out-Null
|
|
141
|
-
} catch {}
|
|
142
|
-
} -ArgumentList $EkkosInstanceId, $sessionId, $sessionName | Out-Null
|
|
143
|
-
} catch {}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
Write-Output "ekkOS session initialized"
|