@blunking/codexlink 0.1.18 → 0.1.19
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 +17 -10
- package/package.json +1 -1
- package/telegram-doctor.ps1 +125 -8
- package/telegram-plugin/lib/bridge.js +6 -4
package/README.md
CHANGED
|
@@ -124,16 +124,23 @@ BLUN_TELEGRAM_OTHER_AGENT_NAMES=frida,angel,dieter,alfred
|
|
|
124
124
|
```
|
|
125
125
|
|
|
126
126
|
Doctor:
|
|
127
|
-
|
|
128
|
-
```powershell
|
|
129
|
-
blun-codex telegram-doctor
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
```powershell
|
|
135
|
-
blun-codex telegram-doctor --
|
|
136
|
-
|
|
127
|
+
|
|
128
|
+
```powershell
|
|
129
|
+
blun-codex telegram-doctor
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Runtime automatisch bereinigen, wenn mehrere Threads geladen sind oder eine alte Bindung klemmt:
|
|
133
|
+
|
|
134
|
+
```powershell
|
|
135
|
+
blun-codex telegram-doctor --fix
|
|
136
|
+
blun-codex telegram-plugin
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
JSON doctor output:
|
|
140
|
+
|
|
141
|
+
```powershell
|
|
142
|
+
blun-codex telegram-doctor --json
|
|
143
|
+
```
|
|
137
144
|
|
|
138
145
|
Dry run:
|
|
139
146
|
|
package/package.json
CHANGED
package/telegram-doctor.ps1
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
param(
|
|
2
|
-
[string]$Profile = "default",
|
|
3
|
-
[switch]$Json
|
|
4
|
-
|
|
1
|
+
param(
|
|
2
|
+
[string]$Profile = "default",
|
|
3
|
+
[switch]$Json,
|
|
4
|
+
[switch]$Fix
|
|
5
|
+
)
|
|
5
6
|
|
|
6
7
|
$ErrorActionPreference = "Stop"
|
|
7
8
|
|
|
8
|
-
function Read-DotEnvFile {
|
|
9
|
+
function Read-DotEnvFile {
|
|
9
10
|
param([string]$Path)
|
|
10
11
|
$values = @{}
|
|
11
12
|
if (-not (Test-Path $Path)) { return $values }
|
|
@@ -133,6 +134,95 @@ function Write-DoctorReport {
|
|
|
133
134
|
}
|
|
134
135
|
}
|
|
135
136
|
|
|
137
|
+
function Write-DotEnvFile {
|
|
138
|
+
param(
|
|
139
|
+
[string]$Path,
|
|
140
|
+
[hashtable]$Values
|
|
141
|
+
)
|
|
142
|
+
$dir = Split-Path -Parent $Path
|
|
143
|
+
if ($dir -and -not (Test-Path $dir)) {
|
|
144
|
+
New-Item -ItemType Directory -Path $dir -Force | Out-Null
|
|
145
|
+
}
|
|
146
|
+
$lines = New-Object 'System.Collections.Generic.List[string]'
|
|
147
|
+
foreach ($key in ($Values.Keys | Sort-Object)) {
|
|
148
|
+
if ([string]::IsNullOrWhiteSpace([string]$key)) { continue }
|
|
149
|
+
$value = [string]$Values[$key]
|
|
150
|
+
$lines.Add($key + "=" + $value) | Out-Null
|
|
151
|
+
}
|
|
152
|
+
Set-Content -Path $Path -Value $lines -Encoding UTF8
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function Stop-PidQuiet {
|
|
156
|
+
param([object]$PidValue)
|
|
157
|
+
$pidText = [string]$PidValue
|
|
158
|
+
if (-not $pidText) { return $false }
|
|
159
|
+
$pidInt = 0
|
|
160
|
+
if (-not [int]::TryParse($pidText, [ref]$pidInt)) { return $false }
|
|
161
|
+
if ($pidInt -le 0) { return $false }
|
|
162
|
+
try {
|
|
163
|
+
Stop-Process -Id $pidInt -Force -ErrorAction Stop
|
|
164
|
+
return $true
|
|
165
|
+
} catch {
|
|
166
|
+
return $false
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function Invoke-RuntimeFix {
|
|
171
|
+
param(
|
|
172
|
+
[object]$Status,
|
|
173
|
+
[string]$RuntimeRoot
|
|
174
|
+
)
|
|
175
|
+
$actions = New-Object 'System.Collections.Generic.List[string]'
|
|
176
|
+
$runtime = $Status.current_runtime
|
|
177
|
+
if ($runtime) {
|
|
178
|
+
$pids = @(
|
|
179
|
+
$runtime.frontend_host_pid,
|
|
180
|
+
$runtime.app_server_pid,
|
|
181
|
+
$runtime.queue_notifier_pid,
|
|
182
|
+
$runtime.poller_pid,
|
|
183
|
+
$runtime.dispatcher_pid,
|
|
184
|
+
$runtime.responder_pid
|
|
185
|
+
) | Where-Object { $_ } | Select-Object -Unique
|
|
186
|
+
foreach ($pidValue in $pids) {
|
|
187
|
+
if (Stop-PidQuiet -PidValue $pidValue) {
|
|
188
|
+
$actions.Add("stopped_pid=" + [string]$pidValue) | Out-Null
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
$runtimeFile = Join-Path $env:USERPROFILE (".codex\runtimes\" + [string]$Status.profile + "\current-remote-runtime.json")
|
|
194
|
+
if (Test-Path $runtimeFile) {
|
|
195
|
+
Remove-Item -LiteralPath $runtimeFile -Force -ErrorAction SilentlyContinue
|
|
196
|
+
$actions.Add("removed_runtime_file") | Out-Null
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
$envFile = Join-Path ([string]$Status.state_dir) ".env"
|
|
200
|
+
$envValues = Read-DotEnvFile -Path $envFile
|
|
201
|
+
if ($envValues.ContainsKey("BLUN_TELEGRAM_THREAD_ID")) {
|
|
202
|
+
$envValues["BLUN_TELEGRAM_THREAD_ID"] = ""
|
|
203
|
+
Write-DotEnvFile -Path $envFile -Values $envValues
|
|
204
|
+
$actions.Add("cleared_env_thread") | Out-Null
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
$stateFile = Join-Path ([string]$Status.state_dir) "state.json"
|
|
208
|
+
if (Test-Path $stateFile) {
|
|
209
|
+
try {
|
|
210
|
+
$state = Get-Content -Raw -Path $stateFile | ConvertFrom-Json
|
|
211
|
+
if ($state.PSObject.Properties.Name.Contains("currentThreadId")) {
|
|
212
|
+
$state.currentThreadId = ""
|
|
213
|
+
} else {
|
|
214
|
+
$state | Add-Member -NotePropertyName "currentThreadId" -NotePropertyValue ""
|
|
215
|
+
}
|
|
216
|
+
$state | ConvertTo-Json -Depth 10 | Set-Content -Path $stateFile -Encoding UTF8
|
|
217
|
+
$actions.Add("cleared_state_thread") | Out-Null
|
|
218
|
+
} catch {
|
|
219
|
+
$actions.Add("state_thread_clear_failed") | Out-Null
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return @($actions)
|
|
224
|
+
}
|
|
225
|
+
|
|
136
226
|
function Get-ProfilePath {
|
|
137
227
|
param(
|
|
138
228
|
[string]$RuntimeRoot,
|
|
@@ -230,6 +320,17 @@ Add-Check -List $checks -Name "allowed_chat_ids" -Status $(if ($allowedChatIds)
|
|
|
230
320
|
Add-Check -List $checks -Name "app_server_ws" -Status $(if ($status.active_ws) { "ok" } else { "warn" }) -Detail $(if ($status.active_ws) { $status.active_ws } else { "No active websocket recorded." })
|
|
231
321
|
Add-Check -List $checks -Name "dispatch_mode" -Status $(if ($status.dispatch_mode -eq "deferred") { "ok" } else { "warn" }) -Detail ("mode=" + [string]$status.dispatch_mode + " cooldown_ms=" + [string]$status.idle_cooldown_ms + " pending_reply_timeout_ms=" + [string]$status.pending_reply_timeout_ms)
|
|
232
322
|
Add-Check -List $checks -Name "bound_thread" -Status $(if ($status.active_thread_id) { "ok" } else { "warn" }) -Detail $(if ($status.active_thread_id) { $status.active_thread_id } else { "No active thread bound yet." })
|
|
323
|
+
$loadedThreads = @($status.loaded_threads | Where-Object { $_ })
|
|
324
|
+
$threadVisibilityStatus = "ok"
|
|
325
|
+
$threadVisibilityDetail = "loaded=" + [string]$loadedThreads.Count
|
|
326
|
+
if ($loadedThreads.Count -gt 1) {
|
|
327
|
+
$threadVisibilityStatus = "warn"
|
|
328
|
+
$threadVisibilityDetail = "multiple loaded threads: " + (($loadedThreads | ForEach-Object { [string]$_ }) -join ",") + ". Run telegram-doctor --fix, then restart telegram-plugin."
|
|
329
|
+
} elseif ($status.active_thread_id -and $loadedThreads.Count -eq 1 -and ([string]$loadedThreads[0]) -ne ([string]$status.active_thread_id)) {
|
|
330
|
+
$threadVisibilityStatus = "warn"
|
|
331
|
+
$threadVisibilityDetail = "bound thread differs from loaded visible thread. Run telegram-doctor --fix, then restart telegram-plugin."
|
|
332
|
+
}
|
|
333
|
+
Add-Check -List $checks -Name "thread_visibility" -Status $threadVisibilityStatus -Detail $threadVisibilityDetail
|
|
233
334
|
Add-Check -List $checks -Name "frontend_owner" -Status $(if ($status.frontend_owner_alive) { "ok" } else { "warn" }) -Detail ("pid=" + [string]$status.frontend_owner_pid + " alive=" + [string]$status.frontend_owner_alive)
|
|
234
335
|
Add-Check -List $checks -Name "queue_notifier" -Status $(if (($null -eq $status.queue_notifier_pid) -or ($status.queue_notifier_alive)) { "ok" } else { "warn" }) -Detail ("pid=" + [string]$status.queue_notifier_pid + " alive=" + [string]$status.queue_notifier_alive)
|
|
235
336
|
Add-Check -List $checks -Name "poller" -Status $(if ($status.poller_alive) { "ok" } else { "warn" }) -Detail ("pid=" + [string]$status.poller_pid + " alive=" + [string]$status.poller_alive)
|
|
@@ -264,15 +365,31 @@ if ($status.last_outbound) {
|
|
|
264
365
|
|
|
265
366
|
Add-Check -List $checks -Name "queue" -Status $(if (([int]$status.queue_depth -eq 0) -and ([int]$status.pending_reply_depth -eq 0)) { "ok" } else { "warn" }) -Detail ("queued=" + $status.queue_depth + " ambient=" + $status.ambient_queue_depth + " parked=" + $status.parked_queue_depth + " submitted=" + $status.submitted_depth + " pending_replies=" + $status.pending_reply_depth + " expired_pending_replies=" + $status.expired_pending_reply_depth)
|
|
266
367
|
|
|
267
|
-
$result = [ordered]@{
|
|
368
|
+
$result = [ordered]@{
|
|
268
369
|
profile = $status.profile
|
|
269
370
|
overall = Get-OverallStatus -Checks $checks
|
|
270
371
|
runtime_root = $runtimeRoot
|
|
271
372
|
state_dir = $status.state_dir
|
|
272
373
|
plugin_root = $status.plugin_root
|
|
273
374
|
checks = $checks
|
|
274
|
-
status = $status
|
|
275
|
-
}
|
|
375
|
+
status = $status
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if ($Fix) {
|
|
379
|
+
$fixActions = Invoke-RuntimeFix -Status $status -RuntimeRoot $runtimeRoot
|
|
380
|
+
$result["fix_actions"] = $fixActions
|
|
381
|
+
if ($Json) {
|
|
382
|
+
$result | ConvertTo-Json -Depth 8
|
|
383
|
+
exit 0
|
|
384
|
+
}
|
|
385
|
+
Write-DoctorReport -Result $result -TokenSource $tokenSource -AllowedChatSource $allowedChatSource
|
|
386
|
+
Write-Host ""
|
|
387
|
+
Write-Host "Fix angewendet. Starte danach neu: blun-codex --profile $($result.profile) telegram-plugin" -ForegroundColor Yellow
|
|
388
|
+
if ($fixActions.Count -gt 0) {
|
|
389
|
+
Write-Host ("Aktionen: " + ($fixActions -join ", ")) -ForegroundColor DarkGray
|
|
390
|
+
}
|
|
391
|
+
exit 0
|
|
392
|
+
}
|
|
276
393
|
|
|
277
394
|
if ($Json) {
|
|
278
395
|
$result | ConvertTo-Json -Depth 8
|
|
@@ -1238,12 +1238,14 @@ function normalizeTelegramThreadId(value) {
|
|
|
1238
1238
|
return String(value || "").trim();
|
|
1239
1239
|
}
|
|
1240
1240
|
|
|
1241
|
-
function isAllowedChat(config,
|
|
1241
|
+
function isAllowedChat(config, inbound) {
|
|
1242
1242
|
const allowed = Array.isArray(config.allowedChatIds) ? config.allowedChatIds : [];
|
|
1243
1243
|
if (allowed.length === 0) {
|
|
1244
1244
|
return true;
|
|
1245
1245
|
}
|
|
1246
|
-
|
|
1246
|
+
const chatId = String(inbound?.chatId || inbound || "").trim();
|
|
1247
|
+
const userId = String(inbound?.userId || "").trim();
|
|
1248
|
+
return allowed.includes(chatId) || (userId && allowed.includes(userId));
|
|
1247
1249
|
}
|
|
1248
1250
|
|
|
1249
1251
|
function splitTelegramText(text, maxLength = 3500) {
|
|
@@ -2125,9 +2127,9 @@ export async function pollOnce() {
|
|
|
2125
2127
|
continue;
|
|
2126
2128
|
}
|
|
2127
2129
|
const inbound = normalizeInbound(update.message);
|
|
2128
|
-
if (!isAllowedChat(config, inbound
|
|
2130
|
+
if (!isAllowedChat(config, inbound)) {
|
|
2129
2131
|
ignored += 1;
|
|
2130
|
-
appendLog(config.paths.activityFile, `IGNORED chat=${inbound.chatId} message=${inbound.messageId}`);
|
|
2132
|
+
appendLog(config.paths.activityFile, `IGNORED chat=${inbound.chatId} user=${inbound.userId || "-"} message=${inbound.messageId}`);
|
|
2131
2133
|
continue;
|
|
2132
2134
|
}
|
|
2133
2135
|
if (String(inbound.chatType || "") === "private" && looksLikeMnemoIdleLoopBrief(inbound.text)) {
|