@ekkos/cli 0.3.3 → 1.0.1

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 (81) hide show
  1. package/README.md +57 -0
  2. package/dist/agent/daemon.d.ts +27 -0
  3. package/dist/agent/daemon.js +254 -29
  4. package/dist/agent/health-check.d.ts +35 -0
  5. package/dist/agent/health-check.js +243 -0
  6. package/dist/agent/pty-runner.d.ts +1 -0
  7. package/dist/agent/pty-runner.js +6 -1
  8. package/dist/capture/transcript-repair.d.ts +1 -0
  9. package/dist/capture/transcript-repair.js +12 -1
  10. package/dist/commands/agent.d.ts +6 -0
  11. package/dist/commands/agent.js +244 -0
  12. package/dist/commands/dashboard.d.ts +25 -0
  13. package/dist/commands/dashboard.js +1175 -0
  14. package/dist/commands/run.d.ts +3 -0
  15. package/dist/commands/run.js +503 -350
  16. package/dist/commands/setup-remote.js +146 -37
  17. package/dist/commands/swarm-dashboard.d.ts +20 -0
  18. package/dist/commands/swarm-dashboard.js +735 -0
  19. package/dist/commands/swarm-setup.d.ts +10 -0
  20. package/dist/commands/swarm-setup.js +956 -0
  21. package/dist/commands/swarm.d.ts +46 -0
  22. package/dist/commands/swarm.js +441 -0
  23. package/dist/commands/test-claude.d.ts +16 -0
  24. package/dist/commands/test-claude.js +156 -0
  25. package/dist/commands/usage/blocks.d.ts +8 -0
  26. package/dist/commands/usage/blocks.js +60 -0
  27. package/dist/commands/usage/daily.d.ts +9 -0
  28. package/dist/commands/usage/daily.js +96 -0
  29. package/dist/commands/usage/dashboard.d.ts +8 -0
  30. package/dist/commands/usage/dashboard.js +104 -0
  31. package/dist/commands/usage/formatters.d.ts +41 -0
  32. package/dist/commands/usage/formatters.js +147 -0
  33. package/dist/commands/usage/index.d.ts +13 -0
  34. package/dist/commands/usage/index.js +87 -0
  35. package/dist/commands/usage/monthly.d.ts +8 -0
  36. package/dist/commands/usage/monthly.js +66 -0
  37. package/dist/commands/usage/session.d.ts +11 -0
  38. package/dist/commands/usage/session.js +193 -0
  39. package/dist/commands/usage/weekly.d.ts +9 -0
  40. package/dist/commands/usage/weekly.js +61 -0
  41. package/dist/deploy/instructions.d.ts +5 -2
  42. package/dist/deploy/instructions.js +11 -8
  43. package/dist/index.js +256 -20
  44. package/dist/lib/tmux-scrollbar.d.ts +14 -0
  45. package/dist/lib/tmux-scrollbar.js +296 -0
  46. package/dist/lib/usage-parser.d.ts +95 -5
  47. package/dist/lib/usage-parser.js +416 -71
  48. package/dist/utils/log-rotate.d.ts +18 -0
  49. package/dist/utils/log-rotate.js +74 -0
  50. package/dist/utils/platform.d.ts +2 -0
  51. package/dist/utils/platform.js +3 -1
  52. package/dist/utils/session-binding.d.ts +5 -0
  53. package/dist/utils/session-binding.js +46 -0
  54. package/dist/utils/state.js +4 -0
  55. package/dist/utils/verify-remote-terminal.d.ts +10 -0
  56. package/dist/utils/verify-remote-terminal.js +415 -0
  57. package/package.json +16 -11
  58. package/templates/CLAUDE.md +135 -23
  59. package/templates/cursor-hooks/after-agent-response.sh +0 -0
  60. package/templates/cursor-hooks/before-submit-prompt.sh +0 -0
  61. package/templates/cursor-hooks/stop.sh +0 -0
  62. package/templates/ekkos-manifest.json +5 -5
  63. package/templates/hooks/assistant-response.sh +0 -0
  64. package/templates/hooks/lib/contract.sh +43 -31
  65. package/templates/hooks/lib/count-tokens.cjs +86 -0
  66. package/templates/hooks/lib/ekkos-reminders.sh +98 -0
  67. package/templates/hooks/lib/state.sh +53 -1
  68. package/templates/hooks/session-start.sh +0 -0
  69. package/templates/hooks/stop.sh +150 -388
  70. package/templates/hooks/user-prompt-submit.sh +353 -443
  71. package/templates/plan-template.md +0 -0
  72. package/templates/spec-template.md +0 -0
  73. package/templates/windsurf-hooks/README.md +212 -0
  74. package/templates/windsurf-hooks/hooks.json +9 -2
  75. package/templates/windsurf-hooks/install.sh +148 -0
  76. package/templates/windsurf-hooks/lib/contract.sh +2 -0
  77. package/templates/windsurf-hooks/post-cascade-response.sh +251 -0
  78. package/templates/windsurf-hooks/pre-user-prompt.sh +435 -0
  79. package/templates/windsurf-skills/ekkos-memory/SKILL.md +219 -0
  80. package/LICENSE +0 -21
  81. 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