@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,320 @@
1
+ #!/bin/bash
2
+ # ═══════════════════════════════════════════════════════════════════════════
3
+ # ekkOS_ Turn Contract Library
4
+ #
5
+ # Shared functions for Golden Loop compliance enforcement.
6
+ # Used by BOTH Claude Code (.claude/) and Cursor (.cursor/) hooks.
7
+ #
8
+ # TURN CONTRACT: Evidence that retrieval occurred before answering.
9
+ # This is the SINGLE SOURCE OF TRUTH for compliance auditing.
10
+ # ═══════════════════════════════════════════════════════════════════════════
11
+
12
+ # Get contract directory based on environment
13
+ get_contract_dir() {
14
+ local source="${1:-claude-code}"
15
+ local project_root="${2:-$PROJECT_ROOT}"
16
+
17
+ if [ "$source" = "cursor" ]; then
18
+ echo "$project_root/.cursor/state/ekkos"
19
+ else
20
+ echo "$project_root/.claude/state/ekkos"
21
+ fi
22
+ }
23
+
24
+ # Generate stable hash of user prompt (for deduplication)
25
+ generate_query_hash() {
26
+ local query="$1"
27
+ # Use md5 on macOS, md5sum on Linux
28
+ if command -v md5 >/dev/null 2>&1; then
29
+ echo -n "$query" | md5 | cut -c1-16
30
+ elif command -v md5sum >/dev/null 2>&1; then
31
+ echo -n "$query" | md5sum | cut -c1-16
32
+ else
33
+ # Fallback: simple hash using cksum
34
+ echo -n "$query" | cksum | cut -d' ' -f1
35
+ fi
36
+ }
37
+
38
+ # Write turn contract at RETRIEVAL time
39
+ # This is the EVIDENCE that retrieval happened before answering
40
+ write_turn_contract() {
41
+ local session_id="$1"
42
+ local retrieval_ok="$2"
43
+ local retrieval_source="$3"
44
+ local pattern_ids="$4" # Comma-separated list
45
+ local directive_ids="$5" # Comma-separated list
46
+ local query_hash="$6"
47
+ local project_root="${7:-$PROJECT_ROOT}"
48
+
49
+ local contract_dir
50
+ contract_dir=$(get_contract_dir "$retrieval_source" "$project_root")
51
+ mkdir -p "$contract_dir" 2>/dev/null || return 1
52
+
53
+ local contract_file="$contract_dir/turn-contract-${session_id}.json"
54
+ local timestamp
55
+ timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)
56
+
57
+ # Convert comma-separated IDs to JSON array
58
+ local pattern_array
59
+ local directive_array
60
+ if [ -n "$pattern_ids" ]; then
61
+ pattern_array=$(echo "$pattern_ids" | tr ',' '\n' | grep -v '^$' | jq -R . | jq -s .)
62
+ else
63
+ pattern_array="[]"
64
+ fi
65
+ if [ -n "$directive_ids" ]; then
66
+ directive_array=$(echo "$directive_ids" | tr ',' '\n' | grep -v '^$' | jq -R . | jq -s .)
67
+ else
68
+ directive_array="[]"
69
+ fi
70
+
71
+ # Write contract
72
+ cat > "$contract_file" << EOF
73
+ {
74
+ "session_id": "$session_id",
75
+ "retrieval_ok": $retrieval_ok,
76
+ "retrieval_source": "$retrieval_source",
77
+ "retrieved_pattern_ids": $pattern_array,
78
+ "retrieved_directive_ids": $directive_array,
79
+ "timestamp": "$timestamp",
80
+ "query_hash": "$query_hash",
81
+ "ekkos_strict": ${EKKOS_STRICT:-0}
82
+ }
83
+ EOF
84
+
85
+ return 0
86
+ }
87
+
88
+ # Read turn contract
89
+ read_turn_contract() {
90
+ local session_id="$1"
91
+ local retrieval_source="$2"
92
+ local project_root="${3:-$PROJECT_ROOT}"
93
+
94
+ local contract_dir
95
+ contract_dir=$(get_contract_dir "$retrieval_source" "$project_root")
96
+ local contract_file="$contract_dir/turn-contract-${session_id}.json"
97
+
98
+ if [ -f "$contract_file" ]; then
99
+ cat "$contract_file"
100
+ return 0
101
+ else
102
+ return 1
103
+ fi
104
+ }
105
+
106
+ # Extract field from contract JSON
107
+ get_contract_field() {
108
+ local contract_json="$1"
109
+ local field="$2"
110
+
111
+ echo "$contract_json" | jq -r ".$field // \"\"" 2>/dev/null
112
+ }
113
+
114
+ # Get array field as comma-separated string
115
+ get_contract_array() {
116
+ local contract_json="$1"
117
+ local field="$2"
118
+
119
+ echo "$contract_json" | jq -r ".$field // [] | join(\",\")" 2>/dev/null
120
+ }
121
+
122
+ # Cleanup turn contract (only after successful capture)
123
+ cleanup_turn_contract() {
124
+ local session_id="$1"
125
+ local retrieval_source="$2"
126
+ local project_root="${3:-$PROJECT_ROOT}"
127
+
128
+ local contract_dir
129
+ contract_dir=$(get_contract_dir "$retrieval_source" "$project_root")
130
+ local contract_file="$contract_dir/turn-contract-${session_id}.json"
131
+
132
+ rm -f "$contract_file" 2>/dev/null
133
+ }
134
+
135
+ # Check if strict mode is enabled
136
+ is_strict_mode() {
137
+ [ "${EKKOS_STRICT:-0}" = "1" ]
138
+ }
139
+
140
+ # Generate strict mode blocker message for Claude Code
141
+ get_strict_blocker_message() {
142
+ cat << 'EOF'
143
+ ════════════════════════════════════════════════════════════════════════════
144
+ ⛔ EKKOS_STRICT MODE: RETRIEVAL FAILED — DO NOT ANSWER
145
+
146
+ ekkOS memory retrieval failed or was not authenticated.
147
+ In STRICT mode, you MUST NOT answer technical questions without memory context.
148
+
149
+ ACTION REQUIRED:
150
+ 1. Check if ekkOS is connected: Run `ekkOS: Connect` in VS Code
151
+ 2. Verify auth token exists: ~/.ekkos/config.json
152
+ 3. Retry the request after connecting
153
+
154
+ DO NOT proceed with answering. The Golden Loop requires retrieval FIRST.
155
+ ════════════════════════════════════════════════════════════════════════════
156
+ EOF
157
+ }
158
+
159
+ # Validate PatternGuard coverage (returns 0-100)
160
+ calculate_pattern_guard_coverage() {
161
+ local assistant_response="$1"
162
+ local pattern_ids="$2" # Comma-separated
163
+
164
+ # Count total patterns
165
+ local total_count
166
+ total_count=$(echo "$pattern_ids" | tr ',' '\n' | grep -c '.' || echo 0)
167
+
168
+ if [ "$total_count" -eq 0 ]; then
169
+ echo "100" # No patterns = 100% coverage by definition
170
+ return 0
171
+ fi
172
+
173
+ # Extract acknowledged IDs from [ekkOS_SELECT] and [ekkOS_SKIP] blocks
174
+ local acknowledged_count=0
175
+
176
+ # Check SELECT block
177
+ local select_block
178
+ select_block=$(echo "$assistant_response" | grep -ozP '\[ekkOS_SELECT\][\s\S]*?\[/ekkOS_SELECT\]' 2>/dev/null | tr '\0' '\n' || true)
179
+ if [ -n "$select_block" ]; then
180
+ local select_count
181
+ select_count=$(echo "$select_block" | grep -oE 'id:\s*[a-f0-9-]+' | wc -l | tr -d ' ')
182
+ acknowledged_count=$((acknowledged_count + select_count))
183
+ fi
184
+
185
+ # Check SKIP block
186
+ local skip_block
187
+ skip_block=$(echo "$assistant_response" | grep -ozP '\[ekkOS_SKIP\][\s\S]*?\[/ekkOS_SKIP\]' 2>/dev/null | tr '\0' '\n' || true)
188
+ if [ -n "$skip_block" ]; then
189
+ local skip_count
190
+ skip_count=$(echo "$skip_block" | grep -oE 'id:\s*[a-f0-9-]+' | wc -l | tr -d ' ')
191
+ acknowledged_count=$((acknowledged_count + skip_count))
192
+ fi
193
+
194
+ # Legacy: Check for [ekkOS_APPLY] markers (fallback)
195
+ if [ "$acknowledged_count" -eq 0 ]; then
196
+ local apply_count
197
+ apply_count=$(echo "$assistant_response" | grep -c '\[ekkOS_APPLY\]' || echo 0)
198
+ acknowledged_count=$apply_count
199
+ fi
200
+
201
+ # Calculate coverage percentage
202
+ local coverage
203
+ coverage=$((acknowledged_count * 100 / total_count))
204
+
205
+ # Cap at 100%
206
+ if [ "$coverage" -gt 100 ]; then
207
+ coverage=100
208
+ fi
209
+
210
+ echo "$coverage"
211
+ }
212
+
213
+ # Check for ekkOS footer presence
214
+ check_footer_present() {
215
+ local assistant_response="$1"
216
+
217
+ # Look for the mandatory footer format:
218
+ # 🧠 **ekkOS_™** · 📅 YYYY-MM-DD
219
+ # OR
220
+ # {IDE} ({Model}) · 🧠 **ekkOS_™** · 📅 {Timestamp}
221
+
222
+ if echo "$assistant_response" | grep -qE '🧠.*ekkOS.*📅.*[0-9]{4}-[0-9]{2}-[0-9]{2}'; then
223
+ echo "true"
224
+ return 0
225
+ else
226
+ echo "false"
227
+ return 1
228
+ fi
229
+ }
230
+
231
+ # Build compliance metadata for capture
232
+ build_compliance_metadata() {
233
+ local retrieval_ok="$1"
234
+ local pattern_guard_coverage="$2"
235
+ local footer_present="$3"
236
+ local ekkos_strict="$4"
237
+ local retrieved_count="$5"
238
+
239
+ local pattern_guard_required="false"
240
+ if [ "$retrieved_count" -gt 0 ]; then
241
+ pattern_guard_required="true"
242
+ fi
243
+
244
+ cat << EOF
245
+ {
246
+ "retrieval_ok": $retrieval_ok,
247
+ "pattern_guard_required": $pattern_guard_required,
248
+ "pattern_guard_coverage_pct": $pattern_guard_coverage,
249
+ "footer_present": $footer_present,
250
+ "ekkos_strict": $ekkos_strict,
251
+ "retrieved_count": $retrieved_count,
252
+ "compliance_version": "1.0"
253
+ }
254
+ EOF
255
+ }
256
+
257
+ # Determine if turn is compliant
258
+ is_turn_compliant() {
259
+ local retrieval_ok="$1"
260
+ local pattern_guard_coverage="$2"
261
+ local footer_present="$3"
262
+ local pattern_count="$4"
263
+
264
+ # Retrieval must have succeeded
265
+ if [ "$retrieval_ok" != "true" ]; then
266
+ echo "false"
267
+ return 1
268
+ fi
269
+
270
+ # If patterns were retrieved, PatternGuard must be 100%
271
+ if [ "$pattern_count" -gt 0 ] && [ "$pattern_guard_coverage" -lt 100 ]; then
272
+ echo "false"
273
+ return 1
274
+ fi
275
+
276
+ # Footer must be present
277
+ if [ "$footer_present" != "true" ]; then
278
+ echo "false"
279
+ return 1
280
+ fi
281
+
282
+ echo "true"
283
+ return 0
284
+ }
285
+
286
+ # Generate violation reason
287
+ get_violation_reason() {
288
+ local retrieval_ok="$1"
289
+ local pattern_guard_coverage="$2"
290
+ local footer_present="$3"
291
+ local pattern_count="$4"
292
+
293
+ local reasons=""
294
+
295
+ if [ "$retrieval_ok" != "true" ]; then
296
+ reasons="retrieval_failed"
297
+ fi
298
+
299
+ if [ "$pattern_count" -gt 0 ] && [ "$pattern_guard_coverage" -lt 100 ]; then
300
+ if [ -n "$reasons" ]; then
301
+ reasons="$reasons,pattern_guard_incomplete"
302
+ else
303
+ reasons="pattern_guard_incomplete"
304
+ fi
305
+ fi
306
+
307
+ if [ "$footer_present" != "true" ]; then
308
+ if [ -n "$reasons" ]; then
309
+ reasons="$reasons,footer_missing"
310
+ else
311
+ reasons="footer_missing"
312
+ fi
313
+ fi
314
+
315
+ if [ -z "$reasons" ]; then
316
+ reasons="none"
317
+ fi
318
+
319
+ echo "$reasons"
320
+ }
@@ -0,0 +1,75 @@
1
+ #!/bin/bash
2
+ # ═══════════════════════════════════════════════════════════════════════════
3
+ # ekkOS_ Hook: Stop (Cursor Agent Mode)
4
+ #
5
+ # Fires when agent iteration completes. Can:
6
+ # 1. Clear Time Machine consumed flag (allow new requests)
7
+ # 2. Capture session summary
8
+ # 3. Optionally submit follow-up message
9
+ # ═══════════════════════════════════════════════════════════════════════════
10
+
11
+ set +e
12
+
13
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
14
+ PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
15
+ STATE_DIR="$PROJECT_ROOT/.cursor/state"
16
+
17
+ # Read JSON input
18
+ INPUT=$(cat)
19
+
20
+ # Extract status
21
+ STATUS=$(echo "$INPUT" | jq -r '.status // "unknown"' 2>/dev/null || echo "unknown")
22
+ LOOP_COUNT=$(echo "$INPUT" | jq -r '.loop_count // 0' 2>/dev/null || echo "0")
23
+
24
+ # ═══════════════════════════════════════════════════════════════════════════
25
+ # Clear Time Machine flag on session end (allow new requests next session)
26
+ # ═══════════════════════════════════════════════════════════════════════════
27
+ if [ "$STATUS" = "completed" ] || [ "$STATUS" = "aborted" ]; then
28
+ rm -f "$STATE_DIR/time-machine-consumed.flag" 2>/dev/null || true
29
+ fi
30
+
31
+ # ═══════════════════════════════════════════════════════════════════════════
32
+ # Optional: Load auth for session summary
33
+ # ═══════════════════════════════════════════════════════════════════════════
34
+ EKKOS_CONFIG="$HOME/.ekkos/config.json"
35
+ AUTH_TOKEN=""
36
+ USER_ID=""
37
+
38
+ if [ -f "$EKKOS_CONFIG" ]; then
39
+ AUTH_TOKEN=$(jq -r '.hookApiKey // .apiKey // ""' "$EKKOS_CONFIG" 2>/dev/null || echo "")
40
+ USER_ID=$(jq -r '.userId // ""' "$EKKOS_CONFIG" 2>/dev/null || echo "")
41
+ fi
42
+
43
+ if [ -z "$AUTH_TOKEN" ] && [ -f "$PROJECT_ROOT/.env.local" ]; then
44
+ AUTH_TOKEN=$(grep -E "^SUPABASE_SECRET_KEY=" "$PROJECT_ROOT/.env.local" | cut -d'=' -f2- | tr -d '"' | tr -d "'" | tr -d '\r')
45
+ fi
46
+
47
+ # ═══════════════════════════════════════════════════════════════════════════
48
+ # Log session end (fire and forget)
49
+ # ═══════════════════════════════════════════════════════════════════════════
50
+ if [ -n "$AUTH_TOKEN" ]; then
51
+ SESSION_ID=""
52
+ if [ -f "$STATE_DIR/current_session_id.txt" ]; then
53
+ SESSION_ID=$(cat "$STATE_DIR/current_session_id.txt" 2>/dev/null || echo "")
54
+ fi
55
+
56
+ TURN_COUNT=0
57
+ TURN_FILE="$STATE_DIR/turn_${SESSION_ID}.txt"
58
+ if [ -f "$TURN_FILE" ]; then
59
+ TURN_COUNT=$(cat "$TURN_FILE" 2>/dev/null || echo "0")
60
+ fi
61
+
62
+ # Could capture session end event here
63
+ # For now, just clean up
64
+
65
+ # Clean up turn counter for next session
66
+ # (commented out - might want to persist across agent runs)
67
+ # rm -f "$TURN_FILE" 2>/dev/null || true
68
+ fi
69
+
70
+ # ═══════════════════════════════════════════════════════════════════════════
71
+ # Return empty response (no follow-up)
72
+ # ═══════════════════════════════════════════════════════════════════════════
73
+ echo '{}'
74
+
75
+ exit 0
@@ -0,0 +1,187 @@
1
+ ---
2
+ description: "ekkOS Memory - 11-layer cognitive memory with 31 MCP tools"
3
+ alwaysApply: true
4
+ ---
5
+
6
+ # ekkOS Memory System
7
+
8
+ You have access to **ekkOS memory** via 31 MCP tools. This is an 11-layer cognitive memory system that makes AI smarter over time by learning from past sessions.
9
+
10
+ ## MANDATORY RULES
11
+
12
+ ### RULE 1: SEARCH BEFORE ANSWERING
13
+ Before answering ANY technical question, call `ekkOS_Search` first.
14
+ Do not skip this. Do not assume you know the answer.
15
+
16
+ ### RULE 2: ACKNOWLEDGE RETRIEVED PATTERNS
17
+ When patterns are retrieved, acknowledge each one:
18
+ ```
19
+ [ekkOS_SELECT]
20
+ - id: <pattern_id>
21
+ reason: <why using this>
22
+ confidence: <0.0-1.0>
23
+ [/ekkOS_SELECT]
24
+
25
+ [ekkOS_SKIP]
26
+ - id: <pattern_id>
27
+ reason: <why not relevant>
28
+ [/ekkOS_SKIP]
29
+ ```
30
+
31
+ ### RULE 3: FORGE WHAT YOU LEARN
32
+ When you fix a bug, get corrected, or learn something new, call `ekkOS_Forge` immediately.
33
+
34
+ ### RULE 4: FAILURES ARE VALUABLE
35
+ When something DOES NOT work, forge it as an anti-pattern.
36
+
37
+ ## MCP Tools (31 Total)
38
+
39
+ ### Core Memory Tools
40
+ | Tool | Description |
41
+ |------|-------------|
42
+ | `ekkOS_Search` | Search across all 11 memory layers |
43
+ | `ekkOS_Context` | Get relevant context for a task |
44
+ | `ekkOS_Capture` | Capture memory events |
45
+ | `ekkOS_Forge` | Create pattern from learned solution |
46
+ | `ekkOS_Directive` | Create MUST/NEVER/PREFER/AVOID rules |
47
+ | `ekkOS_Outcome` | Track if pattern worked or failed |
48
+ | `ekkOS_Detect` | Auto-detect which patterns were used |
49
+ | `ekkOS_Summary` | Get summary of recent MCP activity |
50
+ | `ekkOS_Conflict` | Check for directive/pattern conflicts |
51
+ | `ekkOS_Recall` | Recall past conversations by time |
52
+ | `ekkOS_Codebase` | Search project code embeddings |
53
+ | `ekkOS_Stats` | Get statistics for all layers |
54
+ | `ekkOS_Track` | Track when pattern is applied |
55
+ | `ekkOS_Reflect` | Analyze response for improvements |
56
+
57
+ ### Schema Awareness Tools
58
+ | Tool | Description |
59
+ |------|-------------|
60
+ | `ekkOS_IndexSchema` | Index database schemas (Supabase/Prisma/TS) |
61
+ | `ekkOS_GetSchema` | Get schema for a specific table/type |
62
+
63
+ ### Portability Tools
64
+ | Tool | Description |
65
+ |------|-------------|
66
+ | `ekkOS_Export` | Export your memory data as portable JSON backup |
67
+ | `ekkOS_Import` | Import memory from backup (auto-deduplication) |
68
+
69
+ ### Plan Management
70
+ | Tool | Description |
71
+ |------|-------------|
72
+ | `ekkOS_Plan` | Create structured task plan |
73
+ | `ekkOS_Plans` | List user's plans |
74
+ | `ekkOS_PlanStatus` | Update plan status |
75
+ | `ekkOS_PlanStep` | Mark step complete/incomplete |
76
+ | `ekkOS_Generate` | AI-generate plan from context |
77
+ | `ekkOS_SaveTemplate` | Save plan as reusable template |
78
+ | `ekkOS_Templates` | List available templates |
79
+ | `ekkOS_FromTemplate` | Create plan from template |
80
+
81
+ ### Secrets Management (Layer 11)
82
+ | Tool | Description |
83
+ |------|-------------|
84
+ | `ekkOS_StoreSecret` | Encrypt and store sensitive data |
85
+ | `ekkOS_GetSecret` | Retrieve and decrypt a secret |
86
+ | `ekkOS_ListSecrets` | List secrets metadata (no values) |
87
+ | `ekkOS_DeleteSecret` | Permanently delete a secret |
88
+ | `ekkOS_RotateSecret` | Update secret with new value |
89
+
90
+ ## 11-Layer Architecture
91
+
92
+ | # | Layer | Purpose |
93
+ |---|-------|---------|
94
+ | 1 | Working | Current session state |
95
+ | 2 | Episodic | Past conversations |
96
+ | 3 | Semantic | Embeddings/knowledge |
97
+ | 4 | Patterns | Proven solutions |
98
+ | 5 | Procedural | Step-by-step guides |
99
+ | 6 | Collective | Cross-project wisdom |
100
+ | 7 | Meta | Pattern effectiveness |
101
+ | 8 | Codebase | Project-specific code |
102
+ | 9 | Directives | MUST/NEVER/PREFER/AVOID rules |
103
+ | 10 | Conflict Resolution | Auto-resolves contradictions |
104
+ | 11 | Secrets | Encrypted credentials (AES-256-GCM) |
105
+
106
+ ## FORGE TRIGGERS
107
+
108
+ Call `ekkOS_Forge` when you:
109
+ - Fix a bug (especially non-obvious)
110
+ - Discover a better approach
111
+ - Find a pitfall or gotcha
112
+ - Get corrected by the user
113
+ - Solve auth/config issues
114
+ - Make architectural decisions
115
+ - Debug non-trivially
116
+ - Find something that DOESN'T work
117
+
118
+ Call `ekkOS_Directive` when user says:
119
+ - "always..." → MUST
120
+ - "never..." → NEVER
121
+ - "I prefer..." → PREFER
122
+ - "don't..." / "avoid..." → AVOID
123
+
124
+ ## Response Format
125
+
126
+ End every response with:
127
+ ```
128
+ ---
129
+ 🧠 **ekkOS_™** · 📅 YYYY-MM-DD H:MM AM/PM TZ
130
+ ```
131
+
132
+
133
+
134
+
135
+
136
+
137
+
138
+
139
+
140
+
141
+
142
+
143
+
144
+
145
+
146
+
147
+
148
+
149
+
150
+
151
+
152
+
153
+
154
+
155
+
156
+
157
+
158
+
159
+
160
+
161
+
162
+
163
+
164
+
165
+
166
+
167
+
168
+
169
+
170
+
171
+
172
+
173
+
174
+
175
+
176
+
177
+
178
+
179
+
180
+
181
+
182
+
183
+
184
+
185
+
186
+
187
+
@@ -0,0 +1,96 @@
1
+ #!/bin/bash
2
+ # Post-response hook: Validates and enforces ekkOS footer format
3
+ # Runs AFTER assistant response, checks footer compliance
4
+
5
+ RESPONSE_FILE="$1"
6
+ HOOK_ENV="$2"
7
+
8
+ # Exit if no response file
9
+ if [[ ! -f "$RESPONSE_FILE" ]]; then
10
+ exit 0
11
+ fi
12
+
13
+ # Parse metadata from hook environment
14
+ SESSION_ID=$(echo "$HOOK_ENV" | jq -r '.sessionId // "unknown"')
15
+ TURN=$(echo "$HOOK_ENV" | jq -r '.turn // 0')
16
+ CONTEXT_PERCENT=$(echo "$HOOK_ENV" | jq -r '.contextUsagePercent // 0')
17
+ MODEL=$(echo "$HOOK_ENV" | jq -r '.model // "Claude Code (Opus 4.5)"')
18
+
19
+ # Convert session UUID to word-based name
20
+ convert_uuid_to_name() {
21
+ local uuid="$1"
22
+
23
+ # Word lists (same as MCP)
24
+ local ADJECTIVES=("cosmic" "turbo" "mega" "hyper" "quantum" "atomic" "stellar" "epic"
25
+ "mighty" "groovy" "zippy" "snappy" "jazzy" "funky" "zesty" "peppy"
26
+ "spicy" "crispy" "fluffy" "sparkly" "chunky" "bouncy" "bubbly" "sassy"
27
+ "slick" "sleek" "bold" "nifty" "perky" "plucky" "witty" "nimble"
28
+ "dapper" "fancy" "quirky" "punchy" "swift" "brave" "clever" "dandy"
29
+ "eager" "fiery" "golden" "hasty" "icy" "jolly" "keen" "lively"
30
+ "merry" "noble" "odd" "plush" "quick" "royal" "silly" "tidy"
31
+ "ultra" "vivid" "wacky" "zany" "alpha" "beta" "cyber" "delta"
32
+ "electric" "foggy" "giga" "hazy" "ionic" "jumpy" "kinky" "lunar"
33
+ "magic" "nerdy" "omega" "pixel" "quaint" "retro" "solar" "techno"
34
+ "unified" "viral" "wonky" "xerox" "yappy" "zen" "agile" "binary"
35
+ "chrome" "disco" "elastic" "fizzy" "glossy" "humble" "itchy" "jiffy"
36
+ "kooky" "loopy" "moody" "noisy")
37
+
38
+ local NOUNS=("penguin" "panda" "otter" "narwhal" "alpaca" "llama" "badger" "walrus"
39
+ "waffle" "pickle" "noodle" "pretzel" "muffin" "taco" "nugget" "biscuit"
40
+ "rocket" "comet" "nebula" "quasar" "meteor" "photon" "pulsar" "nova"
41
+ "ninja" "pirate" "wizard" "robot" "yeti" "phoenix" "sphinx" "kraken"
42
+ "thunder" "blizzard" "tornado" "avalanche" "mango" "kiwi" "banana" "coconut"
43
+ "donut" "espresso" "falafel" "gyro" "hummus" "icecream" "jambon" "kebab"
44
+ "latte" "mocha" "nachos" "olive" "pasta" "quinoa" "ramen" "sushi"
45
+ "tamale" "udon" "velvet" "wasabi" "xmas" "yogurt" "ziti" "anchor"
46
+ "beacon" "canyon" "drifter" "echo" "falcon" "glacier" "harbor" "island"
47
+ "jetpack" "kayak" "lagoon" "meadow" "orbit" "parrot" "quest"
48
+ "rapids" "summit" "tunnel" "umbrella" "volcano" "whisper" "xylophone" "yacht"
49
+ "zephyr" "acorn" "bobcat" "cactus" "dolphin" "eagle" "ferret" "gopher"
50
+ "hedgehog" "iguana" "jackal" "koala")
51
+
52
+ # Extract first 8 hex chars
53
+ local hex="${uuid:0:8}"
54
+ hex="${hex//-/}"
55
+
56
+ # Convert to number
57
+ local num=$((16#$hex))
58
+
59
+ # Calculate indices
60
+ local adj_idx=$((num % 100))
61
+ local noun_idx=$(((num / 100) % 100))
62
+
63
+ echo "${ADJECTIVES[$adj_idx]}-${NOUNS[$noun_idx]}"
64
+ }
65
+
66
+ SESSION_NAME=$(convert_uuid_to_name "$SESSION_ID")
67
+ TIMESTAMP=$(date "+%Y-%m-%d %I:%M %p %Z")
68
+
69
+ # Required footer format
70
+ REQUIRED_FOOTER="---
71
+ $MODEL · $SESSION_NAME · Turn $TURN · ${CONTEXT_PERCENT}% · 🧠 **ekkOS_™** · 📅 $TIMESTAMP"
72
+
73
+ # Check if response has correct footer
74
+ RESPONSE_CONTENT=$(cat "$RESPONSE_FILE")
75
+ LAST_LINE=$(echo "$RESPONSE_CONTENT" | tail -1)
76
+
77
+ # Check if footer exists and is correct
78
+ if [[ "$LAST_LINE" == *"ekkOS"* ]] && [[ "$LAST_LINE" == *"Turn"* ]]; then
79
+ # Footer exists - validate format
80
+ if [[ "$LAST_LINE" == *"Turn $TURN"* ]] && [[ "$LAST_LINE" == *"${CONTEXT_PERCENT}%"* ]] && [[ "$LAST_LINE" == *"$SESSION_NAME"* ]]; then
81
+ # Footer is correct
82
+ exit 0
83
+ else
84
+ # Footer exists but is malformed - replace it
85
+ RESPONSE_WITHOUT_FOOTER=$(echo "$RESPONSE_CONTENT" | head -n -2) # Remove last 2 lines (--- and footer)
86
+ echo "$RESPONSE_WITHOUT_FOOTER" > "$RESPONSE_FILE"
87
+ echo "" >> "$RESPONSE_FILE"
88
+ echo "$REQUIRED_FOOTER" >> "$RESPONSE_FILE"
89
+ fi
90
+ else
91
+ # Footer missing - append it
92
+ echo "" >> "$RESPONSE_FILE"
93
+ echo "$REQUIRED_FOOTER" >> "$RESPONSE_FILE"
94
+ fi
95
+
96
+ exit 0