@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,587 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
3
|
+
# ekkOS_ Hook: UserPromptSubmit - SEAMLESS CONTEXT CONTINUITY
|
|
4
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
5
|
+
# ZERO USER ACTION NEEDED:
|
|
6
|
+
# 1. Tracks turn number and context size
|
|
7
|
+
# 2. Detects when compaction happened (context dropped from high to low)
|
|
8
|
+
# 3. AUTO-INJECTS restored context - user just keeps working
|
|
9
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
10
|
+
|
|
11
|
+
set +e
|
|
12
|
+
|
|
13
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
14
|
+
# SESSION NAME GENERATION (must be defined early - used by ekkos-capture)
|
|
15
|
+
# Format: adj-noun-verb (e.g., "cosmic-penguin-runs")
|
|
16
|
+
# 100 × 100 × 100 = 1,000,000 combinations
|
|
17
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
18
|
+
ADJECTIVES=(
|
|
19
|
+
"cosmic" "turbo" "mega" "hyper" "quantum" "atomic" "stellar" "epic"
|
|
20
|
+
"mighty" "groovy" "zippy" "snappy" "jazzy" "funky" "zesty" "peppy"
|
|
21
|
+
"spicy" "crispy" "fluffy" "sparkly" "chunky" "bouncy" "bubbly" "sassy"
|
|
22
|
+
"slick" "sleek" "bold" "nifty" "perky" "plucky" "witty" "nimble"
|
|
23
|
+
"dapper" "fancy" "quirky" "punchy" "swift" "brave" "clever" "dandy"
|
|
24
|
+
"eager" "fiery" "golden" "hasty" "icy" "jolly" "keen" "lively"
|
|
25
|
+
"merry" "noble" "odd" "plush" "quick" "royal" "silly" "tidy"
|
|
26
|
+
"ultra" "vivid" "wacky" "zany" "alpha" "beta" "cyber" "delta"
|
|
27
|
+
"electric" "foggy" "giga" "hazy" "ionic" "jumpy" "kinky" "lunar"
|
|
28
|
+
"magic" "nerdy" "omega" "pixel" "quaint" "retro" "solar" "techno"
|
|
29
|
+
"unified" "viral" "wonky" "xerox" "yappy" "zen" "agile" "binary"
|
|
30
|
+
"chrome" "disco" "elastic" "fizzy" "glossy" "humble" "itchy" "jiffy"
|
|
31
|
+
"kooky" "loopy" "moody" "noisy"
|
|
32
|
+
)
|
|
33
|
+
NOUNS=(
|
|
34
|
+
"penguin" "panda" "otter" "narwhal" "alpaca" "llama" "badger" "walrus"
|
|
35
|
+
"waffle" "pickle" "noodle" "pretzel" "muffin" "taco" "nugget" "biscuit"
|
|
36
|
+
"rocket" "comet" "nebula" "quasar" "meteor" "photon" "pulsar" "nova"
|
|
37
|
+
"ninja" "pirate" "wizard" "robot" "yeti" "phoenix" "sphinx" "kraken"
|
|
38
|
+
"thunder" "blizzard" "tornado" "avalanche" "mango" "kiwi" "banana" "coconut"
|
|
39
|
+
"donut" "espresso" "falafel" "gyro" "hummus" "icecream" "jambon" "kebab"
|
|
40
|
+
"latte" "mocha" "nachos" "olive" "pasta" "quinoa" "ramen" "sushi"
|
|
41
|
+
"tamale" "udon" "velvet" "wasabi" "xmas" "yogurt" "ziti" "anchor"
|
|
42
|
+
"beacon" "canyon" "drifter" "echo" "falcon" "glacier" "harbor" "island"
|
|
43
|
+
"jetpack" "kayak" "lagoon" "meadow" "nebula" "orbit" "parrot" "quest"
|
|
44
|
+
"rapids" "summit" "tunnel" "umbrella" "volcano" "whisper" "xylophone" "yacht"
|
|
45
|
+
"zephyr" "acorn" "bobcat" "cactus" "dolphin" "eagle" "ferret" "gopher"
|
|
46
|
+
"hedgehog" "iguana" "jackal" "koala"
|
|
47
|
+
)
|
|
48
|
+
VERBS=(
|
|
49
|
+
"runs" "jumps" "flies" "swims" "dives" "soars" "glides" "dashes"
|
|
50
|
+
"zooms" "zips" "spins" "twirls" "bounces" "floats" "drifts" "sails"
|
|
51
|
+
"climbs" "leaps" "hops" "skips" "rolls" "slides" "surfs" "rides"
|
|
52
|
+
"builds" "creates" "forges" "shapes" "crafts" "designs" "codes" "types"
|
|
53
|
+
"thinks" "dreams" "learns" "grows" "blooms" "shines" "glows" "sparks"
|
|
54
|
+
"sings" "hums" "calls" "beeps" "clicks" "taps" "pings" "chimes"
|
|
55
|
+
"wins" "leads" "helps" "saves" "guards" "shields" "heals" "fixes"
|
|
56
|
+
"starts" "begins" "launches" "ignites" "blazes" "flares" "bursts" "pops"
|
|
57
|
+
"waves" "nods" "winks" "grins" "smiles" "laughs" "cheers" "claps"
|
|
58
|
+
"seeks" "finds" "spots" "tracks" "hunts" "chases" "catches" "grabs"
|
|
59
|
+
"pushes" "pulls" "lifts" "throws" "kicks" "punts" "bats" "swings"
|
|
60
|
+
"reads" "writes" "draws" "paints" "sculpts" "carves" "molds" "weaves"
|
|
61
|
+
"cooks" "bakes" "grills" "fries"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
uuid_to_words() {
|
|
65
|
+
local uuid="$1"
|
|
66
|
+
local hex="${uuid//-/}"
|
|
67
|
+
hex="${hex:0:12}"
|
|
68
|
+
if [[ ! "$hex" =~ ^[0-9a-fA-F]+$ ]]; then
|
|
69
|
+
echo "unknown-session-starts"
|
|
70
|
+
return
|
|
71
|
+
fi
|
|
72
|
+
local adj_seed=$((16#${hex:0:4}))
|
|
73
|
+
local noun_seed=$((16#${hex:4:4}))
|
|
74
|
+
local verb_seed=$((16#${hex:8:4}))
|
|
75
|
+
local adj_idx=$((adj_seed % ${#ADJECTIVES[@]}))
|
|
76
|
+
local noun_idx=$((noun_seed % ${#NOUNS[@]}))
|
|
77
|
+
local verb_idx=$((verb_seed % ${#VERBS[@]}))
|
|
78
|
+
echo "${ADJECTIVES[$adj_idx]}-${NOUNS[$noun_idx]}-${VERBS[$verb_idx]}"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
82
|
+
PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
|
83
|
+
|
|
84
|
+
INPUT=$(cat)
|
|
85
|
+
USER_QUERY=$(echo "$INPUT" | jq -r '.query // .message // .prompt // ""')
|
|
86
|
+
RAW_SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
|
|
87
|
+
TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // ""')
|
|
88
|
+
|
|
89
|
+
[ -z "$USER_QUERY" ] || [ "$USER_QUERY" = "null" ] && exit 0
|
|
90
|
+
|
|
91
|
+
# Fallback: read session_id from saved state if not in INPUT
|
|
92
|
+
if [ "$RAW_SESSION_ID" = "unknown" ] || [ "$RAW_SESSION_ID" = "null" ] || [ -z "$RAW_SESSION_ID" ]; then
|
|
93
|
+
STATE_FILE="$HOME/.claude/state/current-session.json"
|
|
94
|
+
if [ -f "$STATE_FILE" ]; then
|
|
95
|
+
RAW_SESSION_ID=$(jq -r '.session_id // "unknown"' "$STATE_FILE" 2>/dev/null || echo "unknown")
|
|
96
|
+
fi
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
100
|
+
# INTELLIGENT TOOL ROUTER: Multi-trigger skill detection
|
|
101
|
+
# Detects ALL applicable skills/tools and injects as system reminder
|
|
102
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
103
|
+
SKILL_REMINDERS=()
|
|
104
|
+
QUERY_LOWER=$(echo "$USER_QUERY" | tr '[:upper:]' '[:lower:]')
|
|
105
|
+
|
|
106
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
107
|
+
# MANDATORY TRIGGERS (Always check ekkOS first)
|
|
108
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
109
|
+
|
|
110
|
+
# Memory First - Debug/Error/Problem solving
|
|
111
|
+
if echo "$QUERY_LOWER" | grep -qE '(how do i|debug|error|bug|fix|not working|broken|fails|issue|problem|wrong|crash)'; then
|
|
112
|
+
SKILL_REMINDERS+=("🔧 SKILL REQUIRED: Call Skill(skill: \"ekkOS_Memory_First\") FIRST before debugging")
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
116
|
+
# RECALL TRIGGERS (Time-based memory)
|
|
117
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
118
|
+
if echo "$QUERY_LOWER" | grep -qE '(yesterday|last week|last month|remember when|what did we|where did we leave|before|earlier|previous|ago)'; then
|
|
119
|
+
SKILL_REMINDERS+=("📅 SKILL REQUIRED: Call Skill(skill: \"ekkOS_Deep_Recall\") for time-based memory")
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
123
|
+
# DIRECTIVE TRIGGERS (User preferences)
|
|
124
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
125
|
+
if echo "$QUERY_LOWER" | grep -qE '(always |never |i prefer|i like |dont |don.t |avoid |remember that |from now on)'; then
|
|
126
|
+
SKILL_REMINDERS+=("⚙️ SKILL REQUIRED: Call Skill(skill: \"ekkOS_Preferences\") to capture directive")
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
130
|
+
# SAFETY TRIGGERS (Destructive actions)
|
|
131
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
132
|
+
if echo "$QUERY_LOWER" | grep -qE '(delete|drop |rm -rf|deploy|push.*main|push.*master|production|migrate|rollback)'; then
|
|
133
|
+
SKILL_REMINDERS+=("⚠️ SAFETY REQUIRED: Call ekkOS_Conflict before this destructive action")
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
137
|
+
# SCHEMA TRIGGERS (Database operations)
|
|
138
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
139
|
+
if echo "$QUERY_LOWER" | grep -qE '(sql|query|supabase|prisma|database|table|column|select |insert |update |where )'; then
|
|
140
|
+
SKILL_REMINDERS+=("🗄️ SCHEMA REQUIRED: Call ekkOS_GetSchema for correct field names")
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
144
|
+
# SECRET TRIGGERS (API keys, credentials)
|
|
145
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
146
|
+
if echo "$QUERY_LOWER" | grep -qE '(api key|token|password|credential|secret|my.*key|store.*key)'; then
|
|
147
|
+
SKILL_REMINDERS+=("🔐 SECRETS: Use ekkOS_StoreSecret to securely save credentials")
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
151
|
+
# PLAN TRIGGERS (Complex multi-step tasks)
|
|
152
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
153
|
+
if echo "$QUERY_LOWER" | grep -qE '(implement|build|create.*feature|refactor|migrate|set up|architecture)'; then
|
|
154
|
+
SKILL_REMINDERS+=("📋 PLAN REQUIRED: Call ekkOS_Plan for complex multi-step tasks")
|
|
155
|
+
fi
|
|
156
|
+
|
|
157
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
158
|
+
# LEARN TRIGGERS (User expressing success/failure)
|
|
159
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
160
|
+
if echo "$QUERY_LOWER" | grep -qE '(that worked|thanks|perfect|great|awesome|nailed it|solved|fixed it)'; then
|
|
161
|
+
SKILL_REMINDERS+=("🎯 LEARN: Consider calling ekkOS_Forge to capture this solution as a pattern")
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
165
|
+
# CODEBASE TRIGGERS (Project-specific code search)
|
|
166
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
167
|
+
if echo "$QUERY_LOWER" | grep -qE '(where is|find.*file|search.*code|in this project|in the codebase)'; then
|
|
168
|
+
SKILL_REMINDERS+=("🔍 CODEBASE: Use ekkOS_Codebase for project-specific code search")
|
|
169
|
+
fi
|
|
170
|
+
|
|
171
|
+
# Combine skill reminders (only take first 3 to avoid noise)
|
|
172
|
+
SKILL_REMINDER=""
|
|
173
|
+
REMINDER_COUNT=${#SKILL_REMINDERS[@]}
|
|
174
|
+
if [ "$REMINDER_COUNT" -gt 0 ]; then
|
|
175
|
+
# Take up to 3 most relevant reminders
|
|
176
|
+
MAX_REMINDERS=3
|
|
177
|
+
[ "$REMINDER_COUNT" -lt "$MAX_REMINDERS" ] && MAX_REMINDERS="$REMINDER_COUNT"
|
|
178
|
+
for i in $(seq 0 $((MAX_REMINDERS - 1))); do
|
|
179
|
+
[ -n "$SKILL_REMINDER" ] && SKILL_REMINDER="$SKILL_REMINDER
|
|
180
|
+
"
|
|
181
|
+
SKILL_REMINDER="$SKILL_REMINDER${SKILL_REMINDERS[$i]}"
|
|
182
|
+
done
|
|
183
|
+
fi
|
|
184
|
+
|
|
185
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
186
|
+
# Load auth
|
|
187
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
188
|
+
EKKOS_CONFIG="$HOME/.ekkos/config.json"
|
|
189
|
+
AUTH_TOKEN=""
|
|
190
|
+
if [ -f "$EKKOS_CONFIG" ]; then
|
|
191
|
+
AUTH_TOKEN=$(jq -r '.hookApiKey // .apiKey // ""' "$EKKOS_CONFIG" 2>/dev/null || echo "")
|
|
192
|
+
fi
|
|
193
|
+
[ -z "$AUTH_TOKEN" ] && AUTH_TOKEN=$(grep -E "^SUPABASE_SECRET_KEY=" "$PROJECT_ROOT/.env.local" 2>/dev/null | cut -d'=' -f2- | tr -d '"' | tr -d "'" || echo "")
|
|
194
|
+
|
|
195
|
+
MEMORY_API_URL="https://mcp.ekkos.dev"
|
|
196
|
+
|
|
197
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
198
|
+
# Session ID - NEW ID per conversation (not persisted 24h anymore)
|
|
199
|
+
# Each Claude Code session gets unique ID for proper Time Machine grouping
|
|
200
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
201
|
+
STATE_DIR="$PROJECT_ROOT/.claude/state"
|
|
202
|
+
mkdir -p "$STATE_DIR" 2>/dev/null || true
|
|
203
|
+
SESSION_FILE="$STATE_DIR/current-session.json"
|
|
204
|
+
|
|
205
|
+
# Use Claude's RAW_SESSION_ID exclusively
|
|
206
|
+
SESSION_ID="$RAW_SESSION_ID"
|
|
207
|
+
|
|
208
|
+
# Skip if no valid session ID from Claude
|
|
209
|
+
if [ -z "$SESSION_ID" ] || [ "$SESSION_ID" = "unknown" ] || [ "$SESSION_ID" = "null" ]; then
|
|
210
|
+
exit 0
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
# Save for other hooks to reference (but don't reuse across conversations)
|
|
214
|
+
echo "{\"session_id\": \"$SESSION_ID\", \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}" > "$SESSION_FILE"
|
|
215
|
+
|
|
216
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
217
|
+
# Turn counter - PROJECT-LOCAL storage
|
|
218
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
219
|
+
PROJECT_SESSION_DIR="$STATE_DIR/sessions"
|
|
220
|
+
mkdir -p "$PROJECT_SESSION_DIR" 2>/dev/null || true
|
|
221
|
+
TURN_COUNTER_FILE="$PROJECT_SESSION_DIR/${SESSION_ID}.turn"
|
|
222
|
+
|
|
223
|
+
# Count actual user messages in transcript for accurate turn number
|
|
224
|
+
TURN_NUMBER=1
|
|
225
|
+
if [ -n "$TRANSCRIPT_PATH" ] && [ -f "$TRANSCRIPT_PATH" ]; then
|
|
226
|
+
# Count user message entries in JSONL transcript
|
|
227
|
+
TURN_NUMBER=$(grep -c '"type":"user"' "$TRANSCRIPT_PATH" 2>/dev/null || echo "1")
|
|
228
|
+
[ "$TURN_NUMBER" -eq 0 ] && TURN_NUMBER=1
|
|
229
|
+
fi
|
|
230
|
+
|
|
231
|
+
# PRESERVE HISTORY: Don't overwrite if saved count is higher (after /clear)
|
|
232
|
+
SAVED_TURN_COUNT=0
|
|
233
|
+
[ -f "$TURN_COUNTER_FILE" ] && SAVED_TURN_COUNT=$(cat "$TURN_COUNTER_FILE" 2>/dev/null || echo "0")
|
|
234
|
+
TRANSCRIPT_TURN_COUNT=$TURN_NUMBER # Save for post-clear detection
|
|
235
|
+
POST_CLEAR_DETECTED=false
|
|
236
|
+
if [ "$SAVED_TURN_COUNT" -gt "$TURN_NUMBER" ]; then
|
|
237
|
+
# Post-clear: INCREMENT from saved count (not just copy it)
|
|
238
|
+
TURN_NUMBER=$((SAVED_TURN_COUNT + 1))
|
|
239
|
+
POST_CLEAR_DETECTED=true
|
|
240
|
+
fi
|
|
241
|
+
echo "$TURN_NUMBER" > "$TURN_COUNTER_FILE"
|
|
242
|
+
|
|
243
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
244
|
+
# 🧠 WORKING MEMORY: Fast capture each turn (async, non-blocking)
|
|
245
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
246
|
+
MEMORY_API_URL="https://mcp.ekkos.dev"
|
|
247
|
+
if [ -f "$HOME/.ekkos/config.json" ]; then
|
|
248
|
+
CAPTURE_TOKEN=$(jq -r '.hookApiKey // .apiKey // ""' "$HOME/.ekkos/config.json" 2>/dev/null || echo "")
|
|
249
|
+
if [ -n "$CAPTURE_TOKEN" ] && [ "$CAPTURE_TOKEN" != "null" ]; then
|
|
250
|
+
# Async capture to Redis/Supabase - doesn't block hook execution
|
|
251
|
+
(curl -s -X POST "$MEMORY_API_URL/api/v1/working/fast-capture" \
|
|
252
|
+
-H "Authorization: Bearer $CAPTURE_TOKEN" \
|
|
253
|
+
-H "Content-Type: application/json" \
|
|
254
|
+
-d "{\"session_id\":\"$RAW_SESSION_ID\",\"turn\":$TURN_NUMBER,\"query\":$(echo "$USER_QUERY" | jq -Rs .)}" \
|
|
255
|
+
>/dev/null 2>&1) &
|
|
256
|
+
fi
|
|
257
|
+
fi
|
|
258
|
+
|
|
259
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
260
|
+
# 💾 LOCAL CACHE: Tier 0 capture for instant /continue (async, non-blocking)
|
|
261
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
262
|
+
if command -v ekkos-capture &>/dev/null; then
|
|
263
|
+
# Generate session name if not already set
|
|
264
|
+
if [ -z "$SESSION_NAME" ] || [ "$SESSION_NAME" = "unknown-session-starts" ]; then
|
|
265
|
+
SESSION_NAME=$(uuid_to_words "$RAW_SESSION_ID" 2>/dev/null || echo "unknown-session")
|
|
266
|
+
fi
|
|
267
|
+
# Async local capture - writes to ~/.ekkos/cache/sessions/<uuid>.jsonl
|
|
268
|
+
(ekkos-capture user "$RAW_SESSION_ID" "$SESSION_NAME" "$TURN_NUMBER" "$USER_QUERY" "$PROJECT_ROOT" \
|
|
269
|
+
>/dev/null 2>&1) &
|
|
270
|
+
fi
|
|
271
|
+
|
|
272
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
273
|
+
# 📥 GOLDEN LOOP: CAPTURE PHASE - Track turn start
|
|
274
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
275
|
+
GOLDEN_LOOP_FILE="$PROJECT_ROOT/.ekkos/golden-loop-current.json"
|
|
276
|
+
mkdir -p "$PROJECT_ROOT/.ekkos" 2>/dev/null || true
|
|
277
|
+
|
|
278
|
+
# Write current phase to file (extension watches this for real-time updates)
|
|
279
|
+
jq -n \
|
|
280
|
+
--arg phase "capture" \
|
|
281
|
+
--argjson turn "$TURN_NUMBER" \
|
|
282
|
+
--arg session "$SESSION_ID" \
|
|
283
|
+
--arg timestamp "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
284
|
+
'{
|
|
285
|
+
phase: $phase,
|
|
286
|
+
turn: $turn,
|
|
287
|
+
session: $session,
|
|
288
|
+
timestamp: $timestamp,
|
|
289
|
+
stats: {
|
|
290
|
+
retrieved: 0,
|
|
291
|
+
applied: 0,
|
|
292
|
+
forged: 0
|
|
293
|
+
}
|
|
294
|
+
}' > "$GOLDEN_LOOP_FILE" 2>/dev/null || true
|
|
295
|
+
|
|
296
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
297
|
+
# 🔍 GOLDEN LOOP: RETRIEVE PHASE - Auto-retrieve patterns from ekkOS
|
|
298
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
299
|
+
EKKOS_API_KEY=""
|
|
300
|
+
if [ -f "$HOME/.ekkos/.hookApiKey" ]; then
|
|
301
|
+
EKKOS_API_KEY=$(cat "$HOME/.ekkos/.hookApiKey" 2>/dev/null || echo "")
|
|
302
|
+
elif [ -f "$HOME/.ekkos/config.json" ]; then
|
|
303
|
+
EKKOS_API_KEY=$(jq -r '.hookApiKey // ""' "$HOME/.ekkos/config.json" 2>/dev/null || echo "")
|
|
304
|
+
fi
|
|
305
|
+
|
|
306
|
+
RETRIEVED_PATTERNS=""
|
|
307
|
+
PATTERN_COUNT=0
|
|
308
|
+
RETRIEVED_DIRECTIVES=""
|
|
309
|
+
DIRECTIVE_COUNT=0
|
|
310
|
+
|
|
311
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
312
|
+
# 📦 DIRECTIVE CACHE: Local cache to avoid API calls every turn
|
|
313
|
+
# Only fetch from API if:
|
|
314
|
+
# 1. Cache doesn't exist
|
|
315
|
+
# 2. Cache is >1 hour old
|
|
316
|
+
# 3. Directive-related trigger detected in query
|
|
317
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
318
|
+
DIRECTIVE_CACHE_DIR="$HOME/.ekkos/cache"
|
|
319
|
+
DIRECTIVE_CACHE_FILE="$DIRECTIVE_CACHE_DIR/directives.json"
|
|
320
|
+
DIRECTIVE_CACHE_TTL=3600 # 1 hour in seconds
|
|
321
|
+
mkdir -p "$DIRECTIVE_CACHE_DIR" 2>/dev/null || true
|
|
322
|
+
|
|
323
|
+
# Check if we need to refresh directive cache
|
|
324
|
+
DIRECTIVE_CACHE_VALID=false
|
|
325
|
+
DIRECTIVE_TRIGGER_DETECTED=false
|
|
326
|
+
|
|
327
|
+
# Smart detection: Check if query mentions directive-related keywords
|
|
328
|
+
if echo "$QUERY_LOWER" | grep -qE '(always |never |i prefer|i like |dont |don.t |avoid |remember that |from now on|directive|preference)'; then
|
|
329
|
+
DIRECTIVE_TRIGGER_DETECTED=true
|
|
330
|
+
fi
|
|
331
|
+
|
|
332
|
+
if [ -f "$DIRECTIVE_CACHE_FILE" ]; then
|
|
333
|
+
CACHE_TIMESTAMP=$(jq -r '.cached_at // 0' "$DIRECTIVE_CACHE_FILE" 2>/dev/null || echo "0")
|
|
334
|
+
CURRENT_TIMESTAMP=$(date +%s)
|
|
335
|
+
CACHE_AGE=$((CURRENT_TIMESTAMP - CACHE_TIMESTAMP))
|
|
336
|
+
|
|
337
|
+
# Cache is valid if <1 hour old AND no directive trigger detected
|
|
338
|
+
if [ "$CACHE_AGE" -lt "$DIRECTIVE_CACHE_TTL" ] && [ "$DIRECTIVE_TRIGGER_DETECTED" = "false" ]; then
|
|
339
|
+
DIRECTIVE_CACHE_VALID=true
|
|
340
|
+
fi
|
|
341
|
+
fi
|
|
342
|
+
|
|
343
|
+
# Decide whether to inject directives this turn
|
|
344
|
+
# SMART INJECTION: Only on Turn 1, post-clear, or directive trigger
|
|
345
|
+
SHOULD_INJECT_DIRECTIVES=false
|
|
346
|
+
if [ "$TURN_NUMBER" -eq 1 ] || [ "$POST_CLEAR_DETECTED" = "true" ] || [ "$DIRECTIVE_TRIGGER_DETECTED" = "true" ]; then
|
|
347
|
+
SHOULD_INJECT_DIRECTIVES=true
|
|
348
|
+
fi
|
|
349
|
+
|
|
350
|
+
if [ -n "$EKKOS_API_KEY" ] && [ -n "$USER_QUERY" ]; then
|
|
351
|
+
# Update phase to RETRIEVE
|
|
352
|
+
jq -n \
|
|
353
|
+
--arg phase "retrieve" \
|
|
354
|
+
--argjson turn "$TURN_NUMBER" \
|
|
355
|
+
--arg session "$SESSION_ID" \
|
|
356
|
+
--arg timestamp "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
357
|
+
'{
|
|
358
|
+
phase: $phase,
|
|
359
|
+
turn: $turn,
|
|
360
|
+
session: $session,
|
|
361
|
+
timestamp: $timestamp,
|
|
362
|
+
stats: {
|
|
363
|
+
retrieved: 0,
|
|
364
|
+
applied: 0,
|
|
365
|
+
forged: 0
|
|
366
|
+
}
|
|
367
|
+
}' > "$GOLDEN_LOOP_FILE" 2>/dev/null || true
|
|
368
|
+
|
|
369
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
370
|
+
# PATTERN RETRIEVAL: Always search patterns (they're query-specific)
|
|
371
|
+
# DIRECTIVE RETRIEVAL: Only if cache is invalid or trigger detected
|
|
372
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
373
|
+
|
|
374
|
+
# Build sources array - always include patterns, conditionally include directives
|
|
375
|
+
if [ "$DIRECTIVE_CACHE_VALID" = "true" ]; then
|
|
376
|
+
SEARCH_SOURCES='["patterns"]'
|
|
377
|
+
else
|
|
378
|
+
SEARCH_SOURCES='["patterns", "directives"]'
|
|
379
|
+
fi
|
|
380
|
+
|
|
381
|
+
# Call ekkOS MCP gateway
|
|
382
|
+
SEARCH_RESPONSE=$(curl -s -X POST "https://api.ekkos.dev/api/v1/mcp/call" \
|
|
383
|
+
-H "Authorization: Bearer $EKKOS_API_KEY" \
|
|
384
|
+
-H "Content-Type: application/json" \
|
|
385
|
+
--max-time 2 \
|
|
386
|
+
-d "{\"tool\": \"ekkOS_Search\", \"arguments\": {\"query\": $(echo "$USER_QUERY" | jq -Rs .), \"limit\": 5, \"sources\": $SEARCH_SOURCES}}" 2>/dev/null || echo '{"result": {"results": {"patterns": [], "directives": []}}}')
|
|
387
|
+
|
|
388
|
+
# Count patterns retrieved (MCP response: .result.results.patterns)
|
|
389
|
+
PATTERN_COUNT=$(echo "$SEARCH_RESPONSE" | jq -r '.result.results.patterns | length' 2>/dev/null || echo "0")
|
|
390
|
+
|
|
391
|
+
# Update golden loop with retrieved count
|
|
392
|
+
if [ "$PATTERN_COUNT" -gt 0 ]; then
|
|
393
|
+
jq -n \
|
|
394
|
+
--arg phase "inject" \
|
|
395
|
+
--argjson turn "$TURN_NUMBER" \
|
|
396
|
+
--arg session "$SESSION_ID" \
|
|
397
|
+
--arg timestamp "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
398
|
+
--argjson retrieved "$PATTERN_COUNT" \
|
|
399
|
+
'{
|
|
400
|
+
phase: $phase,
|
|
401
|
+
turn: $turn,
|
|
402
|
+
session: $session,
|
|
403
|
+
timestamp: $timestamp,
|
|
404
|
+
stats: {
|
|
405
|
+
retrieved: $retrieved,
|
|
406
|
+
applied: 0,
|
|
407
|
+
forged: 0
|
|
408
|
+
}
|
|
409
|
+
}' > "$GOLDEN_LOOP_FILE" 2>/dev/null || true
|
|
410
|
+
|
|
411
|
+
# Format patterns for injection (MCP response: .result.results.patterns)
|
|
412
|
+
RETRIEVED_PATTERNS=$(echo "$SEARCH_RESPONSE" | jq -r '
|
|
413
|
+
.result.results.patterns[]? |
|
|
414
|
+
"**\(.title)**\n\(.problem // .guidance // "")\n\n## Solution\n\(.solution // .content // "")\n\nSuccess Rate: \((.success_rate // 0) * 100)%\nApplied: \(.applied_count // 0) times\n"
|
|
415
|
+
' 2>/dev/null || echo "")
|
|
416
|
+
fi
|
|
417
|
+
|
|
418
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
419
|
+
# DIRECTIVE HANDLING: Use cache if valid, otherwise process from response
|
|
420
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
421
|
+
if [ "$DIRECTIVE_CACHE_VALID" = "true" ]; then
|
|
422
|
+
# Load directives from cache
|
|
423
|
+
DIRECTIVE_COUNT=$(jq -r '.count // 0' "$DIRECTIVE_CACHE_FILE" 2>/dev/null || echo "0")
|
|
424
|
+
RETRIEVED_DIRECTIVES=$(jq -r '.formatted // ""' "$DIRECTIVE_CACHE_FILE" 2>/dev/null || echo "")
|
|
425
|
+
else
|
|
426
|
+
# Extract and format DIRECTIVES from API response
|
|
427
|
+
DIRECTIVE_COUNT=$(echo "$SEARCH_RESPONSE" | jq -r '.result.results.directives | length' 2>/dev/null || echo "0")
|
|
428
|
+
|
|
429
|
+
if [ "$DIRECTIVE_COUNT" -gt 0 ]; then
|
|
430
|
+
# Group directives by type for clean display
|
|
431
|
+
MUST_DIRECTIVES=$(echo "$SEARCH_RESPONSE" | jq -r '.result.results.directives[] | select(.type == "MUST") | " • \(.rule)"' 2>/dev/null || echo "")
|
|
432
|
+
NEVER_DIRECTIVES=$(echo "$SEARCH_RESPONSE" | jq -r '.result.results.directives[] | select(.type == "NEVER") | " • \(.rule)"' 2>/dev/null || echo "")
|
|
433
|
+
PREFER_DIRECTIVES=$(echo "$SEARCH_RESPONSE" | jq -r '.result.results.directives[] | select(.type == "PREFER") | " • \(.rule)"' 2>/dev/null || echo "")
|
|
434
|
+
AVOID_DIRECTIVES=$(echo "$SEARCH_RESPONSE" | jq -r '.result.results.directives[] | select(.type == "AVOID") | " • \(.rule)"' 2>/dev/null || echo "")
|
|
435
|
+
|
|
436
|
+
# Build directive section
|
|
437
|
+
if [ -n "$MUST_DIRECTIVES" ] || [ -n "$NEVER_DIRECTIVES" ] || [ -n "$PREFER_DIRECTIVES" ] || [ -n "$AVOID_DIRECTIVES" ]; then
|
|
438
|
+
RETRIEVED_DIRECTIVES="🔴 USER DIRECTIVES (FOLLOW THESE):"
|
|
439
|
+
[ -n "$MUST_DIRECTIVES" ] && RETRIEVED_DIRECTIVES="$RETRIEVED_DIRECTIVES
|
|
440
|
+
|
|
441
|
+
MUST:
|
|
442
|
+
$MUST_DIRECTIVES"
|
|
443
|
+
[ -n "$NEVER_DIRECTIVES" ] && RETRIEVED_DIRECTIVES="$RETRIEVED_DIRECTIVES
|
|
444
|
+
|
|
445
|
+
NEVER:
|
|
446
|
+
$NEVER_DIRECTIVES"
|
|
447
|
+
[ -n "$PREFER_DIRECTIVES" ] && RETRIEVED_DIRECTIVES="$RETRIEVED_DIRECTIVES
|
|
448
|
+
|
|
449
|
+
PREFER:
|
|
450
|
+
$PREFER_DIRECTIVES"
|
|
451
|
+
[ -n "$AVOID_DIRECTIVES" ] && RETRIEVED_DIRECTIVES="$RETRIEVED_DIRECTIVES
|
|
452
|
+
|
|
453
|
+
AVOID:
|
|
454
|
+
$AVOID_DIRECTIVES"
|
|
455
|
+
fi
|
|
456
|
+
|
|
457
|
+
# Save to cache for future turns
|
|
458
|
+
jq -n \
|
|
459
|
+
--argjson count "$DIRECTIVE_COUNT" \
|
|
460
|
+
--arg formatted "$RETRIEVED_DIRECTIVES" \
|
|
461
|
+
--argjson cached_at "$(date +%s)" \
|
|
462
|
+
'{
|
|
463
|
+
count: $count,
|
|
464
|
+
formatted: $formatted,
|
|
465
|
+
cached_at: $cached_at
|
|
466
|
+
}' > "$DIRECTIVE_CACHE_FILE" 2>/dev/null || true
|
|
467
|
+
fi
|
|
468
|
+
fi
|
|
469
|
+
fi
|
|
470
|
+
|
|
471
|
+
# Context tracking removed - Claude Code handles its own context management
|
|
472
|
+
|
|
473
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
474
|
+
# COLORS
|
|
475
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
476
|
+
CYAN='\033[0;36m'
|
|
477
|
+
GREEN='\033[0;32m'
|
|
478
|
+
YELLOW='\033[1;33m'
|
|
479
|
+
MAGENTA='\033[0;35m'
|
|
480
|
+
DIM='\033[2m'
|
|
481
|
+
BOLD='\033[1m'
|
|
482
|
+
RESET='\033[0m'
|
|
483
|
+
|
|
484
|
+
CURRENT_TIME=$(date "+%Y-%m-%d %I:%M:%S %p %Z")
|
|
485
|
+
|
|
486
|
+
# Generate session name (arrays and uuid_to_words defined at top of file)
|
|
487
|
+
SESSION_NAME=""
|
|
488
|
+
if [ -n "$SESSION_ID" ] && [ "$SESSION_ID" != "unknown" ] && [ "$SESSION_ID" != "null" ]; then
|
|
489
|
+
SESSION_NAME=$(uuid_to_words "$SESSION_ID")
|
|
490
|
+
fi
|
|
491
|
+
|
|
492
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
493
|
+
# "/continue" COMMAND: Delegated to Skill system (DO NOT INTERCEPT)
|
|
494
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
495
|
+
# REMOVED: Hook used to intercept /continue and do simple restoration
|
|
496
|
+
# NOW: Let /continue Skill handle it - supports session names + intelligent narrative
|
|
497
|
+
#
|
|
498
|
+
# Why this changed:
|
|
499
|
+
# - Hook was ignoring session name argument (always used "current")
|
|
500
|
+
# - Hook couldn't provide intelligent narrative briefing
|
|
501
|
+
# - Skill system now has proper name→UUID resolution in API
|
|
502
|
+
#
|
|
503
|
+
# OLD BEHAVIOR (removed):
|
|
504
|
+
# - Hook caught /continue → API call with "current" → exit
|
|
505
|
+
# NEW BEHAVIOR:
|
|
506
|
+
# - /continue groovy-cactus → Skill system → API with session name → intelligent briefing
|
|
507
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
508
|
+
|
|
509
|
+
# Note: Session name is shown in status line for easy reference:
|
|
510
|
+
# Example: "🧠 ekkOS Memory | Turn 42 | groovy-cactus | 2026-01-12 09:40 AM EST"
|
|
511
|
+
|
|
512
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
513
|
+
# AUTO-RESTORE REMOVED: Manual /continue only (saves 79% token burn!)
|
|
514
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
515
|
+
# WHY REMOVED:
|
|
516
|
+
# - Auto-restore burns 5,000 tokens per turn (250K tokens over 50 turns)
|
|
517
|
+
# - Manual /continue: 2,000 tokens once + clean slate (52K total = 79% savings!)
|
|
518
|
+
# - Manual /continue is 10x more powerful (Bash + multi-source + narrative)
|
|
519
|
+
# - User has control (can choose session, can skip if starting fresh)
|
|
520
|
+
# - Explicit > implicit (user knows exactly what's happening)
|
|
521
|
+
#
|
|
522
|
+
# OLD BEHAVIOR (removed):
|
|
523
|
+
# - Compaction detection → auto-inject 10 turns
|
|
524
|
+
# - Post-clear detection → auto-inject 10 turns
|
|
525
|
+
# NEW BEHAVIOR:
|
|
526
|
+
# - User types: /continue groovy-cactus
|
|
527
|
+
# - Skill runs with full Bash power + intelligent narrative
|
|
528
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
529
|
+
|
|
530
|
+
# Simple status line - no context warnings, Claude handles its own context
|
|
531
|
+
echo -e "${CYAN}${BOLD}🧠 ekkOS Memory${RESET} ${DIM}| Turn ${TURN_NUMBER} | ${SESSION_NAME} | ${CURRENT_TIME}${RESET}"
|
|
532
|
+
|
|
533
|
+
# Output skill reminder if detected
|
|
534
|
+
if [ -n "$SKILL_REMINDER" ]; then
|
|
535
|
+
echo ""
|
|
536
|
+
echo -e "${MAGENTA}${BOLD}$SKILL_REMINDER${RESET}"
|
|
537
|
+
fi
|
|
538
|
+
|
|
539
|
+
# 💉 GOLDEN LOOP: INJECT PHASE - Inject directives FIRST (highest priority)
|
|
540
|
+
# SMART INJECTION: Only on Turn 1, post-clear, or directive trigger
|
|
541
|
+
if [ "$SHOULD_INJECT_DIRECTIVES" = "true" ] && [ -n "$RETRIEVED_DIRECTIVES" ] && [ "$DIRECTIVE_COUNT" -gt 0 ]; then
|
|
542
|
+
echo ""
|
|
543
|
+
echo "<system-reminder>"
|
|
544
|
+
echo -e "$RETRIEVED_DIRECTIVES"
|
|
545
|
+
echo "</system-reminder>"
|
|
546
|
+
fi
|
|
547
|
+
|
|
548
|
+
# 💉 GOLDEN LOOP: INJECT PHASE - Inject retrieved patterns into context
|
|
549
|
+
if [ -n "$RETRIEVED_PATTERNS" ] && [ "$PATTERN_COUNT" -gt 0 ]; then
|
|
550
|
+
echo ""
|
|
551
|
+
echo "<system-reminder>"
|
|
552
|
+
echo "🔍 RETRIEVED PATTERNS FROM ekkOS MEMORY ($PATTERN_COUNT patterns found)"
|
|
553
|
+
echo ""
|
|
554
|
+
echo -e "$RETRIEVED_PATTERNS"
|
|
555
|
+
echo ""
|
|
556
|
+
echo "These patterns were automatically retrieved based on your query. Review and apply relevant solutions."
|
|
557
|
+
echo "</system-reminder>"
|
|
558
|
+
echo ""
|
|
559
|
+
echo "🔴 MANDATORY PATTERN ACKNOWLEDGMENT (PatternGuard):"
|
|
560
|
+
echo "You MUST acknowledge ALL $PATTERN_COUNT patterns above - either SELECT or SKIP each one."
|
|
561
|
+
echo ""
|
|
562
|
+
echo "For patterns you USE:"
|
|
563
|
+
echo "[ekkOS_SELECT]"
|
|
564
|
+
echo "- id: <pattern_id>"
|
|
565
|
+
echo " reason: <1-line why using>"
|
|
566
|
+
echo " confidence: <0.0-1.0>"
|
|
567
|
+
echo "[/ekkOS_SELECT]"
|
|
568
|
+
echo ""
|
|
569
|
+
echo "For patterns NOT relevant:"
|
|
570
|
+
echo "[ekkOS_SKIP]"
|
|
571
|
+
echo "- id: <pattern_id>"
|
|
572
|
+
echo " reason: <1-line why not relevant>"
|
|
573
|
+
echo "[/ekkOS_SKIP]"
|
|
574
|
+
echo ""
|
|
575
|
+
echo "⚡ AUTOMATIC APPLICATION: When pattern matches your task, APPLY IT immediately without asking."
|
|
576
|
+
echo "Track outcome after: ekkOS_Outcome({success: true/false})"
|
|
577
|
+
echo ""
|
|
578
|
+
echo "100% coverage required. This is how the system learns what works."
|
|
579
|
+
fi
|
|
580
|
+
|
|
581
|
+
# Inject footer format reminder (helps Claude remember session name)
|
|
582
|
+
if [ -n "$SESSION_NAME" ] && [ "$SESSION_NAME" != "unknown-session" ]; then
|
|
583
|
+
echo ""
|
|
584
|
+
echo "<footer-format>End responses with: Claude Code ({Model}) · 🧠 **ekkOS_™** · Turn ${TURN_NUMBER} · ${SESSION_NAME} · 📅 ${CURRENT_TIME}</footer-format>"
|
|
585
|
+
fi
|
|
586
|
+
|
|
587
|
+
exit 0
|