@ekkos/cli 1.0.36 → 1.1.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/commands/dashboard.js +561 -186
- package/dist/deploy/settings.js +13 -26
- package/package.json +1 -1
- package/templates/hooks/assistant-response.ps1 +94 -26
- package/templates/hooks/hooks.json +24 -12
- package/templates/hooks/lib/count-tokens.cjs +0 -0
- package/templates/hooks/lib/ekkos-reminders.sh +0 -0
- package/templates/hooks/session-start.ps1 +61 -224
- package/templates/hooks/session-start.sh +1 -1
- package/templates/hooks/stop.ps1 +103 -249
- package/templates/hooks/stop.sh +1 -1
- package/templates/hooks/user-prompt-submit.ps1 +129 -519
- package/templates/hooks/user-prompt-submit.sh +2 -2
- package/templates/plan-template.md +0 -0
- package/templates/spec-template.md +0 -0
- package/templates/windsurf-hooks/install.sh +0 -0
- package/templates/windsurf-hooks/lib/contract.sh +0 -0
- package/templates/windsurf-hooks/post-cascade-response.sh +0 -0
- package/templates/windsurf-hooks/pre-user-prompt.sh +0 -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 -179
- package/templates/windsurf-hooks/before-submit-prompt.sh +0 -238
- package/templates/windsurf-skills/ekkos-memory/SKILL.md +0 -219
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
-
# ekkOS_ Hook: SessionStart -
|
|
2
|
+
# ekkOS_ Hook: SessionStart - Initialize session (Windows)
|
|
3
3
|
# MANAGED BY ekkos-connect - DO NOT EDIT DIRECTLY
|
|
4
4
|
# EKKOS_MANAGED=1
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# 1. Check for pending Time Machine "Continue from here" requests
|
|
8
|
-
# 2. Initialize session tracking + Golden Loop
|
|
9
|
-
# 3. Fetch and inject user directives (MUST/NEVER/PREFER/AVOID)
|
|
5
|
+
# EKKOS_MANIFEST_SHA256=<computed-at-build>
|
|
6
|
+
# EKKOS_TEMPLATE_VERSION=1.0.0
|
|
10
7
|
#
|
|
11
|
-
# Per
|
|
8
|
+
# Per ekkOS Onboarding Spec v1.2 FINAL + ADDENDUM:
|
|
9
|
+
# - All persisted records MUST include: instanceId, sessionId, sessionName
|
|
10
|
+
# - Uses EKKOS_INSTANCE_ID env var for multi-session isolation
|
|
12
11
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
13
12
|
|
|
14
13
|
$ErrorActionPreference = "SilentlyContinue"
|
|
15
14
|
|
|
16
15
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
17
|
-
# CONFIG PATHS
|
|
16
|
+
# CONFIG PATHS - No hardcoded word arrays per spec v1.2 Addendum
|
|
18
17
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
19
18
|
$EkkosConfigDir = if ($env:EKKOS_CONFIG_DIR) { $env:EKKOS_CONFIG_DIR } else { "$env:USERPROFILE\.ekkos" }
|
|
20
19
|
$SessionWordsJson = "$EkkosConfigDir\session-words.json"
|
|
21
20
|
$SessionWordsDefault = "$EkkosConfigDir\.defaults\session-words.json"
|
|
22
|
-
$EkkosInstanceId = if ($env:EKKOS_INSTANCE_ID) { $env:EKKOS_INSTANCE_ID } else { "default" }
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
23
|
+
# INSTANCE ID - Multi-session isolation per v1.2 ADDENDUM
|
|
24
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
25
|
+
$EkkosInstanceId = if ($env:EKKOS_INSTANCE_ID) { $env:EKKOS_INSTANCE_ID } else { "default" }
|
|
25
26
|
|
|
26
27
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
27
28
|
# Load session words from JSON file - NO HARDCODED ARRAYS
|
|
@@ -30,22 +31,41 @@ $script:SessionWords = $null
|
|
|
30
31
|
|
|
31
32
|
function Load-SessionWords {
|
|
32
33
|
$wordsFile = $SessionWordsJson
|
|
33
|
-
|
|
34
|
-
if (-not (Test-Path $wordsFile)) {
|
|
34
|
+
|
|
35
|
+
if (-not (Test-Path $wordsFile)) {
|
|
36
|
+
$wordsFile = $SessionWordsDefault
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (-not (Test-Path $wordsFile)) {
|
|
40
|
+
return $null
|
|
41
|
+
}
|
|
42
|
+
|
|
35
43
|
try {
|
|
36
44
|
$script:SessionWords = Get-Content $wordsFile -Raw | ConvertFrom-Json
|
|
37
|
-
} catch {
|
|
45
|
+
} catch {
|
|
46
|
+
return $null
|
|
47
|
+
}
|
|
38
48
|
}
|
|
39
49
|
|
|
40
50
|
function Convert-UuidToWords {
|
|
41
51
|
param([string]$uuid)
|
|
42
|
-
|
|
43
|
-
if (-not $script:SessionWords) {
|
|
52
|
+
|
|
53
|
+
if (-not $script:SessionWords) {
|
|
54
|
+
Load-SessionWords
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (-not $script:SessionWords) {
|
|
58
|
+
return "unknown-session"
|
|
59
|
+
}
|
|
44
60
|
|
|
45
61
|
$adjectives = $script:SessionWords.adjectives
|
|
46
62
|
$nouns = $script:SessionWords.nouns
|
|
47
63
|
$verbs = $script:SessionWords.verbs
|
|
48
|
-
|
|
64
|
+
|
|
65
|
+
if (-not $adjectives -or -not $nouns -or -not $verbs) {
|
|
66
|
+
return "unknown-session"
|
|
67
|
+
}
|
|
68
|
+
|
|
49
69
|
if (-not $uuid -or $uuid -eq "unknown") { return "unknown-session" }
|
|
50
70
|
|
|
51
71
|
$clean = $uuid -replace "-", ""
|
|
@@ -55,116 +75,36 @@ function Convert-UuidToWords {
|
|
|
55
75
|
$a = [Convert]::ToInt32($clean.Substring(0,4), 16) % $adjectives.Length
|
|
56
76
|
$n = [Convert]::ToInt32($clean.Substring(4,4), 16) % $nouns.Length
|
|
57
77
|
$an = [Convert]::ToInt32($clean.Substring(8,4), 16) % $verbs.Length
|
|
78
|
+
|
|
58
79
|
return "$($adjectives[$a])-$($nouns[$n])-$($verbs[$an])"
|
|
59
|
-
} catch {
|
|
80
|
+
} catch {
|
|
81
|
+
return "unknown-session"
|
|
82
|
+
}
|
|
60
83
|
}
|
|
61
84
|
|
|
62
85
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
63
86
|
# READ INPUT
|
|
64
87
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
65
88
|
$inputJson = [Console]::In.ReadToEnd()
|
|
89
|
+
|
|
66
90
|
try {
|
|
67
91
|
$input = $inputJson | ConvertFrom-Json
|
|
68
92
|
$sessionId = $input.session_id
|
|
69
93
|
} catch {
|
|
70
94
|
$sessionId = "unknown"
|
|
71
95
|
}
|
|
72
|
-
if (-not $sessionId) { $sessionId = "unknown" }
|
|
73
96
|
|
|
74
97
|
$sessionName = Convert-UuidToWords $sessionId
|
|
75
98
|
|
|
76
99
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
77
|
-
#
|
|
78
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
79
|
-
$authToken = ""
|
|
80
|
-
$userId = ""
|
|
81
|
-
$configFile = Join-Path $EkkosConfigDir "config.json"
|
|
82
|
-
if (Test-Path $configFile) {
|
|
83
|
-
try {
|
|
84
|
-
$config = Get-Content $configFile -Raw | ConvertFrom-Json
|
|
85
|
-
$authToken = $config.hookApiKey
|
|
86
|
-
if (-not $authToken) { $authToken = $config.apiKey }
|
|
87
|
-
$userId = $config.userId
|
|
88
|
-
} catch {}
|
|
89
|
-
}
|
|
90
|
-
if (-not $authToken) { exit 0 }
|
|
91
|
-
|
|
92
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
93
|
-
# TIME MACHINE: Check for pending "Continue from here" requests
|
|
100
|
+
# INITIALIZE STATE DIRECTORY
|
|
94
101
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
95
|
-
$timeMachineSession = ""
|
|
96
|
-
$timeMachineFromTurn = ""
|
|
97
|
-
$timeMachineToTurn = ""
|
|
98
|
-
$restoreRequestId = $env:EKKOS_RESTORE
|
|
99
|
-
|
|
100
|
-
if (-not $timeMachineSession -and $userId) {
|
|
101
|
-
try {
|
|
102
|
-
$headers = @{ "Authorization" = "Bearer $authToken" }
|
|
103
|
-
$pendingResponse = Invoke-RestMethod -Uri "$MemoryApiUrl/api/v1/context/restore-request/pending?user_id=$userId" `
|
|
104
|
-
-Method GET -Headers $headers -TimeoutSec 3
|
|
105
|
-
|
|
106
|
-
if ($pendingResponse.pending -eq $true -and $pendingResponse.request) {
|
|
107
|
-
$timeMachineSession = $pendingResponse.request.session_id
|
|
108
|
-
$timeMachineFromTurn = $pendingResponse.request.from_turn
|
|
109
|
-
$timeMachineToTurn = $pendingResponse.request.to_turn
|
|
110
|
-
$restoreRequestId = $pendingResponse.request.request_id
|
|
111
|
-
|
|
112
|
-
if ($timeMachineSession) {
|
|
113
|
-
$esc = [char]27
|
|
114
|
-
[Console]::Error.WriteLine("")
|
|
115
|
-
[Console]::Error.WriteLine("${esc}[0;35m------------------------------------------------------------------------${esc}[0m")
|
|
116
|
-
[Console]::Error.WriteLine("${esc}[0;35m${esc}[1m TIME MACHINE${esc}[0m ${esc}[2m| Restoring session from web request...${esc}[0m")
|
|
117
|
-
[Console]::Error.WriteLine("${esc}[0;35m------------------------------------------------------------------------${esc}[0m")
|
|
118
|
-
|
|
119
|
-
$consumeBody = @{ request_id = $restoreRequestId } | ConvertTo-Json -Depth 10
|
|
120
|
-
try {
|
|
121
|
-
Invoke-RestMethod -Uri "$MemoryApiUrl/api/v1/context/restore-request/consume" `
|
|
122
|
-
-Method POST -Headers @{ "Authorization" = "Bearer $authToken"; "Content-Type" = "application/json" } `
|
|
123
|
-
-Body ([System.Text.Encoding]::UTF8.GetBytes($consumeBody)) -TimeoutSec 3 | Out-Null
|
|
124
|
-
} catch {}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
} catch {}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
131
|
-
# SESSION PERSISTENCE - PROJECT-LOCAL for isolation
|
|
132
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
133
|
-
$projectRoot = if ($env:PWD) { $env:PWD } else { (Get-Location).Path }
|
|
134
102
|
$stateDir = Join-Path $env:USERPROFILE ".claude\state"
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (-not (Test-Path $stateDir)) { New-Item -ItemType Directory -Path $stateDir -Force | Out-Null }
|
|
138
|
-
if (-not (Test-Path $projectSessionDir)) { New-Item -ItemType Directory -Path $projectSessionDir -Force | Out-Null }
|
|
139
|
-
|
|
140
|
-
$savedTurnCount = 0
|
|
141
|
-
$mostRecentSession = ""
|
|
142
|
-
|
|
143
|
-
if ($sessionId -ne "unknown") {
|
|
144
|
-
$turnFile = Join-Path $projectSessionDir "$sessionId.turn"
|
|
145
|
-
if (Test-Path $turnFile) {
|
|
146
|
-
try { $savedTurnCount = [int](Get-Content $turnFile -Raw).Trim() } catch { $savedTurnCount = 0 }
|
|
147
|
-
$mostRecentSession = $sessionId
|
|
148
|
-
} else {
|
|
149
|
-
$mostRecentFile = Get-ChildItem "$projectSessionDir\*.turn" -ErrorAction SilentlyContinue |
|
|
150
|
-
Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
|
151
|
-
if ($mostRecentFile) {
|
|
152
|
-
$mostRecentSession = $mostRecentFile.BaseName
|
|
153
|
-
try { $savedTurnCount = [int](Get-Content $mostRecentFile.FullName -Raw).Trim() } catch { $savedTurnCount = 0 }
|
|
154
|
-
}
|
|
155
|
-
}
|
|
103
|
+
if (-not (Test-Path $stateDir)) {
|
|
104
|
+
New-Item -ItemType Directory -Path $stateDir -Force | Out-Null
|
|
156
105
|
}
|
|
157
106
|
|
|
158
|
-
|
|
159
|
-
$sessionData = @{
|
|
160
|
-
session_id = $sessionId
|
|
161
|
-
session_name = $sessionName
|
|
162
|
-
instance_id = $EkkosInstanceId
|
|
163
|
-
timestamp = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
|
|
164
|
-
project_root = $projectRoot
|
|
165
|
-
} | ConvertTo-Json -Depth 10
|
|
166
|
-
Set-Content -Path $sessionFile -Value $sessionData -Force
|
|
167
|
-
|
|
107
|
+
# Reset turn counter for new session
|
|
168
108
|
$stateFile = Join-Path $stateDir "hook-state.json"
|
|
169
109
|
$state = @{
|
|
170
110
|
turn = 0
|
|
@@ -173,137 +113,34 @@ $state = @{
|
|
|
173
113
|
instance_id = $EkkosInstanceId
|
|
174
114
|
started_at = (Get-Date).ToString("o")
|
|
175
115
|
} | ConvertTo-Json -Depth 10
|
|
176
|
-
Set-Content -Path $stateFile -Value $state -Force
|
|
177
116
|
|
|
178
|
-
|
|
179
|
-
# GOLDEN LOOP: Initialize session tracking file
|
|
180
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
181
|
-
$ekkosDir = Join-Path $projectRoot ".ekkos"
|
|
182
|
-
if (-not (Test-Path $ekkosDir)) { New-Item -ItemType Directory -Path $ekkosDir -Force | Out-Null }
|
|
117
|
+
Set-Content -Path $stateFile -Value $state -Force
|
|
183
118
|
|
|
184
|
-
|
|
185
|
-
$
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
stats = @{ retrieved = 0; applied = 0; forged = 0 }
|
|
119
|
+
# Save session ID for other hooks
|
|
120
|
+
$sessionFile = Join-Path $stateDir "current-session.json"
|
|
121
|
+
$sessionData = @{
|
|
122
|
+
session_id = $sessionId
|
|
123
|
+
session_name = $sessionName
|
|
124
|
+
instance_id = $EkkosInstanceId
|
|
191
125
|
} | ConvertTo-Json -Depth 10
|
|
192
|
-
|
|
126
|
+
|
|
127
|
+
Set-Content -Path $sessionFile -Value $sessionData -Force
|
|
193
128
|
|
|
194
129
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
195
|
-
# LOCAL CACHE: Initialize session
|
|
130
|
+
# LOCAL CACHE: Initialize session in Tier 0 cache
|
|
131
|
+
# Per v1.2 ADDENDUM: Pass instanceId for namespacing
|
|
196
132
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
197
133
|
$captureCmd = Get-Command "ekkos-capture" -ErrorAction SilentlyContinue
|
|
198
134
|
if ($captureCmd -and $sessionId -ne "unknown") {
|
|
199
135
|
try {
|
|
136
|
+
# NEW format: ekkos-capture init <instance_id> <session_id> <session_name>
|
|
200
137
|
Start-Job -ScriptBlock {
|
|
201
138
|
param($instanceId, $sessId, $sessName)
|
|
202
|
-
try {
|
|
139
|
+
try {
|
|
140
|
+
& ekkos-capture init $instanceId $sessId $sessName 2>&1 | Out-Null
|
|
141
|
+
} catch {}
|
|
203
142
|
} -ArgumentList $EkkosInstanceId, $sessionId, $sessionName | Out-Null
|
|
204
143
|
} catch {}
|
|
205
144
|
}
|
|
206
145
|
|
|
207
|
-
|
|
208
|
-
# COLORS
|
|
209
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
210
|
-
$esc = [char]27
|
|
211
|
-
$CYAN = "${esc}[0;36m"; $GREEN = "${esc}[0;32m"; $MAGENTA = "${esc}[0;35m"
|
|
212
|
-
$DIM = "${esc}[2m"; $BOLD = "${esc}[1m"; $RESET = "${esc}[0m"
|
|
213
|
-
|
|
214
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
215
|
-
# TIME MACHINE RESTORATION
|
|
216
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
217
|
-
if ($timeMachineSession) {
|
|
218
|
-
[Console]::Error.WriteLine("")
|
|
219
|
-
$tmPreview = $timeMachineSession.Substring(0, [Math]::Min(12, $timeMachineSession.Length))
|
|
220
|
-
[Console]::Error.WriteLine("${MAGENTA}${BOLD} TIME MACHINE${RESET} ${DIM}| Restoring past session: ${tmPreview}...${RESET}")
|
|
221
|
-
|
|
222
|
-
$recallBody = @{ session_id = $timeMachineSession; last_n = 15; format = "summary" }
|
|
223
|
-
if ($timeMachineFromTurn -and $timeMachineToTurn) {
|
|
224
|
-
$recallBody = @{ session_id = $timeMachineSession; from_turn = [int]$timeMachineFromTurn; to_turn = [int]$timeMachineToTurn; format = "summary" }
|
|
225
|
-
} elseif ($timeMachineFromTurn) {
|
|
226
|
-
$recallBody = @{ session_id = $timeMachineSession; from_turn = [int]$timeMachineFromTurn; format = "summary" }
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
$recallJson = $recallBody | ConvertTo-Json -Depth 10
|
|
230
|
-
try {
|
|
231
|
-
$restoreResponse = Invoke-RestMethod -Uri "$MemoryApiUrl/api/v1/turns/recall" `
|
|
232
|
-
-Method POST `
|
|
233
|
-
-Headers @{ "Authorization" = "Bearer $authToken"; "Content-Type" = "application/json" } `
|
|
234
|
-
-Body ([System.Text.Encoding]::UTF8.GetBytes($recallJson)) -TimeoutSec 5
|
|
235
|
-
|
|
236
|
-
$restoredCount = ($restoreResponse.turns | Measure-Object).Count
|
|
237
|
-
if ($restoredCount -gt 0) {
|
|
238
|
-
[Console]::Error.WriteLine("${MAGENTA} ✓${RESET} Restored $restoredCount turns from past session")
|
|
239
|
-
[Console]::Error.WriteLine("")
|
|
240
|
-
|
|
241
|
-
$turnsOutput = ""
|
|
242
|
-
foreach ($t in $restoreResponse.turns) {
|
|
243
|
-
$q = if ($t.user_query) { $t.user_query.Substring(0, [Math]::Min(100, $t.user_query.Length)) } else { "..." }
|
|
244
|
-
$r = if ($t.assistant_response) { $t.assistant_response.Substring(0, [Math]::Min(200, $t.assistant_response.Length)) } else { "..." }
|
|
245
|
-
$turnLine = "**Turn $($t.turn_number)**: $q..."
|
|
246
|
-
[Console]::Error.WriteLine($turnLine)
|
|
247
|
-
[Console]::Error.WriteLine("> $r...")
|
|
248
|
-
[Console]::Error.WriteLine("")
|
|
249
|
-
$turnsOutput += "$turnLine`n> $r...`n`n"
|
|
250
|
-
}
|
|
251
|
-
Write-Output $turnsOutput
|
|
252
|
-
|
|
253
|
-
[Console]::Error.WriteLine("${DIM}You've traveled to a past session. Continue from here!${RESET}")
|
|
254
|
-
[Console]::Error.WriteLine("")
|
|
255
|
-
}
|
|
256
|
-
} catch {}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
260
|
-
# DIRECTIVE RETRIEVAL: Fetch user's MUST/NEVER/PREFER/AVOID rules
|
|
261
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
262
|
-
if ($authToken) {
|
|
263
|
-
try {
|
|
264
|
-
$directivesResponse = Invoke-RestMethod -Uri "$MemoryApiUrl/api/v1/memory/directives?limit=20" `
|
|
265
|
-
-Method GET -Headers @{ "Authorization" = "Bearer $authToken" } -TimeoutSec 3
|
|
266
|
-
|
|
267
|
-
$directiveCount = $directivesResponse.count
|
|
268
|
-
if ($directiveCount -gt 0) {
|
|
269
|
-
Write-Output "<system-reminder>"
|
|
270
|
-
Write-Output "USER DIRECTIVES (FOLLOW THESE):"
|
|
271
|
-
Write-Output ""
|
|
272
|
-
|
|
273
|
-
foreach ($type in @("MUST", "NEVER", "PREFER", "AVOID")) {
|
|
274
|
-
$rules = $directivesResponse.$type
|
|
275
|
-
if ($rules -and ($rules | Measure-Object).Count -gt 0) {
|
|
276
|
-
Write-Output "${type}:"
|
|
277
|
-
$rules | Select-Object -First 5 | ForEach-Object { Write-Output " - $($_.rule)" }
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
Write-Output "</system-reminder>"
|
|
282
|
-
[Console]::Error.WriteLine("${GREEN} $directiveCount directives loaded${RESET}")
|
|
283
|
-
}
|
|
284
|
-
} catch {}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
288
|
-
# STATUS DISPLAY
|
|
289
|
-
# ═══════════════════════════════════════════════════════════════════════════
|
|
290
|
-
if ($savedTurnCount -gt 0) {
|
|
291
|
-
[Console]::Error.WriteLine("")
|
|
292
|
-
[Console]::Error.WriteLine("${CYAN}${BOLD} ekkOS${RESET} ${DIM}|${RESET} Session: $sessionId ${DIM}|${RESET} ${GREEN}$savedTurnCount turns${RESET}")
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
if ($timeMachineSession) {
|
|
296
|
-
$tmP = $timeMachineSession.Substring(0, [Math]::Min(12, $timeMachineSession.Length))
|
|
297
|
-
[Console]::Error.WriteLine("${MAGENTA}------------------------------------------------------------------------${RESET}")
|
|
298
|
-
[Console]::Error.WriteLine("${MAGENTA} ${RESET} Time Machine active - Restored from session ${tmP}...")
|
|
299
|
-
[Console]::Error.WriteLine("${MAGENTA}------------------------------------------------------------------------${RESET}")
|
|
300
|
-
} elseif ($savedTurnCount -gt 0) {
|
|
301
|
-
[Console]::Error.WriteLine("${GREEN}------------------------------------------------------------------------${RESET}")
|
|
302
|
-
[Console]::Error.WriteLine("${GREEN}✓${RESET} Session continued - $savedTurnCount turns preserved - Ready to resume")
|
|
303
|
-
[Console]::Error.WriteLine("${GREEN}------------------------------------------------------------------------${RESET}")
|
|
304
|
-
} else {
|
|
305
|
-
[Console]::Error.WriteLine("${CYAN}✓${RESET} New session started")
|
|
306
|
-
}
|
|
307
|
-
[Console]::Error.WriteLine("")
|
|
308
|
-
|
|
309
|
-
exit 0
|
|
146
|
+
Write-Output "ekkOS session initialized"
|
|
@@ -78,7 +78,7 @@ fi
|
|
|
78
78
|
|
|
79
79
|
[ -z "$AUTH_TOKEN" ] && exit 0
|
|
80
80
|
|
|
81
|
-
MEMORY_API_URL="https://
|
|
81
|
+
MEMORY_API_URL="https://mcp.ekkos.dev"
|
|
82
82
|
|
|
83
83
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
84
84
|
# TIME MACHINE: Check for pending "Continue from here" requests
|