@ekkos/cli 0.2.18 → 1.0.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/README.md +57 -0
- package/dist/agent/daemon.d.ts +27 -0
- package/dist/agent/daemon.js +254 -29
- package/dist/agent/health-check.d.ts +35 -0
- package/dist/agent/health-check.js +243 -0
- package/dist/agent/pty-runner.d.ts +1 -0
- package/dist/agent/pty-runner.js +6 -1
- package/dist/capture/eviction-client.d.ts +139 -0
- package/dist/capture/eviction-client.js +454 -0
- package/dist/capture/index.d.ts +2 -0
- package/dist/capture/index.js +2 -0
- package/dist/capture/jsonl-rewriter.d.ts +96 -0
- package/dist/capture/jsonl-rewriter.js +1369 -0
- package/dist/capture/transcript-repair.d.ts +51 -0
- package/dist/capture/transcript-repair.js +319 -0
- package/dist/commands/agent.d.ts +6 -0
- package/dist/commands/agent.js +244 -0
- package/dist/commands/dashboard.d.ts +25 -0
- package/dist/commands/dashboard.js +1175 -0
- package/dist/commands/doctor.js +23 -1
- package/dist/commands/run.d.ts +5 -0
- package/dist/commands/run.js +1605 -516
- package/dist/commands/setup-remote.js +146 -37
- package/dist/commands/swarm-dashboard.d.ts +20 -0
- package/dist/commands/swarm-dashboard.js +735 -0
- package/dist/commands/swarm-setup.d.ts +10 -0
- package/dist/commands/swarm-setup.js +956 -0
- package/dist/commands/swarm.d.ts +46 -0
- package/dist/commands/swarm.js +441 -0
- package/dist/commands/test-claude.d.ts +16 -0
- package/dist/commands/test-claude.js +156 -0
- package/dist/commands/usage/blocks.d.ts +8 -0
- package/dist/commands/usage/blocks.js +60 -0
- package/dist/commands/usage/daily.d.ts +9 -0
- package/dist/commands/usage/daily.js +96 -0
- package/dist/commands/usage/dashboard.d.ts +8 -0
- package/dist/commands/usage/dashboard.js +104 -0
- package/dist/commands/usage/formatters.d.ts +41 -0
- package/dist/commands/usage/formatters.js +147 -0
- package/dist/commands/usage/index.d.ts +13 -0
- package/dist/commands/usage/index.js +87 -0
- package/dist/commands/usage/monthly.d.ts +8 -0
- package/dist/commands/usage/monthly.js +66 -0
- package/dist/commands/usage/session.d.ts +11 -0
- package/dist/commands/usage/session.js +193 -0
- package/dist/commands/usage/weekly.d.ts +9 -0
- package/dist/commands/usage/weekly.js +61 -0
- package/dist/commands/usage.d.ts +7 -0
- package/dist/commands/usage.js +214 -0
- package/dist/cron/index.d.ts +7 -0
- package/dist/cron/index.js +13 -0
- package/dist/cron/promoter.d.ts +70 -0
- package/dist/cron/promoter.js +403 -0
- package/dist/deploy/instructions.d.ts +5 -2
- package/dist/deploy/instructions.js +11 -8
- package/dist/index.js +262 -5
- package/dist/lib/tmux-scrollbar.d.ts +14 -0
- package/dist/lib/tmux-scrollbar.js +296 -0
- package/dist/lib/usage-monitor.d.ts +47 -0
- package/dist/lib/usage-monitor.js +124 -0
- package/dist/lib/usage-parser.d.ts +162 -0
- package/dist/lib/usage-parser.js +583 -0
- package/dist/restore/RestoreOrchestrator.d.ts +4 -0
- package/dist/restore/RestoreOrchestrator.js +118 -30
- package/dist/utils/log-rotate.d.ts +18 -0
- package/dist/utils/log-rotate.js +74 -0
- package/dist/utils/platform.d.ts +2 -0
- package/dist/utils/platform.js +3 -1
- package/dist/utils/session-binding.d.ts +5 -0
- package/dist/utils/session-binding.js +46 -0
- package/dist/utils/state.js +4 -0
- package/dist/utils/verify-remote-terminal.d.ts +10 -0
- package/dist/utils/verify-remote-terminal.js +415 -0
- package/package.json +9 -2
- package/templates/CLAUDE.md +135 -23
- package/templates/ekkos-manifest.json +5 -5
- package/templates/hooks/lib/contract.sh +43 -31
- package/templates/hooks/lib/count-tokens.cjs +86 -0
- package/templates/hooks/lib/ekkos-reminders.sh +98 -0
- package/templates/hooks/lib/state.sh +53 -1
- package/templates/hooks/stop.sh +150 -388
- package/templates/hooks/user-prompt-submit.sh +353 -443
- package/templates/windsurf-hooks/README.md +212 -0
- package/templates/windsurf-hooks/hooks.json +9 -2
- package/templates/windsurf-hooks/install.sh +148 -0
- package/templates/windsurf-hooks/lib/contract.sh +2 -0
- package/templates/windsurf-hooks/post-cascade-response.sh +251 -0
- package/templates/windsurf-hooks/pre-user-prompt.sh +435 -0
- package/templates/windsurf-skills/ekkos-memory/SKILL.md +219 -0
- package/templates/agents/README.md +0 -182
- package/templates/agents/code-reviewer.md +0 -166
- package/templates/agents/debug-detective.md +0 -169
- package/templates/agents/ekkOS_Vercel.md +0 -99
- package/templates/agents/extension-manager.md +0 -229
- package/templates/agents/git-companion.md +0 -185
- package/templates/agents/github-test-agent.md +0 -321
- package/templates/agents/railway-manager.md +0 -215
- package/templates/windsurf-hooks/before-submit-prompt.sh +0 -238
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
3
|
-
# ekkOS_ Hook: BeforeSubmitPrompt (Windsurf Cascade) - RETRIEVE + INJECT + CONTRACT
|
|
4
|
-
#
|
|
5
|
-
# ARCHITECTURE: Dumb Hook, Smart Backend
|
|
6
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
7
|
-
# This hook runs BEFORE the prompt is sent to the AI.
|
|
8
|
-
# It is THE CANONICAL retrieval path for Windsurf.
|
|
9
|
-
#
|
|
10
|
-
# GOLDEN LOOP ENFORCEMENT:
|
|
11
|
-
# - Writes turn contract as evidence of retrieval
|
|
12
|
-
# - In STRICT mode, returns continue=false to block turn
|
|
13
|
-
# - Lists pattern IDs explicitly for PatternGuard validation
|
|
14
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
15
|
-
|
|
16
|
-
set +e # Don't exit on errors - be bulletproof
|
|
17
|
-
|
|
18
|
-
# Get project root
|
|
19
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
20
|
-
PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
|
21
|
-
STATE_DIR="$PROJECT_ROOT/.windsurf/state"
|
|
22
|
-
mkdir -p "$STATE_DIR" 2>/dev/null || true
|
|
23
|
-
|
|
24
|
-
# Load turn contract library
|
|
25
|
-
if [ -f "$SCRIPT_DIR/lib/contract.sh" ]; then
|
|
26
|
-
source "$SCRIPT_DIR/lib/contract.sh" 2>/dev/null || true
|
|
27
|
-
fi
|
|
28
|
-
|
|
29
|
-
# Fallback functions if library didn't load
|
|
30
|
-
if ! command -v write_turn_contract >/dev/null 2>&1; then
|
|
31
|
-
write_turn_contract() { return 0; }
|
|
32
|
-
fi
|
|
33
|
-
if ! command -v generate_query_hash >/dev/null 2>&1; then
|
|
34
|
-
generate_query_hash() { echo "$(date +%s)"; }
|
|
35
|
-
fi
|
|
36
|
-
if ! command -v is_strict_mode >/dev/null 2>&1; then
|
|
37
|
-
is_strict_mode() { [ "${EKKOS_STRICT:-0}" = "1" ]; }
|
|
38
|
-
fi
|
|
39
|
-
if ! command -v get_strict_blocker_message >/dev/null 2>&1; then
|
|
40
|
-
get_strict_blocker_message() { echo "⛔ EKKOS_STRICT: Retrieval failed - DO NOT ANSWER"; }
|
|
41
|
-
fi
|
|
42
|
-
|
|
43
|
-
# Read JSON input from stdin
|
|
44
|
-
INPUT=$(cat)
|
|
45
|
-
|
|
46
|
-
# Extract prompt text and session info
|
|
47
|
-
PROMPT_TEXT=$(echo "$INPUT" | jq -r '.prompt // .text // ""' 2>/dev/null || echo "")
|
|
48
|
-
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // .conversation_id // ""' 2>/dev/null || echo "")
|
|
49
|
-
MODEL_INFO=$(echo "$INPUT" | jq -r '.model // ""' 2>/dev/null || echo "")
|
|
50
|
-
|
|
51
|
-
# Generate session ID if not provided
|
|
52
|
-
if [ -z "$SESSION_ID" ] || [ "$SESSION_ID" = "null" ]; then
|
|
53
|
-
SESSION_ID="windsurf-$(date +%s)-$$"
|
|
54
|
-
fi
|
|
55
|
-
|
|
56
|
-
# Skip if empty
|
|
57
|
-
if [ -z "$PROMPT_TEXT" ] || [ "$PROMPT_TEXT" = "null" ]; then
|
|
58
|
-
echo '{"continue": true}'
|
|
59
|
-
exit 0
|
|
60
|
-
fi
|
|
61
|
-
|
|
62
|
-
# Generate query hash for contract
|
|
63
|
-
QUERY_HASH=$(generate_query_hash "$PROMPT_TEXT")
|
|
64
|
-
|
|
65
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
66
|
-
# Load auth token - PORTABLE: Check 3 sources in priority order
|
|
67
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
68
|
-
EKKOS_CONFIG="$HOME/.ekkos/config.json"
|
|
69
|
-
AUTH_TOKEN=""
|
|
70
|
-
USER_ID=""
|
|
71
|
-
|
|
72
|
-
# 1. First try ~/.ekkos/config.json (set by VS Code extension - most portable)
|
|
73
|
-
# Prefer hookApiKey (scoped key for hooks) over apiKey (legacy)
|
|
74
|
-
if [ -f "$EKKOS_CONFIG" ]; then
|
|
75
|
-
AUTH_TOKEN=$(jq -r '.hookApiKey // .apiKey // ""' "$EKKOS_CONFIG" 2>/dev/null || echo "")
|
|
76
|
-
USER_ID=$(jq -r '.userId // ""' "$EKKOS_CONFIG" 2>/dev/null || echo "")
|
|
77
|
-
fi
|
|
78
|
-
|
|
79
|
-
# 2. Then try project .env.local (for developers)
|
|
80
|
-
if [ -z "$AUTH_TOKEN" ] && [ -f "$PROJECT_ROOT/.env.local" ]; then
|
|
81
|
-
AUTH_TOKEN=$(grep -E "^SUPABASE_SECRET_KEY=" "$PROJECT_ROOT/.env.local" | cut -d'=' -f2- | tr -d '"' | tr -d "'" | tr -d '\r')
|
|
82
|
-
fi
|
|
83
|
-
|
|
84
|
-
# 3. Finally try environment variable
|
|
85
|
-
if [ -z "$AUTH_TOKEN" ]; then
|
|
86
|
-
AUTH_TOKEN="${SUPABASE_SECRET_KEY:-}"
|
|
87
|
-
fi
|
|
88
|
-
|
|
89
|
-
# Track retrieval status
|
|
90
|
-
RETRIEVAL_OK="false"
|
|
91
|
-
RETRIEVED_PATTERN_IDS=""
|
|
92
|
-
RETRIEVED_DIRECTIVE_IDS=""
|
|
93
|
-
|
|
94
|
-
# Skip if no auth
|
|
95
|
-
if [ -z "$AUTH_TOKEN" ]; then
|
|
96
|
-
# STRICT MODE: Block turn if no auth
|
|
97
|
-
if is_strict_mode; then
|
|
98
|
-
BLOCKER_MSG=$(get_strict_blocker_message)
|
|
99
|
-
write_turn_contract "$SESSION_ID" "false" "windsurf" "" "" "$QUERY_HASH" "$PROJECT_ROOT"
|
|
100
|
-
echo "{\"continue\": false, \"user_message\": $(echo "$BLOCKER_MSG" | jq -R -s .)}"
|
|
101
|
-
exit 0
|
|
102
|
-
fi
|
|
103
|
-
|
|
104
|
-
write_turn_contract "$SESSION_ID" "false" "windsurf" "" "" "$QUERY_HASH" "$PROJECT_ROOT"
|
|
105
|
-
echo '{"continue": true, "user_message": "[ekkOS] No auth token. Run ekkOS: Connect in VS Code."}'
|
|
106
|
-
exit 0
|
|
107
|
-
fi
|
|
108
|
-
|
|
109
|
-
# Cloud API
|
|
110
|
-
MEMORY_API_URL="https://mcp.ekkos.dev"
|
|
111
|
-
|
|
112
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
113
|
-
# [ekkOS_RETRIEVE] Search memory for patterns (all 8 queryable layers)
|
|
114
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
115
|
-
JSON_PAYLOAD=$(jq -n \
|
|
116
|
-
--arg query "$PROMPT_TEXT" \
|
|
117
|
-
--arg user_id "${USER_ID:-system}" \
|
|
118
|
-
--arg session "windsurf-$SESSION_ID" \
|
|
119
|
-
'{
|
|
120
|
-
query: $query,
|
|
121
|
-
user_id: $user_id,
|
|
122
|
-
session_id: $session,
|
|
123
|
-
max_per_layer: 5,
|
|
124
|
-
include_layers: ["working", "episodic", "semantic", "patterns", "procedural", "collective", "codebase", "directives"],
|
|
125
|
-
metadata: { source: "windsurf-cascade-hook" }
|
|
126
|
-
}' 2>/dev/null || echo '{}')
|
|
127
|
-
|
|
128
|
-
API_RESPONSE=$(curl -s -X POST "$MEMORY_API_URL/api/v1/context/retrieve" \
|
|
129
|
-
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
130
|
-
-H "Content-Type: application/json" \
|
|
131
|
-
-d "$JSON_PAYLOAD" \
|
|
132
|
-
--connect-timeout 3 \
|
|
133
|
-
--max-time 5 2>/dev/null || echo '{"error":"timeout"}')
|
|
134
|
-
|
|
135
|
-
# Check if retrieval succeeded
|
|
136
|
-
if echo "$API_RESPONSE" | jq -e '.layers' >/dev/null 2>&1; then
|
|
137
|
-
RETRIEVAL_OK="true"
|
|
138
|
-
else
|
|
139
|
-
# STRICT MODE: Block turn if retrieval failed
|
|
140
|
-
if is_strict_mode; then
|
|
141
|
-
BLOCKER_MSG=$(get_strict_blocker_message)
|
|
142
|
-
write_turn_contract "$SESSION_ID" "false" "windsurf" "" "" "$QUERY_HASH" "$PROJECT_ROOT"
|
|
143
|
-
echo "{\"continue\": false, \"user_message\": $(echo "$BLOCKER_MSG" | jq -R -s .)}"
|
|
144
|
-
exit 0
|
|
145
|
-
fi
|
|
146
|
-
|
|
147
|
-
API_RESPONSE='{"error":"timeout","formatted_context":"","layers":{"patterns":[],"directives":[]}}'
|
|
148
|
-
fi
|
|
149
|
-
|
|
150
|
-
# Extract counts
|
|
151
|
-
PATTERN_COUNT=$(echo "$API_RESPONSE" | jq '.layers.patterns // [] | length' 2>/dev/null || echo "0")
|
|
152
|
-
DIRECTIVE_COUNT=$(echo "$API_RESPONSE" | jq '.layers.directives // [] | length' 2>/dev/null || echo "0")
|
|
153
|
-
TOTAL_COUNT=$((PATTERN_COUNT + DIRECTIVE_COUNT))
|
|
154
|
-
|
|
155
|
-
# Extract pattern and directive IDs for turn contract
|
|
156
|
-
RETRIEVED_PATTERN_IDS=$(echo "$API_RESPONSE" | jq -r '.layers.patterns // [] | map(.pattern_id // .id) | join(",")' 2>/dev/null || echo "")
|
|
157
|
-
RETRIEVED_DIRECTIVE_IDS=$(echo "$API_RESPONSE" | jq -r '.layers.directives // [] | map(.directive_id // .id) | join(",")' 2>/dev/null || echo "")
|
|
158
|
-
|
|
159
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
160
|
-
# [ekkOS_CONTRACT] Write turn contract as evidence of retrieval
|
|
161
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
162
|
-
write_turn_contract "$SESSION_ID" "$RETRIEVAL_OK" "windsurf" "$RETRIEVED_PATTERN_IDS" "$RETRIEVED_DIRECTIVE_IDS" "$QUERY_HASH" "$PROJECT_ROOT"
|
|
163
|
-
|
|
164
|
-
# Save session ID to state file
|
|
165
|
-
echo "$SESSION_ID" > "$STATE_DIR/current_session_id.txt" 2>/dev/null || true
|
|
166
|
-
|
|
167
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
168
|
-
# [ekkOS_INJECT] Build user message with patterns
|
|
169
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
170
|
-
if [ "$PATTERN_COUNT" -gt 0 ]; then
|
|
171
|
-
# Get formatted context
|
|
172
|
-
FORMATTED=$(echo "$API_RESPONSE" | jq -r '.formatted_context // ""' 2>/dev/null)
|
|
173
|
-
|
|
174
|
-
# Get pattern IDs for PatternGuard
|
|
175
|
-
PATTERN_ID_LIST=$(echo "$API_RESPONSE" | jq -r '.layers.patterns[:5][] | .pattern_id // .id' 2>/dev/null || echo "")
|
|
176
|
-
|
|
177
|
-
if [ -n "$FORMATTED" ] && [ "$FORMATTED" != "null" ]; then
|
|
178
|
-
MESSAGE="━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
179
|
-
🧠 ekkOS™ Memory Substrate
|
|
180
|
-
✓ $PATTERN_COUNT patterns loaded from memory
|
|
181
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
182
|
-
|
|
183
|
-
$FORMATTED
|
|
184
|
-
|
|
185
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
186
|
-
⚠️ PATTERNGUARD REQUIRED
|
|
187
|
-
|
|
188
|
-
You MUST acknowledge ALL $PATTERN_COUNT pattern(s) above.
|
|
189
|
-
|
|
190
|
-
Pattern IDs to acknowledge:
|
|
191
|
-
$PATTERN_ID_LIST
|
|
192
|
-
|
|
193
|
-
For patterns you USE:
|
|
194
|
-
[ekkOS_SELECT]
|
|
195
|
-
- id: <pattern-uuid>
|
|
196
|
-
reason: <why using>
|
|
197
|
-
confidence: <0.0-1.0>
|
|
198
|
-
[/ekkOS_SELECT]
|
|
199
|
-
|
|
200
|
-
For patterns you DO NOT use:
|
|
201
|
-
[ekkOS_SKIP]
|
|
202
|
-
- id: <pattern-uuid>
|
|
203
|
-
reason: <why not relevant>
|
|
204
|
-
[/ekkOS_SKIP]
|
|
205
|
-
|
|
206
|
-
Coverage MUST be 100% (all IDs acknowledged).
|
|
207
|
-
|
|
208
|
-
RESPONSE FORMAT: End with:
|
|
209
|
-
🧠 **ekkOS_™** · 📅 YYYY-MM-DD H:MM AM/PM TZ
|
|
210
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
211
|
-
else
|
|
212
|
-
# Fallback: minimal injection
|
|
213
|
-
MESSAGE="━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
214
|
-
🧠 ekkOS™: $PATTERN_COUNT patterns found
|
|
215
|
-
|
|
216
|
-
Pattern IDs to acknowledge with [ekkOS_SELECT] or [ekkOS_SKIP]:
|
|
217
|
-
$PATTERN_ID_LIST
|
|
218
|
-
|
|
219
|
-
End response with: 🧠 **ekkOS_™** · 📅 YYYY-MM-DD
|
|
220
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
221
|
-
fi
|
|
222
|
-
|
|
223
|
-
# Save patterns for capture
|
|
224
|
-
echo "$API_RESPONSE" | jq '.layers.patterns // []' > "$STATE_DIR/patterns-${SESSION_ID}.json" 2>/dev/null || true
|
|
225
|
-
|
|
226
|
-
echo "{\"continue\": true, \"user_message\": $(echo "$MESSAGE" | jq -R -s .)}" | jq -c .
|
|
227
|
-
else
|
|
228
|
-
# No patterns - still write contract and remind about footer
|
|
229
|
-
MESSAGE="━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
230
|
-
🧠 ekkOS™: No patterns found (new territory)
|
|
231
|
-
|
|
232
|
-
End response with: 🧠 **ekkOS_™** · 📅 YYYY-MM-DD
|
|
233
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
234
|
-
|
|
235
|
-
echo "{\"continue\": true, \"user_message\": $(echo "$MESSAGE" | jq -R -s .)}" | jq -c .
|
|
236
|
-
fi
|
|
237
|
-
|
|
238
|
-
exit 0
|