@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,47 @@
|
|
|
1
|
+
# /continue
|
|
2
|
+
|
|
3
|
+
Restore your last 5 turns after running `/clear`.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
/clear # First: free up context
|
|
9
|
+
/continue # Then: restore last 5 turns
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## What Happens
|
|
13
|
+
|
|
14
|
+
1. Hook detects `/continue`
|
|
15
|
+
2. Fetches last 5 turns from ekkOS API
|
|
16
|
+
3. Injects them as context
|
|
17
|
+
4. Claude continues seamlessly
|
|
18
|
+
|
|
19
|
+
## Why This Exists
|
|
20
|
+
|
|
21
|
+
When context gets full (90%+), you need to `/clear` but don't want to lose your work. This command restores just enough context (5 turns) to continue working without re-explaining everything.
|
|
22
|
+
|
|
23
|
+
## The Flow
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
Work normally until context ~90%
|
|
27
|
+
↓
|
|
28
|
+
Run: /clear (frees context)
|
|
29
|
+
↓
|
|
30
|
+
Run: /continue (restores 5 turns)
|
|
31
|
+
↓
|
|
32
|
+
Keep working
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Example
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
[Context at 92%]
|
|
39
|
+
|
|
40
|
+
You: /clear
|
|
41
|
+
Claude: Context cleared.
|
|
42
|
+
|
|
43
|
+
You: /continue
|
|
44
|
+
Hook: ✓ Session continued (5 turns restored)
|
|
45
|
+
|
|
46
|
+
Claude: ✓ **Continuing** - We were working on the /continue command...
|
|
47
|
+
```
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
3
|
+
# ekkOS_ Hook: AfterAgentResponse (Cursor Agent Mode)
|
|
4
|
+
#
|
|
5
|
+
# Captures agent responses for turn storage in ekkOS L2 (episodic memory)
|
|
6
|
+
# This enables Time Machine to work with Cursor Agent conversations
|
|
7
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
8
|
+
|
|
9
|
+
set +e
|
|
10
|
+
|
|
11
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
|
+
PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
|
13
|
+
STATE_DIR="$PROJECT_ROOT/.cursor/state"
|
|
14
|
+
mkdir -p "$STATE_DIR" 2>/dev/null || true
|
|
15
|
+
|
|
16
|
+
# Read JSON input
|
|
17
|
+
INPUT=$(cat)
|
|
18
|
+
|
|
19
|
+
# Extract response text
|
|
20
|
+
RESPONSE_TEXT=$(echo "$INPUT" | jq -r '.text // ""' 2>/dev/null || echo "")
|
|
21
|
+
|
|
22
|
+
# Skip if empty
|
|
23
|
+
if [ -z "$RESPONSE_TEXT" ] || [ "$RESPONSE_TEXT" = "null" ]; then
|
|
24
|
+
exit 0
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
28
|
+
# Load auth
|
|
29
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
30
|
+
EKKOS_CONFIG="$HOME/.ekkos/config.json"
|
|
31
|
+
AUTH_TOKEN=""
|
|
32
|
+
USER_ID=""
|
|
33
|
+
|
|
34
|
+
if [ -f "$EKKOS_CONFIG" ]; then
|
|
35
|
+
AUTH_TOKEN=$(jq -r '.hookApiKey // .apiKey // ""' "$EKKOS_CONFIG" 2>/dev/null || echo "")
|
|
36
|
+
USER_ID=$(jq -r '.userId // ""' "$EKKOS_CONFIG" 2>/dev/null || echo "")
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
if [ -z "$AUTH_TOKEN" ] && [ -f "$PROJECT_ROOT/.env.local" ]; then
|
|
40
|
+
AUTH_TOKEN=$(grep -E "^SUPABASE_SECRET_KEY=" "$PROJECT_ROOT/.env.local" | cut -d'=' -f2- | tr -d '"' | tr -d "'" | tr -d '\r')
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
[ -z "$AUTH_TOKEN" ] && exit 0
|
|
44
|
+
|
|
45
|
+
MEMORY_API_URL="https://mcp.ekkos.dev"
|
|
46
|
+
|
|
47
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
48
|
+
# Load session state
|
|
49
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
50
|
+
SESSION_ID=""
|
|
51
|
+
LAST_QUERY=""
|
|
52
|
+
|
|
53
|
+
if [ -f "$STATE_DIR/current_session_id.txt" ]; then
|
|
54
|
+
SESSION_ID=$(cat "$STATE_DIR/current_session_id.txt" 2>/dev/null || echo "")
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
if [ -f "$STATE_DIR/last_query.txt" ]; then
|
|
58
|
+
LAST_QUERY=$(cat "$STATE_DIR/last_query.txt" 2>/dev/null || echo "")
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# Generate session ID if missing
|
|
62
|
+
if [ -z "$SESSION_ID" ]; then
|
|
63
|
+
SESSION_ID="cursor-agent-$(date +%s)-$$"
|
|
64
|
+
echo "$SESSION_ID" > "$STATE_DIR/current_session_id.txt"
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
68
|
+
# Get turn number
|
|
69
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
70
|
+
TURN_FILE="$STATE_DIR/turn_${SESSION_ID}.txt"
|
|
71
|
+
TURN_NUMBER=1
|
|
72
|
+
if [ -f "$TURN_FILE" ]; then
|
|
73
|
+
TURN_NUMBER=$(cat "$TURN_FILE" 2>/dev/null || echo "0")
|
|
74
|
+
TURN_NUMBER=$((TURN_NUMBER + 1))
|
|
75
|
+
fi
|
|
76
|
+
echo "$TURN_NUMBER" > "$TURN_FILE"
|
|
77
|
+
|
|
78
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
79
|
+
# Capture turn to ekkOS L2
|
|
80
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
81
|
+
# Only capture if we have a query to pair with
|
|
82
|
+
if [ -n "$LAST_QUERY" ]; then
|
|
83
|
+
# Truncate for API limits
|
|
84
|
+
QUERY_TRUNCATED="${LAST_QUERY:0:10000}"
|
|
85
|
+
RESPONSE_TRUNCATED="${RESPONSE_TEXT:0:50000}"
|
|
86
|
+
|
|
87
|
+
CAPTURE_PAYLOAD=$(jq -n \
|
|
88
|
+
--arg session_id "cursor-agent-$SESSION_ID" \
|
|
89
|
+
--arg user_id "${USER_ID:-system}" \
|
|
90
|
+
--arg user_query "$QUERY_TRUNCATED" \
|
|
91
|
+
--arg assistant_response "$RESPONSE_TRUNCATED" \
|
|
92
|
+
--argjson turn_number "$TURN_NUMBER" \
|
|
93
|
+
'{
|
|
94
|
+
session_id: $session_id,
|
|
95
|
+
user_id: $user_id,
|
|
96
|
+
user_query: $user_query,
|
|
97
|
+
assistant_response: $assistant_response,
|
|
98
|
+
metadata: {
|
|
99
|
+
source: "cursor-agent",
|
|
100
|
+
turn_number: $turn_number,
|
|
101
|
+
agent_mode: true
|
|
102
|
+
}
|
|
103
|
+
}' 2>/dev/null || echo '{}')
|
|
104
|
+
|
|
105
|
+
# Fire and forget - don't block agent
|
|
106
|
+
curl -s -X POST "$MEMORY_API_URL/api/v1/capture" \
|
|
107
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
108
|
+
-H "Content-Type: application/json" \
|
|
109
|
+
-d "$CAPTURE_PAYLOAD" \
|
|
110
|
+
--connect-timeout 2 \
|
|
111
|
+
--max-time 3 >/dev/null 2>&1 &
|
|
112
|
+
|
|
113
|
+
# Clear last query
|
|
114
|
+
rm -f "$STATE_DIR/last_query.txt" 2>/dev/null || true
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
exit 0
|
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
3
|
+
# ekkOS_ Hook: BeforeSubmitPrompt (Cursor) - RETRIEVE + INJECT + TIME MACHINE
|
|
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 Cursor.
|
|
9
|
+
#
|
|
10
|
+
# FEATURES:
|
|
11
|
+
# - Pattern retrieval from all memory layers
|
|
12
|
+
# - Time Machine "Continue from here" support
|
|
13
|
+
# - Turn contract for PatternGuard validation
|
|
14
|
+
# - STRICT mode support (block on failed retrieval)
|
|
15
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
16
|
+
|
|
17
|
+
set +e # Don't exit on errors - be bulletproof
|
|
18
|
+
|
|
19
|
+
# Get project root
|
|
20
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
21
|
+
PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
|
22
|
+
STATE_DIR="$PROJECT_ROOT/.cursor/state"
|
|
23
|
+
mkdir -p "$STATE_DIR" 2>/dev/null || true
|
|
24
|
+
|
|
25
|
+
# Load turn contract library
|
|
26
|
+
if [ -f "$SCRIPT_DIR/lib/contract.sh" ]; then
|
|
27
|
+
source "$SCRIPT_DIR/lib/contract.sh" 2>/dev/null || true
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Fallback functions if library didn't load
|
|
31
|
+
if ! command -v write_turn_contract >/dev/null 2>&1; then
|
|
32
|
+
write_turn_contract() { return 0; }
|
|
33
|
+
fi
|
|
34
|
+
if ! command -v generate_query_hash >/dev/null 2>&1; then
|
|
35
|
+
generate_query_hash() { echo "$(date +%s)"; }
|
|
36
|
+
fi
|
|
37
|
+
if ! command -v is_strict_mode >/dev/null 2>&1; then
|
|
38
|
+
is_strict_mode() { [ "${EKKOS_STRICT:-0}" = "1" ]; }
|
|
39
|
+
fi
|
|
40
|
+
if ! command -v get_strict_blocker_message >/dev/null 2>&1; then
|
|
41
|
+
get_strict_blocker_message() { echo "⛔ EKKOS_STRICT: Retrieval failed - DO NOT ANSWER"; }
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# Read JSON input from stdin
|
|
45
|
+
INPUT=$(cat)
|
|
46
|
+
|
|
47
|
+
# Extract prompt text and session info
|
|
48
|
+
PROMPT_TEXT=$(echo "$INPUT" | jq -r '.prompt // .text // ""' 2>/dev/null || echo "")
|
|
49
|
+
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // .conversation_id // ""' 2>/dev/null || echo "")
|
|
50
|
+
MODEL_INFO=$(echo "$INPUT" | jq -r '.model // ""' 2>/dev/null || echo "")
|
|
51
|
+
|
|
52
|
+
# Generate session ID if not provided
|
|
53
|
+
if [ -z "$SESSION_ID" ] || [ "$SESSION_ID" = "null" ]; then
|
|
54
|
+
SESSION_ID="cursor-$(date +%s)-$$"
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# Skip if empty
|
|
58
|
+
if [ -z "$PROMPT_TEXT" ] || [ "$PROMPT_TEXT" = "null" ]; then
|
|
59
|
+
echo '{"continue": true}'
|
|
60
|
+
exit 0
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# Generate query hash for contract
|
|
64
|
+
QUERY_HASH=$(generate_query_hash "$PROMPT_TEXT")
|
|
65
|
+
|
|
66
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
67
|
+
# Load auth token - PORTABLE: Check 3 sources in priority order
|
|
68
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
69
|
+
EKKOS_CONFIG="$HOME/.ekkos/config.json"
|
|
70
|
+
AUTH_TOKEN=""
|
|
71
|
+
USER_ID=""
|
|
72
|
+
|
|
73
|
+
# 1. First try ~/.ekkos/config.json (set by VS Code extension - most portable)
|
|
74
|
+
# Prefer hookApiKey (scoped key for hooks) over apiKey (legacy)
|
|
75
|
+
if [ -f "$EKKOS_CONFIG" ]; then
|
|
76
|
+
AUTH_TOKEN=$(jq -r '.hookApiKey // .apiKey // ""' "$EKKOS_CONFIG" 2>/dev/null || echo "")
|
|
77
|
+
USER_ID=$(jq -r '.userId // ""' "$EKKOS_CONFIG" 2>/dev/null || echo "")
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# 2. Then try project .env.local (for developers)
|
|
81
|
+
if [ -z "$AUTH_TOKEN" ] && [ -f "$PROJECT_ROOT/.env.local" ]; then
|
|
82
|
+
AUTH_TOKEN=$(grep -E "^SUPABASE_SECRET_KEY=" "$PROJECT_ROOT/.env.local" | cut -d'=' -f2- | tr -d '"' | tr -d "'" | tr -d '\r')
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# 3. Finally try environment variable
|
|
86
|
+
if [ -z "$AUTH_TOKEN" ]; then
|
|
87
|
+
AUTH_TOKEN="${SUPABASE_SECRET_KEY:-}"
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
# Track retrieval status
|
|
91
|
+
RETRIEVAL_OK="false"
|
|
92
|
+
RETRIEVED_PATTERN_IDS=""
|
|
93
|
+
RETRIEVED_DIRECTIVE_IDS=""
|
|
94
|
+
|
|
95
|
+
# Skip if no auth
|
|
96
|
+
if [ -z "$AUTH_TOKEN" ]; then
|
|
97
|
+
# STRICT MODE: Block turn if no auth
|
|
98
|
+
if is_strict_mode; then
|
|
99
|
+
BLOCKER_MSG=$(get_strict_blocker_message)
|
|
100
|
+
write_turn_contract "$SESSION_ID" "false" "cursor" "" "" "$QUERY_HASH" "$PROJECT_ROOT"
|
|
101
|
+
echo "{\"continue\": false, \"user_message\": $(echo "$BLOCKER_MSG" | jq -R -s .)}"
|
|
102
|
+
exit 0
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
write_turn_contract "$SESSION_ID" "false" "cursor" "" "" "$QUERY_HASH" "$PROJECT_ROOT"
|
|
106
|
+
echo '{"continue": true, "user_message": "[ekkOS] No auth token. Run ekkOS: Connect in VS Code."}'
|
|
107
|
+
exit 0
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
# Cloud API
|
|
111
|
+
MEMORY_API_URL="https://mcp.ekkos.dev"
|
|
112
|
+
|
|
113
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
114
|
+
# [ENDLESS CONTEXT] Automatic context restoration (like Claude Code)
|
|
115
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
116
|
+
# Cursor loses context silently - we detect and restore automatically.
|
|
117
|
+
# Triggers: new session, time gap, or explicit request.
|
|
118
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
119
|
+
ENDLESS_CONTEXT=""
|
|
120
|
+
SESSION_FLAG="$STATE_DIR/session-active.flag"
|
|
121
|
+
LAST_INTERACTION_FILE="$STATE_DIR/last-interaction.txt"
|
|
122
|
+
TURN_COUNTER_FILE="$STATE_DIR/cursor-turn.txt"
|
|
123
|
+
|
|
124
|
+
# Get current turn count
|
|
125
|
+
CURRENT_TURN=1
|
|
126
|
+
if [ -f "$TURN_COUNTER_FILE" ]; then
|
|
127
|
+
CURRENT_TURN=$(cat "$TURN_COUNTER_FILE" 2>/dev/null || echo "0")
|
|
128
|
+
CURRENT_TURN=$((CURRENT_TURN + 1))
|
|
129
|
+
fi
|
|
130
|
+
echo "$CURRENT_TURN" > "$TURN_COUNTER_FILE" 2>/dev/null || true
|
|
131
|
+
|
|
132
|
+
# Determine if we should restore context
|
|
133
|
+
SHOULD_RESTORE_CONTEXT=false
|
|
134
|
+
RESTORE_REASON=""
|
|
135
|
+
|
|
136
|
+
# 1. First turn of new session
|
|
137
|
+
if [ ! -f "$SESSION_FLAG" ]; then
|
|
138
|
+
SHOULD_RESTORE_CONTEXT=true
|
|
139
|
+
RESTORE_REASON="new session"
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
# 2. Time gap detection (context likely compacted)
|
|
143
|
+
if [ -f "$LAST_INTERACTION_FILE" ]; then
|
|
144
|
+
LAST_INTERACTION=$(cat "$LAST_INTERACTION_FILE" 2>/dev/null || echo "0")
|
|
145
|
+
NOW=$(date +%s)
|
|
146
|
+
SECONDS_AGO=$((NOW - LAST_INTERACTION))
|
|
147
|
+
|
|
148
|
+
# 10 minutes = likely new conversation / compacted
|
|
149
|
+
if [ "$SECONDS_AGO" -gt 600 ]; then
|
|
150
|
+
SHOULD_RESTORE_CONTEXT=true
|
|
151
|
+
RESTORE_REASON="10min gap"
|
|
152
|
+
rm -f "$SESSION_FLAG" 2>/dev/null || true
|
|
153
|
+
CURRENT_TURN=1
|
|
154
|
+
echo "1" > "$TURN_COUNTER_FILE" 2>/dev/null || true
|
|
155
|
+
fi
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
# 3. User explicitly asks
|
|
159
|
+
PROMPT_LOWER=$(echo "$PROMPT_TEXT" | tr '[:upper:]' '[:lower:]')
|
|
160
|
+
if echo "$PROMPT_LOWER" | grep -qE "(recall|where were we|what were we|continue|restore context|load context|what did we)"; then
|
|
161
|
+
SHOULD_RESTORE_CONTEXT=true
|
|
162
|
+
RESTORE_REASON="user request"
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
# Update last interaction
|
|
166
|
+
date +%s > "$LAST_INTERACTION_FILE" 2>/dev/null || true
|
|
167
|
+
|
|
168
|
+
# Auto-restore when triggered
|
|
169
|
+
if [ "$SHOULD_RESTORE_CONTEXT" = true ] && [ -n "$USER_ID" ]; then
|
|
170
|
+
# Fetch recent turns from L2
|
|
171
|
+
RECENT_RESPONSE=$(curl -s -X POST "$MEMORY_API_URL/api/v1/turns/recall" \
|
|
172
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
173
|
+
-H "Content-Type: application/json" \
|
|
174
|
+
-d "{\"user_id\": \"$USER_ID\", \"last_n\": 10, \"format\": \"summary\"}" \
|
|
175
|
+
--connect-timeout 3 \
|
|
176
|
+
--max-time 5 2>/dev/null || echo '{}')
|
|
177
|
+
|
|
178
|
+
RECENT_COUNT=$(echo "$RECENT_RESPONSE" | jq '.turns // [] | length' 2>/dev/null || echo "0")
|
|
179
|
+
|
|
180
|
+
if [ "$RECENT_COUNT" -gt 0 ]; then
|
|
181
|
+
RECENT_CONTEXT=$(echo "$RECENT_RESPONSE" | jq -r '.formatted_context // ""' 2>/dev/null)
|
|
182
|
+
TOTAL_TURNS=$(echo "$RECENT_RESPONSE" | jq -r '.total_turns_in_session // 0' 2>/dev/null)
|
|
183
|
+
|
|
184
|
+
if [ -n "$RECENT_CONTEXT" ] && [ "$RECENT_CONTEXT" != "null" ]; then
|
|
185
|
+
ENDLESS_CONTEXT="━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
186
|
+
🧠 ENDLESS CONTEXT · Auto-restored ($RESTORE_REASON)
|
|
187
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
188
|
+
|
|
189
|
+
$RECENT_CONTEXT
|
|
190
|
+
|
|
191
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
192
|
+
Turn $CURRENT_TURN · Session has $TOTAL_TURNS turns saved
|
|
193
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
194
|
+
|
|
195
|
+
# Mark session as active
|
|
196
|
+
echo "$(date +%s)" > "$SESSION_FLAG" 2>/dev/null || true
|
|
197
|
+
fi
|
|
198
|
+
fi
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
202
|
+
# [TIME MACHINE] Check for pending "Continue from here" requests
|
|
203
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
204
|
+
TIME_MACHINE_CONTEXT=""
|
|
205
|
+
TIME_MACHINE_FLAG="$STATE_DIR/time-machine-consumed.flag"
|
|
206
|
+
|
|
207
|
+
# Only check if we haven't already consumed a request this session
|
|
208
|
+
if [ -n "$USER_ID" ] && [ ! -f "$TIME_MACHINE_FLAG" ]; then
|
|
209
|
+
PENDING_RESPONSE=$(curl -s -X GET "$MEMORY_API_URL/api/v1/context/restore-request/pending?user_id=$USER_ID" \
|
|
210
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
211
|
+
--connect-timeout 2 \
|
|
212
|
+
--max-time 3 2>/dev/null || echo '{}')
|
|
213
|
+
|
|
214
|
+
IS_PENDING=$(echo "$PENDING_RESPONSE" | jq -r '.pending // false' 2>/dev/null)
|
|
215
|
+
|
|
216
|
+
if [ "$IS_PENDING" = "true" ]; then
|
|
217
|
+
TM_SESSION=$(echo "$PENDING_RESPONSE" | jq -r '.request.session_id // ""')
|
|
218
|
+
TM_FROM_TURN=$(echo "$PENDING_RESPONSE" | jq -r '.request.from_turn // ""')
|
|
219
|
+
TM_REQUEST_ID=$(echo "$PENDING_RESPONSE" | jq -r '.request.request_id // ""')
|
|
220
|
+
|
|
221
|
+
if [ -n "$TM_SESSION" ]; then
|
|
222
|
+
# Build recall request
|
|
223
|
+
RECALL_BODY="{\"session_id\": \"$TM_SESSION\", \"last_n\": 15, \"format\": \"summary\"}"
|
|
224
|
+
if [ -n "$TM_FROM_TURN" ] && [ "$TM_FROM_TURN" != "null" ]; then
|
|
225
|
+
RECALL_BODY="{\"session_id\": \"$TM_SESSION\", \"from_turn\": $TM_FROM_TURN, \"format\": \"summary\"}"
|
|
226
|
+
fi
|
|
227
|
+
|
|
228
|
+
# Fetch turns
|
|
229
|
+
TM_RESPONSE=$(curl -s -X POST "$MEMORY_API_URL/api/v1/turns/recall" \
|
|
230
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
231
|
+
-H "Content-Type: application/json" \
|
|
232
|
+
-d "$RECALL_BODY" \
|
|
233
|
+
--connect-timeout 3 \
|
|
234
|
+
--max-time 5 2>/dev/null || echo '{}')
|
|
235
|
+
|
|
236
|
+
TM_TURNS=$(echo "$TM_RESPONSE" | jq -r '.formatted_context // ""' 2>/dev/null)
|
|
237
|
+
|
|
238
|
+
if [ -n "$TM_TURNS" ] && [ "$TM_TURNS" != "null" ]; then
|
|
239
|
+
TIME_MACHINE_CONTEXT="━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
240
|
+
⏰ TIME MACHINE - Restored from past session
|
|
241
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
242
|
+
|
|
243
|
+
$TM_TURNS
|
|
244
|
+
|
|
245
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
246
|
+
Continue from where you left off!
|
|
247
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
248
|
+
|
|
249
|
+
# Mark request as consumed
|
|
250
|
+
curl -s -X POST "$MEMORY_API_URL/api/v1/context/restore-request/consume" \
|
|
251
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
252
|
+
-H "Content-Type: application/json" \
|
|
253
|
+
-d "{\"request_id\": \"$TM_REQUEST_ID\"}" \
|
|
254
|
+
--connect-timeout 2 \
|
|
255
|
+
--max-time 3 >/dev/null 2>&1 || true
|
|
256
|
+
|
|
257
|
+
# Set flag so we don't check again this session
|
|
258
|
+
echo "$TM_REQUEST_ID" > "$TIME_MACHINE_FLAG" 2>/dev/null || true
|
|
259
|
+
fi
|
|
260
|
+
fi
|
|
261
|
+
fi
|
|
262
|
+
fi
|
|
263
|
+
|
|
264
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
265
|
+
# [ekkOS_RETRIEVE] Search memory for patterns (all 8 queryable layers)
|
|
266
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
267
|
+
JSON_PAYLOAD=$(jq -n \
|
|
268
|
+
--arg query "$PROMPT_TEXT" \
|
|
269
|
+
--arg user_id "${USER_ID:-system}" \
|
|
270
|
+
--arg session "cursor-$SESSION_ID" \
|
|
271
|
+
'{
|
|
272
|
+
query: $query,
|
|
273
|
+
user_id: $user_id,
|
|
274
|
+
session_id: $session,
|
|
275
|
+
max_per_layer: 5,
|
|
276
|
+
include_layers: ["working", "episodic", "semantic", "patterns", "procedural", "collective", "codebase", "directives"],
|
|
277
|
+
metadata: { source: "cursor-hook" }
|
|
278
|
+
}' 2>/dev/null || echo '{}')
|
|
279
|
+
|
|
280
|
+
API_RESPONSE=$(curl -s -X POST "$MEMORY_API_URL/api/v1/context/retrieve" \
|
|
281
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
282
|
+
-H "Content-Type: application/json" \
|
|
283
|
+
-d "$JSON_PAYLOAD" \
|
|
284
|
+
--connect-timeout 3 \
|
|
285
|
+
--max-time 5 2>/dev/null || echo '{"error":"timeout"}')
|
|
286
|
+
|
|
287
|
+
# Check if retrieval succeeded
|
|
288
|
+
if echo "$API_RESPONSE" | jq -e '.layers' >/dev/null 2>&1; then
|
|
289
|
+
RETRIEVAL_OK="true"
|
|
290
|
+
else
|
|
291
|
+
# STRICT MODE: Block turn if retrieval failed
|
|
292
|
+
if is_strict_mode; then
|
|
293
|
+
BLOCKER_MSG=$(get_strict_blocker_message)
|
|
294
|
+
write_turn_contract "$SESSION_ID" "false" "cursor" "" "" "$QUERY_HASH" "$PROJECT_ROOT"
|
|
295
|
+
echo "{\"continue\": false, \"user_message\": $(echo "$BLOCKER_MSG" | jq -R -s .)}"
|
|
296
|
+
exit 0
|
|
297
|
+
fi
|
|
298
|
+
|
|
299
|
+
API_RESPONSE='{"error":"timeout","formatted_context":"","layers":{"patterns":[],"directives":[]}}'
|
|
300
|
+
fi
|
|
301
|
+
|
|
302
|
+
# Extract counts
|
|
303
|
+
PATTERN_COUNT=$(echo "$API_RESPONSE" | jq '.layers.patterns // [] | length' 2>/dev/null || echo "0")
|
|
304
|
+
DIRECTIVE_COUNT=$(echo "$API_RESPONSE" | jq '.layers.directives // [] | length' 2>/dev/null || echo "0")
|
|
305
|
+
TOTAL_COUNT=$((PATTERN_COUNT + DIRECTIVE_COUNT))
|
|
306
|
+
|
|
307
|
+
# Extract pattern and directive IDs for turn contract
|
|
308
|
+
RETRIEVED_PATTERN_IDS=$(echo "$API_RESPONSE" | jq -r '.layers.patterns // [] | map(.pattern_id // .id) | join(",")' 2>/dev/null || echo "")
|
|
309
|
+
RETRIEVED_DIRECTIVE_IDS=$(echo "$API_RESPONSE" | jq -r '.layers.directives // [] | map(.directive_id // .id) | join(",")' 2>/dev/null || echo "")
|
|
310
|
+
|
|
311
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
312
|
+
# [ekkOS_CONTRACT] Write turn contract as evidence of retrieval
|
|
313
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
314
|
+
write_turn_contract "$SESSION_ID" "$RETRIEVAL_OK" "cursor" "$RETRIEVED_PATTERN_IDS" "$RETRIEVED_DIRECTIVE_IDS" "$QUERY_HASH" "$PROJECT_ROOT"
|
|
315
|
+
|
|
316
|
+
# Save session ID and query for Agent mode hooks
|
|
317
|
+
echo "$SESSION_ID" > "$STATE_DIR/current_session_id.txt" 2>/dev/null || true
|
|
318
|
+
echo "$PROMPT_TEXT" > "$STATE_DIR/last_query.txt" 2>/dev/null || true
|
|
319
|
+
|
|
320
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
321
|
+
# [ekkOS_INJECT] Build user message with patterns
|
|
322
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
323
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
324
|
+
# Build final message with Time Machine + Patterns
|
|
325
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
326
|
+
MESSAGE=""
|
|
327
|
+
|
|
328
|
+
# Add Endless Context if present (auto-restored recent turns)
|
|
329
|
+
if [ -n "$ENDLESS_CONTEXT" ]; then
|
|
330
|
+
MESSAGE="$ENDLESS_CONTEXT
|
|
331
|
+
|
|
332
|
+
"
|
|
333
|
+
fi
|
|
334
|
+
|
|
335
|
+
# Add Time Machine context if present (overrides Endless Context)
|
|
336
|
+
if [ -n "$TIME_MACHINE_CONTEXT" ]; then
|
|
337
|
+
MESSAGE="$TIME_MACHINE_CONTEXT
|
|
338
|
+
|
|
339
|
+
"
|
|
340
|
+
fi
|
|
341
|
+
|
|
342
|
+
if [ "$PATTERN_COUNT" -gt 0 ]; then
|
|
343
|
+
# Get formatted context
|
|
344
|
+
FORMATTED=$(echo "$API_RESPONSE" | jq -r '.formatted_context // ""' 2>/dev/null)
|
|
345
|
+
|
|
346
|
+
# Get pattern IDs for PatternGuard
|
|
347
|
+
PATTERN_ID_LIST=$(echo "$API_RESPONSE" | jq -r '.layers.patterns[:5][] | .pattern_id // .id' 2>/dev/null || echo "")
|
|
348
|
+
|
|
349
|
+
if [ -n "$FORMATTED" ] && [ "$FORMATTED" != "null" ]; then
|
|
350
|
+
MESSAGE="${MESSAGE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
351
|
+
🧠 ekkOS™ Memory Substrate
|
|
352
|
+
✓ $PATTERN_COUNT patterns loaded from memory
|
|
353
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
354
|
+
|
|
355
|
+
$FORMATTED
|
|
356
|
+
|
|
357
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
358
|
+
⚠️ PATTERNGUARD REQUIRED
|
|
359
|
+
|
|
360
|
+
You MUST acknowledge ALL $PATTERN_COUNT pattern(s) above.
|
|
361
|
+
|
|
362
|
+
Pattern IDs to acknowledge:
|
|
363
|
+
$PATTERN_ID_LIST
|
|
364
|
+
|
|
365
|
+
For patterns you USE:
|
|
366
|
+
[ekkOS_SELECT]
|
|
367
|
+
- id: <pattern-uuid>
|
|
368
|
+
reason: <why using>
|
|
369
|
+
confidence: <0.0-1.0>
|
|
370
|
+
[/ekkOS_SELECT]
|
|
371
|
+
|
|
372
|
+
For patterns you DO NOT use:
|
|
373
|
+
[ekkOS_SKIP]
|
|
374
|
+
- id: <pattern-uuid>
|
|
375
|
+
reason: <why not relevant>
|
|
376
|
+
[/ekkOS_SKIP]
|
|
377
|
+
|
|
378
|
+
Coverage MUST be 100% (all IDs acknowledged).
|
|
379
|
+
|
|
380
|
+
RESPONSE FORMAT: End with:
|
|
381
|
+
🧠 **ekkOS_™** · 📅 YYYY-MM-DD H:MM AM/PM TZ
|
|
382
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
383
|
+
else
|
|
384
|
+
# Fallback: minimal injection
|
|
385
|
+
MESSAGE="${MESSAGE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
386
|
+
🧠 ekkOS™: $PATTERN_COUNT patterns found
|
|
387
|
+
|
|
388
|
+
Pattern IDs to acknowledge with [ekkOS_SELECT] or [ekkOS_SKIP]:
|
|
389
|
+
$PATTERN_ID_LIST
|
|
390
|
+
|
|
391
|
+
End response with: 🧠 **ekkOS_™** · 📅 YYYY-MM-DD
|
|
392
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
393
|
+
fi
|
|
394
|
+
|
|
395
|
+
# Save patterns for stop.sh
|
|
396
|
+
echo "$API_RESPONSE" | jq '.layers.patterns // []' > "$STATE_DIR/patterns-${SESSION_ID}.json" 2>/dev/null || true
|
|
397
|
+
|
|
398
|
+
echo "{\"continue\": true, \"user_message\": $(echo "$MESSAGE" | jq -R -s .)}" | jq -c .
|
|
399
|
+
elif [ -n "$TIME_MACHINE_CONTEXT" ] || [ -n "$ENDLESS_CONTEXT" ]; then
|
|
400
|
+
# Time Machine or Endless Context only, no patterns
|
|
401
|
+
MESSAGE="${MESSAGE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
402
|
+
🧠 ekkOS™: Context restored, no new patterns
|
|
403
|
+
|
|
404
|
+
End response with: 🧠 **ekkOS_™** · 📅 YYYY-MM-DD
|
|
405
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
406
|
+
|
|
407
|
+
echo "{\"continue\": true, \"user_message\": $(echo "$MESSAGE" | jq -R -s .)}" | jq -c .
|
|
408
|
+
else
|
|
409
|
+
# No Time Machine, no patterns - still write contract and remind about footer
|
|
410
|
+
MESSAGE="━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
411
|
+
🧠 ekkOS™: No patterns found (new territory)
|
|
412
|
+
|
|
413
|
+
End response with: 🧠 **ekkOS_™** · 📅 YYYY-MM-DD
|
|
414
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
415
|
+
|
|
416
|
+
echo "{\"continue\": true, \"user_message\": $(echo "$MESSAGE" | jq -R -s .)}" | jq -c .
|
|
417
|
+
fi
|
|
418
|
+
|
|
419
|
+
exit 0
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"hooks": {
|
|
4
|
+
"beforeSubmitPrompt": [
|
|
5
|
+
{
|
|
6
|
+
"command": "./.cursor/hooks/before-submit-prompt.sh"
|
|
7
|
+
}
|
|
8
|
+
],
|
|
9
|
+
"afterAgentResponse": [
|
|
10
|
+
{
|
|
11
|
+
"command": "./.cursor/hooks/after-agent-response.sh"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"stop": [
|
|
15
|
+
{
|
|
16
|
+
"command": "./.cursor/hooks/stop.sh"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
}
|