@ekkos/cli 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/dist/cache/LocalSessionStore.d.ts +129 -0
  2. package/dist/cache/LocalSessionStore.js +688 -0
  3. package/dist/cache/capture.d.ts +26 -0
  4. package/dist/cache/capture.js +461 -0
  5. package/dist/cache/index.d.ts +7 -0
  6. package/dist/cache/index.js +23 -0
  7. package/dist/cache/types.d.ts +147 -0
  8. package/dist/cache/types.js +40 -0
  9. package/dist/commands/init.d.ts +9 -0
  10. package/dist/commands/init.js +478 -0
  11. package/dist/commands/run.d.ts +12 -0
  12. package/dist/commands/run.js +829 -0
  13. package/dist/commands/setup.d.ts +6 -0
  14. package/dist/commands/setup.js +658 -0
  15. package/dist/commands/status.d.ts +1 -0
  16. package/dist/commands/status.js +109 -0
  17. package/dist/commands/test.d.ts +1 -0
  18. package/dist/commands/test.js +157 -0
  19. package/dist/deploy/agents.d.ts +15 -0
  20. package/dist/deploy/agents.js +72 -0
  21. package/dist/deploy/hooks.d.ts +16 -0
  22. package/dist/deploy/hooks.js +121 -0
  23. package/dist/deploy/index.d.ts +7 -0
  24. package/dist/deploy/index.js +24 -0
  25. package/dist/deploy/instructions.d.ts +12 -0
  26. package/dist/deploy/instructions.js +36 -0
  27. package/dist/deploy/mcp.d.ts +19 -0
  28. package/dist/deploy/mcp.js +109 -0
  29. package/dist/deploy/plugins.d.ts +19 -0
  30. package/dist/deploy/plugins.js +62 -0
  31. package/dist/deploy/settings.d.ts +8 -0
  32. package/dist/deploy/settings.js +84 -0
  33. package/dist/deploy/skills.d.ts +19 -0
  34. package/dist/deploy/skills.js +60 -0
  35. package/dist/index.d.ts +2 -0
  36. package/dist/index.js +71 -0
  37. package/dist/restore/RestoreOrchestrator.d.ts +48 -0
  38. package/dist/restore/RestoreOrchestrator.js +481 -0
  39. package/dist/restore/index.d.ts +4 -0
  40. package/dist/restore/index.js +20 -0
  41. package/dist/utils/platform.d.ts +29 -0
  42. package/dist/utils/platform.js +65 -0
  43. package/dist/utils/session-words.json +119 -0
  44. package/dist/utils/state.d.ts +57 -0
  45. package/dist/utils/state.js +186 -0
  46. package/dist/utils/templates.d.ts +24 -0
  47. package/dist/utils/templates.js +118 -0
  48. package/package.json +48 -0
  49. package/templates/CLAUDE.md +287 -0
  50. package/templates/README.md +378 -0
  51. package/templates/agents/README.md +182 -0
  52. package/templates/agents/code-reviewer.md +166 -0
  53. package/templates/agents/debug-detective.md +169 -0
  54. package/templates/agents/ekkOS_Vercel.md +99 -0
  55. package/templates/agents/extension-manager.md +229 -0
  56. package/templates/agents/git-companion.md +185 -0
  57. package/templates/agents/github-test-agent.md +321 -0
  58. package/templates/agents/railway-manager.md +179 -0
  59. package/templates/claude-plugins/PHASE2_COMPLETION.md +346 -0
  60. package/templates/claude-plugins/PLUGIN_PROPOSALS.md +1776 -0
  61. package/templates/claude-plugins/README.md +587 -0
  62. package/templates/claude-plugins/agents/code-reviewer.json +14 -0
  63. package/templates/claude-plugins/agents/debug-detective.json +15 -0
  64. package/templates/claude-plugins/agents/git-companion.json +14 -0
  65. package/templates/claude-plugins/blog-manager/.claude-plugin/plugin.json +8 -0
  66. package/templates/claude-plugins/blog-manager/commands/blog.md +691 -0
  67. package/templates/claude-plugins/golden-loop-monitor/.claude-plugin/plugin.json +8 -0
  68. package/templates/claude-plugins/golden-loop-monitor/commands/loop-status.md +434 -0
  69. package/templates/claude-plugins/learning-tracker/.claude-plugin/plugin.json +8 -0
  70. package/templates/claude-plugins/learning-tracker/commands/my-patterns.md +282 -0
  71. package/templates/claude-plugins/memory-lens/.claude-plugin/plugin.json +8 -0
  72. package/templates/claude-plugins/memory-lens/commands/memory-search.md +181 -0
  73. package/templates/claude-plugins/pattern-coach/.claude-plugin/plugin.json +8 -0
  74. package/templates/claude-plugins/pattern-coach/commands/forge.md +365 -0
  75. package/templates/claude-plugins/project-schema-validator/.claude-plugin/plugin.json +8 -0
  76. package/templates/claude-plugins/project-schema-validator/commands/validate-schema.md +582 -0
  77. package/templates/claude-plugins-admin/AGENT_TEAM_PROPOSALS.md +819 -0
  78. package/templates/claude-plugins-admin/README.md +446 -0
  79. package/templates/claude-plugins-admin/autonomous-admin-agent/.claude-plugin/plugin.json +8 -0
  80. package/templates/claude-plugins-admin/autonomous-admin-agent/commands/agent.md +595 -0
  81. package/templates/claude-plugins-admin/backend-agent/.claude-plugin/plugin.json +8 -0
  82. package/templates/claude-plugins-admin/backend-agent/commands/backend.md +798 -0
  83. package/templates/claude-plugins-admin/deploy-guardian/.claude-plugin/plugin.json +8 -0
  84. package/templates/claude-plugins-admin/deploy-guardian/commands/deploy.md +554 -0
  85. package/templates/claude-plugins-admin/frontend-agent/.claude-plugin/plugin.json +8 -0
  86. package/templates/claude-plugins-admin/frontend-agent/commands/frontend.md +881 -0
  87. package/templates/claude-plugins-admin/mcp-server-manager/.claude-plugin/plugin.json +8 -0
  88. package/templates/claude-plugins-admin/mcp-server-manager/commands/mcp.md +85 -0
  89. package/templates/claude-plugins-admin/memory-system-monitor/.claude-plugin/plugin.json +8 -0
  90. package/templates/claude-plugins-admin/memory-system-monitor/commands/memory-health.md +569 -0
  91. package/templates/claude-plugins-admin/qa-agent/.claude-plugin/plugin.json +8 -0
  92. package/templates/claude-plugins-admin/qa-agent/commands/qa.md +863 -0
  93. package/templates/claude-plugins-admin/tech-lead-agent/.claude-plugin/plugin.json +8 -0
  94. package/templates/claude-plugins-admin/tech-lead-agent/commands/lead.md +732 -0
  95. package/templates/commands/continue.md +47 -0
  96. package/templates/cursor-hooks/after-agent-response.sh +117 -0
  97. package/templates/cursor-hooks/before-submit-prompt.sh +419 -0
  98. package/templates/cursor-hooks/hooks.json +20 -0
  99. package/templates/cursor-hooks/lib/contract.sh +320 -0
  100. package/templates/cursor-hooks/stop.sh +75 -0
  101. package/templates/cursor-rules/ekkos-memory.md +187 -0
  102. package/templates/hooks/assistant-response.sh +96 -0
  103. package/templates/hooks/hooks.json +28 -0
  104. package/templates/hooks/lib/contract.sh +320 -0
  105. package/templates/hooks/lib/state.sh +158 -0
  106. package/templates/hooks/session-start.ps1 +41 -0
  107. package/templates/hooks/session-start.sh +318 -0
  108. package/templates/hooks/stop.ps1 +16 -0
  109. package/templates/hooks/stop.sh +989 -0
  110. package/templates/hooks/user-prompt-submit.ps1 +174 -0
  111. package/templates/hooks/user-prompt-submit.sh +587 -0
  112. package/templates/hooks-node/lib/state.js +187 -0
  113. package/templates/hooks-node/stop.js +416 -0
  114. package/templates/hooks-node/user-prompt-submit.js +337 -0
  115. package/templates/plan-template.md +306 -0
  116. package/templates/rules/00-hooks-contract.mdc +89 -0
  117. package/templates/rules/30-ekkos-core.mdc +188 -0
  118. package/templates/rules/31-ekkos-messages.mdc +78 -0
  119. package/templates/skills/continue/SKILL.md +169 -0
  120. package/templates/skills/ekkOS_Deep_Recall/Skill.md +282 -0
  121. package/templates/skills/ekkOS_Learn/Skill.md +265 -0
  122. package/templates/skills/ekkOS_Memory_First/Skill.md +206 -0
  123. package/templates/skills/ekkOS_Plan_Assist/Skill.md +302 -0
  124. package/templates/skills/ekkOS_Preferences/Skill.md +247 -0
  125. package/templates/skills/ekkOS_Reflect/Skill.md +257 -0
  126. package/templates/skills/ekkOS_Safety/Skill.md +265 -0
  127. package/templates/skills/ekkOS_Schema/Skill.md +251 -0
  128. package/templates/skills/ekkOS_Summary/Skill.md +257 -0
  129. package/templates/skills/ekkOS_Vault/Skill.md +287 -0
  130. package/templates/skills/permissions/Skill.md +322 -0
  131. package/templates/spec-template.md +159 -0
  132. package/templates/windsurf-hooks/before-submit-prompt.sh +238 -0
  133. package/templates/windsurf-hooks/hooks.json +10 -0
  134. package/templates/windsurf-hooks/lib/contract.sh +320 -0
  135. package/templates/windsurf-rules/ekkos-memory.md +129 -0
@@ -0,0 +1,89 @@
1
+ ---
2
+ priority: 100
3
+ globs: ["**/*"]
4
+ alwaysApply: true
5
+ ---
6
+
7
+ # 🔒 Cursor Hooks Contract
8
+
9
+ ⚠️ **MANDATORY**: Hooks run automatically - you don't call them manually
10
+
11
+ ## Hook Architecture
12
+
13
+ **Dumb Hooks, Smart Backend** - Hooks just capture data, backend does analysis
14
+
15
+ ### user-prompt-submit.sh (Runs BEFORE Response)
16
+
17
+ **Triggers**: When user sends a message
18
+ **Does**:
19
+
20
+ - Captures start time
21
+ - Retrieves patterns from MCP gateway (automatic)
22
+ - Displays patterns to user
23
+ - Saves patterns to `.cursor/state/` for badge
24
+
25
+ **You see**:
26
+
27
+ ```
28
+ 🧠 ekkOS™_Retrieving [18ms]
29
+ ✓ 3 patterns loaded from memory
30
+ ```
31
+
32
+ ### stop.sh (Runs AFTER Response)
33
+
34
+ **Triggers**: When your response completes
35
+ **Does**:
36
+
37
+ - Captures conversation to memory API
38
+ - Generates badge with metrics
39
+ - Triggers async analysis (pattern detection, success judgment)
40
+ - Displays badge at end
41
+
42
+ **You see**:
43
+
44
+ ```
45
+ [ekkOS_CAPTURE] ✓ Saved (ID: abc123...)
46
+ [reflex:uuid] badge
47
+ ```
48
+
49
+ ## What You Do
50
+
51
+ **✅ DO**:
52
+
53
+ - Display `_ekkos_stream_message` when present in tool responses
54
+ - Call `forge_insight` when solving problems
55
+ - Show ekkOS branded messages
56
+
57
+ **❌ DON'T**:
58
+
59
+ - Manually call capture scripts (hooks do this)
60
+ - Generate badges yourself (hooks do this)
61
+ - Worry about pattern retrieval (MCP gateway does this)
62
+
63
+ ## Hook Flow
64
+
65
+ ```
66
+ User sends message
67
+
68
+ user-prompt-submit.sh runs
69
+
70
+ Patterns retrieved and displayed
71
+
72
+ You respond (using patterns)
73
+
74
+ stop.sh runs
75
+
76
+ Conversation captured + badge generated
77
+ ```
78
+
79
+ ## Trust the Hooks
80
+
81
+ Hooks are:
82
+
83
+ - ✅ Fully portable (POSIX-compliant)
84
+ - ✅ Bulletproof (fallbacks for missing tools)
85
+ - ✅ Fast (non-blocking, cloud-first)
86
+ - ✅ Automatic (you never call them)
87
+
88
+ **Your job**: Use the patterns hooks provide, forge insights when you solve problems
89
+
@@ -0,0 +1,188 @@
1
+ ---
2
+ priority: 100
3
+ globs: ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"]
4
+ ---
5
+
6
+ # 🧠 ekkOS™ Memory Integration [CRITICAL]
7
+
8
+ ## Golden Loop Enforcement
9
+
10
+ ⚠️ MANDATORY WORKFLOW - NO EXCEPTIONS
11
+
12
+ ### Phase 1: RETRIEVE (⚠️ CURSOR: YOU MUST DO THIS)
13
+
14
+ 🔴 **FIRST THING EVERY RESPONSE**: Call `ekkOS_Search` with the user's query!
15
+
16
+ ```typescript
17
+ // ALWAYS call this BEFORE doing anything else
18
+ mcp__ekkos-memory__ekkOS_Search({
19
+ query: "<user's question or task>",
20
+ limit: 5
21
+ })
22
+ ```
23
+
24
+ Then check response for: `_ekkos_patterns`, `_ekkos_stream_message`
25
+
26
+ **Why?** Cursor has no hooks. Claude Code auto-retrieves via hooks - you don't.
27
+ You MUST manually retrieve or the Golden Loop breaks.
28
+
29
+ ### Phase 2: APPLY (Use Retrieved Patterns)
30
+
31
+ When patterns found → Apply them (PROVEN solutions, not suggestions)
32
+ Output: `[ekkOS_APPLY] Using pattern: "Pattern Name"`
33
+
34
+ ### Phase 3: MEASURE (Track Outcomes)
35
+
36
+ Pattern worked? → success | Pattern failed? → failure
37
+ Output: `[ekkOS_MEASURE] Pattern "X" outcome: success/failure`
38
+
39
+ ### Phase 4: LEARN (Forge New Patterns)
40
+
41
+ 🔴 MANDATORY: Call `forge_insight` when you solve ANY problem
42
+
43
+ **When to forge**:
44
+
45
+ - Fixed bug (non-obvious) → forge
46
+ - Found better approach → forge
47
+ - Discovered gotcha/pitfall → forge
48
+ - User corrected you → forge
49
+ - Solved problem (>1 attempt) → forge
50
+
51
+ **Tool call**:
52
+
53
+ ```typescript
54
+ mcp__ekkos-memory__forge_insight({
55
+ title: "Clear Title",
56
+ problem: "What failed?",
57
+ solution: "How you fixed it",
58
+ tags: ["tech", "tags"],
59
+ });
60
+ ```
61
+
62
+ Output: `[ekkOS_LEARN] Forged: "Pattern Title"`
63
+
64
+ ### Phase 5: CAPTURE (Cursor: Limited)
65
+
66
+ ⚠️ **Cursor limitation**: No automatic capture like Claude Code hooks.
67
+ Conversations are captured when MCP tools are called (search_memory, forge_insight).
68
+ For full capture, use Claude Code or the ekkOS dashboard.
69
+
70
+ ## MCP Tools (31 Total - YOU call these)
71
+
72
+ ### 🔴 MANDATORY - Use Proactively
73
+
74
+ | Tool | Trigger | Description |
75
+ |------|---------|-------------|
76
+ | `ekkOS_Search` | Before ANY technical question | Search all 11 memory layers |
77
+ | `ekkOS_Forge` | When you fix bug, learn, get corrected | Create pattern from solution |
78
+ | `ekkOS_Directive` | User says "always/never/prefer/avoid" | Create MUST/NEVER/PREFER/AVOID rules |
79
+ | `ekkOS_Outcome` | Pattern worked or failed | Track success/failure |
80
+ | `ekkOS_Detect` | After responding | Auto-detect patterns used |
81
+ | `ekkOS_Summary` | Show MCP activity | Get activity summary |
82
+ | `ekkOS_Conflict` | Before destructive action | Check for conflicts |
83
+ | `ekkOS_Reflect` | Analyze response quality | Find improvement opportunities |
84
+
85
+ ### 📚 Recall & Context
86
+
87
+ | Tool | Description |
88
+ |------|-------------|
89
+ | `ekkOS_Recall` | "What did we discuss yesterday?" |
90
+ | `ekkOS_Context` | Get task-specific context |
91
+ | `ekkOS_Codebase` | Find code patterns in project |
92
+ | `ekkOS_Capture` | Manual event capture |
93
+ | `ekkOS_Track` | Track pattern application |
94
+ | `ekkOS_Stats` | Memory layer statistics |
95
+
96
+ ### 📊 Schema Awareness
97
+
98
+ | Tool | Description |
99
+ |------|-------------|
100
+ | `ekkOS_IndexSchema` | Index database schemas (Supabase/Prisma/TS) |
101
+ | `ekkOS_GetSchema` | Get schema for a specific table/type |
102
+
103
+ ### 📋 Plan Management
104
+
105
+ | Tool | Description |
106
+ |------|-------------|
107
+ | `ekkOS_Plan` | Create structured plan |
108
+ | `ekkOS_Plans` | List user's plans |
109
+ | `ekkOS_PlanStatus` | Change plan state |
110
+ | `ekkOS_PlanStep` | Mark step complete |
111
+ | `ekkOS_Generate` | AI-generate plan |
112
+ | `ekkOS_SaveTemplate` | Save as reusable template |
113
+ | `ekkOS_Templates` | List templates |
114
+ | `ekkOS_FromTemplate` | Create from template |
115
+
116
+ ### 🔐 Secrets Management
117
+
118
+ | Tool | Description |
119
+ |------|-------------|
120
+ | `ekkOS_StoreSecret` | Encrypt and store credentials |
121
+ | `ekkOS_GetSecret` | Retrieve and decrypt |
122
+ | `ekkOS_ListSecrets` | List metadata (no values) |
123
+ | `ekkOS_DeleteSecret` | Permanently delete |
124
+ | `ekkOS_RotateSecret` | Update with new value |
125
+
126
+ ### 💾 Portability
127
+
128
+ | Tool | Description |
129
+ |------|-------------|
130
+ | `ekkOS_Export` | Backup patterns, directives, plans |
131
+ | `ekkOS_Import` | Restore from backup |
132
+
133
+ ## Proactive Tool Triggers
134
+
135
+ ### Always Use `ekkOS_Search` When:
136
+ - User asks technical question
137
+ - User mentions past discussion
138
+ - Topic involves architecture, config, debugging
139
+ - You're about to make a decision
140
+
141
+ ### Always Use `ekkOS_Forge` When:
142
+ - Fixed bug (especially non-obvious)
143
+ - Discovered better approach
144
+ - Found pitfall or gotcha
145
+ - User corrected you
146
+ - Made architectural decision
147
+ - Something DIDN'T work (anti-pattern)
148
+
149
+ ### Always Use `ekkOS_Directive` When:
150
+ - User says "always..." → MUST
151
+ - User says "never..." → NEVER
152
+ - User says "I prefer..." → PREFER
153
+ - User says "don't..." → AVOID
154
+
155
+ ### Always Use `ekkOS_Conflict` When:
156
+ - About to delete files/data
157
+ - About to deploy to production
158
+ - About to modify config files
159
+
160
+ ## Enforcement
161
+
162
+ ⚠️ Violating Golden Loop = System failure
163
+ Every conversation MUST follow: RETRIEVE → APPLY → MEASURE → LEARN → CAPTURE
164
+
165
+ ---
166
+
167
+ ## 🔴 MANDATORY RESPONSE FORMAT (NO EXCEPTIONS)
168
+
169
+ **Every response MUST end with a timestamp footer:**
170
+
171
+ ```
172
+ ---
173
+ 🧠 **ekkOS_™** · 📅 YYYY-MM-DD H:MM AM/PM TZ
174
+ ```
175
+
176
+ **Example:**
177
+ ```
178
+ ---
179
+ 🧠 **ekkOS_™** · 📅 2025-12-08 2:30 PM PST
180
+ ```
181
+
182
+ **Why this matters:**
183
+ - Timestamps track when patterns were applied
184
+ - 3-Judge evaluations need temporal context
185
+ - Future agents can trace learning timeline
186
+ - Golden Loop metrics require time-based correlation
187
+
188
+ **⚠️ MISSING TIMESTAMP = INCOMPLETE LOOP = SYSTEM DEGRADATION**
@@ -0,0 +1,78 @@
1
+ ---
2
+ priority: 100
3
+ globs: ["**/*"]
4
+ ---
5
+
6
+ # ekkOS™ Branded Message Templates
7
+
8
+ ## Stream Message Fields (Display All Present)
9
+
10
+ ```
11
+ _ekkos_stream_message → Display FIRST (🧠 Retrieving/🔄 Applying/✅ Learned)
12
+ _ekkos_learning_message → Display AFTER solution (🔥 Learning - pattern detected)
13
+ _ekkos_session_summary → Display AT END (📊 Summary at turns 5/10/20/50)
14
+ ```
15
+
16
+ ## Message Examples
17
+
18
+ ### Before Response:
19
+
20
+ ```
21
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
22
+ 🧠 ekkOS™_Retrieving [18ms]
23
+ ✓ 3 patterns loaded from memory
24
+ • "Pattern Name" (94% success, 12 uses)
25
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
26
+ ```
27
+
28
+ ### When Learning:
29
+
30
+ ```
31
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
32
+ 🔥 ekkOS™_Learning
33
+ New pattern detected: "Title"
34
+ Confidence: 60% (forming)
35
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
36
+ ```
37
+
38
+ ### When Pattern Saved:
39
+
40
+ ```
41
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
42
+ ✅ ekkOS™_Learned
43
+ Pattern saved: "Title"
44
+ Confidence: 85% | Success: 100%
45
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
46
+ ```
47
+
48
+ ### When Reusing:
49
+
50
+ ```
51
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
52
+ 🔄 ekkOS™_Applying
53
+ Using pattern from 2 messages ago
54
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
55
+ ```
56
+
57
+ ### Session Summary:
58
+
59
+ ```
60
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
61
+ 📊 ekkOS™_Session_Summary
62
+ Memory Activity:
63
+ Retrieved: 5 patterns
64
+ Applied: 3 patterns
65
+ Learned: 2 new patterns
66
+ Confidence: +8% overall
67
+
68
+ Your AI is getting smarter.
69
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
70
+ ```
71
+
72
+ ## Requirements
73
+
74
+ - ALWAYS use ekkOS™ branding (with ™)
75
+ - ALWAYS show retrieval before response
76
+ - ALWAYS show learning when it happens
77
+ - Keep messages concise but visible
78
+
@@ -0,0 +1,169 @@
1
+ ---
2
+ name: continue
3
+ description: Resume session after /clear - instant restore from local cache (1ms) with Redis/Supabase fallback
4
+ allowed-tools:
5
+ - Bash
6
+ ---
7
+
8
+ # /continue
9
+
10
+ Instant session restore. NO THINKING - just execute.
11
+
12
+ ## Execution
13
+
14
+ **Run this IMMEDIATELY - do not analyze, just execute:**
15
+
16
+ ```bash
17
+ export EKKOS_SESSION="${ARGUMENTS:-}"
18
+ # Use session-specific temp file to avoid collision across concurrent sessions
19
+ output_file="/tmp/continue-restore-${EKKOS_SESSION:-default}.md"
20
+
21
+ # ═══════════════════════════════════════════════════════════════════════════
22
+ # TIER 0: Local cache restore (~1ms) - TRY FIRST
23
+ # ═══════════════════════════════════════════════════════════════════════════
24
+ tier0_result=$(ekkos-capture restore "$EKKOS_SESSION" --markdown 2>/dev/null)
25
+ tier0_exit=$?
26
+
27
+ if [ $tier0_exit -eq 0 ] && [ -n "$tier0_result" ] && echo "$tier0_result" | grep -q "CONTEXT RESTORED"; then
28
+ echo "$tier0_result" > "$output_file"
29
+ # Extract session name and stats (portable - no grep -P)
30
+ session_name=$(echo "$tier0_result" | grep "Session:" | head -1 | sed 's/.*Session: \([^ (]*\).*/\1/')
31
+ turns=$(echo "$tier0_result" | grep "Turns restored:" | head -1 | sed 's/.*Turns restored: \([0-9]*\).*/\1/')
32
+ source=$(echo "$tier0_result" | grep "Source:" | head -1 | sed 's/.*Source: \([a-z]*\).*/\1/')
33
+ echo "✓ $session_name restored ($turns turns from $source cache)"
34
+ echo "📄 Full content: $output_file"
35
+ exit 0
36
+ fi
37
+
38
+ # ═══════════════════════════════════════════════════════════════════════════
39
+ # TIER 1/2: API fallback (Redis ~150ms, Supabase ~500ms)
40
+ # ═══════════════════════════════════════════════════════════════════════════
41
+ python3 << 'PYTHON'
42
+ import urllib.request
43
+ import json
44
+ import os
45
+ import sys
46
+
47
+ session = os.environ.get('EKKOS_SESSION', '').strip()
48
+
49
+ # Read config
50
+ config = {}
51
+ try:
52
+ with open(os.path.expanduser('~/.ekkos/config.json'), 'r') as f:
53
+ config = json.load(f)
54
+ except:
55
+ pass
56
+
57
+ auth = config.get('hookApiKey') or config.get('apiKey', '')
58
+
59
+ # Use session-specific temp file (matches bash section)
60
+ output_file = f"/tmp/continue-restore-{session or 'default'}.md"
61
+
62
+ url = "https://api.ekkos.dev/api/v1/working/restore"
63
+ if session:
64
+ url += f"?session={session}&full=true"
65
+
66
+ req = urllib.request.Request(url, headers={"Authorization": f"Bearer {auth}"})
67
+
68
+ try:
69
+ with urllib.request.urlopen(req, timeout=15) as response:
70
+ data = json.loads(response.read().decode('utf-8'))
71
+
72
+ if data.get('mode') == 'full_restore' and 'turns' in data:
73
+ turns = data['turns']
74
+ session_name = data.get('session_name', session or 'unknown')
75
+
76
+ # Build system-reminder format matching local restore
77
+ MAX_SIZE = 60000 # ~15k tokens
78
+ output_lines = [
79
+ '<system-reminder>',
80
+ 'CONTEXT RESTORED (ekkOS /continue)',
81
+ f'Session: {session_name}',
82
+ 'Source: redis',
83
+ f'Turns restored: {len(turns)}',
84
+ '',
85
+ '## Recent Turns (older → newer)',
86
+ ]
87
+
88
+ cumulative_size = 0
89
+ turn_count = 0
90
+
91
+ # Process turns oldest first for narrative flow
92
+ for turn in turns:
93
+ turn_num = turn.get('turn_number', '?')
94
+ user_query = turn.get('user', {}).get('query', '')
95
+ agent_response = turn.get('agent', {}).get('response', '')
96
+ tools = turn.get('agent', {}).get('tools_used', [])
97
+ files = turn.get('user', {}).get('files_referenced', [])
98
+
99
+ if not user_query and not agent_response:
100
+ continue
101
+
102
+ turn_lines = [f"### Turn {turn_num}"]
103
+ if user_query:
104
+ turn_lines.append(f"**User:** {user_query}")
105
+ if agent_response:
106
+ if len(agent_response) > 4000:
107
+ agent_response = agent_response[:4000] + "\n\n[...truncated...]"
108
+ turn_lines.append(f"\n**Assistant:**\n{agent_response}")
109
+ if tools:
110
+ turn_lines.append(f"\n*Tools: {', '.join(tools)}*")
111
+ if files:
112
+ turn_lines.append(f"\n*Files: {', '.join(files[:10])}*")
113
+ turn_lines.append("\n---\n")
114
+
115
+ turn_content = "\n".join(turn_lines)
116
+ turn_size = len(turn_content.encode('utf-8'))
117
+
118
+ if cumulative_size + turn_size > MAX_SIZE:
119
+ break
120
+
121
+ output_lines.extend(turn_lines)
122
+ cumulative_size += turn_size
123
+ turn_count += 1
124
+
125
+ output_lines.extend([
126
+ '',
127
+ 'INSTRUCTION: Resume seamlessly where you left off.',
128
+ 'Do not ask "what were we doing?"',
129
+ 'Start your response with: "✓ Continuing -"',
130
+ '</system-reminder>'
131
+ ])
132
+
133
+ kb_size = cumulative_size / 1024
134
+ token_est = cumulative_size // 4
135
+
136
+ with open(output_file, 'w', encoding='utf-8') as f:
137
+ f.write("\n".join(output_lines))
138
+
139
+ print(f"✓ {session_name} restored ({turn_count} turns from redis, {kb_size:.1f}KB, ~{token_est} tokens)")
140
+ print(f"📄 Full content: {output_file}")
141
+ else:
142
+ # Try to show available sessions if session not found
143
+ if 'available_sessions' in data:
144
+ sessions = data.get('available_sessions', [])
145
+ with open(output_file, 'w', encoding='utf-8') as f:
146
+ f.write(f"Session '{session}' not found\n\n")
147
+ f.write("Available sessions:\n")
148
+ for s in sessions[:10]:
149
+ f.write(f"- {s}\n")
150
+ print(f"Session '{session}' not found")
151
+ print(f"📄 Available sessions: {output_file}")
152
+ sys.exit(1)
153
+ else:
154
+ markdown = data.get('markdown', '')
155
+ if markdown:
156
+ with open(output_file, 'w', encoding='utf-8') as f:
157
+ f.write(markdown)
158
+ print("✓ Session restored (fallback mode)")
159
+ print(f"📄 Full content: {output_file}")
160
+ else:
161
+ print("Error: No session data available")
162
+ sys.exit(1)
163
+ except Exception as e:
164
+ print(f"Error: {e}")
165
+ sys.exit(1)
166
+ PYTHON
167
+ ```
168
+
169
+ **Then immediately read the output file (path shown in console output) using the Read tool to display the full content to the user. Do not just echo the bash output.**