@blunking/codexlink 0.1.12 → 0.1.14
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 +232 -232
- package/blun-codex.ps1 +140 -140
- package/package.json +40 -40
- package/start-codex-agent.ps1 +727 -727
- package/telegram-doctor.ps1 +214 -214
- package/telegram-plugin/lib/storage.js +25 -25
- package/telegram-setup.ps1 +145 -144
- package/telegram-status.ps1 +256 -256
- package/telegram-title-embed.ps1 +114 -107
- package/telegram-title-watcher.ps1 +109 -103
package/telegram-title-embed.ps1
CHANGED
|
@@ -7,15 +7,15 @@ param(
|
|
|
7
7
|
|
|
8
8
|
[string]$LogFile = ""
|
|
9
9
|
)
|
|
10
|
-
|
|
11
|
-
$ErrorActionPreference = "SilentlyContinue"
|
|
12
|
-
|
|
13
|
-
if (-not ("BlunEmbeddedQueueTitleWatcher" -as [type])) {
|
|
14
|
-
Add-Type -ReferencedAssemblies "System.Web.Extensions" -TypeDefinition @"
|
|
15
|
-
using System;
|
|
16
|
-
using System.Collections;
|
|
17
|
-
using System.Collections.Generic;
|
|
18
|
-
using System.IO;
|
|
10
|
+
|
|
11
|
+
$ErrorActionPreference = "SilentlyContinue"
|
|
12
|
+
|
|
13
|
+
if (-not ("BlunEmbeddedQueueTitleWatcher" -as [type])) {
|
|
14
|
+
Add-Type -ReferencedAssemblies "System.Web.Extensions" -TypeDefinition @"
|
|
15
|
+
using System;
|
|
16
|
+
using System.Collections;
|
|
17
|
+
using System.Collections.Generic;
|
|
18
|
+
using System.IO;
|
|
19
19
|
using System.Threading;
|
|
20
20
|
using System.Web.Script.Serialization;
|
|
21
21
|
|
|
@@ -48,14 +48,14 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
48
48
|
TrySetTitle(_baseTitle);
|
|
49
49
|
if (_timer != null)
|
|
50
50
|
{
|
|
51
|
-
_timer.Dispose();
|
|
52
|
-
}
|
|
53
|
-
_timer = new Timer(_ => Tick(), null, 0, 900);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
private static void Tick()
|
|
58
|
-
{
|
|
51
|
+
_timer.Dispose();
|
|
52
|
+
}
|
|
53
|
+
_timer = new Timer(_ => Tick(), null, 0, 900);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private static void Tick()
|
|
58
|
+
{
|
|
59
59
|
try
|
|
60
60
|
{
|
|
61
61
|
string title;
|
|
@@ -91,15 +91,15 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
91
91
|
WriteLog("TITLE_ERROR");
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
|
-
|
|
95
|
-
private static void TryWriteNotice(string notice)
|
|
96
|
-
{
|
|
97
|
-
var normalized = notice ?? "";
|
|
98
|
-
if (string.Equals(normalized, _lastNotice, StringComparison.Ordinal))
|
|
99
|
-
{
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
94
|
+
|
|
95
|
+
private static void TryWriteNotice(string notice)
|
|
96
|
+
{
|
|
97
|
+
var normalized = notice ?? "";
|
|
98
|
+
if (string.Equals(normalized, _lastNotice, StringComparison.Ordinal))
|
|
99
|
+
{
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
103
|
try
|
|
104
104
|
{
|
|
105
105
|
// Do not write background queue notices into the interactive Codex
|
|
@@ -131,8 +131,15 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
131
131
|
|
|
132
132
|
try
|
|
133
133
|
{
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
var enabled = Environment.GetEnvironmentVariable("BLUN_TELEGRAM_CONSOLE_UI_NOTICES");
|
|
135
|
+
if (string.Equals(enabled, "1", StringComparison.OrdinalIgnoreCase)
|
|
136
|
+
|| string.Equals(enabled, "true", StringComparison.OrdinalIgnoreCase)
|
|
137
|
+
|| string.Equals(enabled, "yes", StringComparison.OrdinalIgnoreCase)
|
|
138
|
+
|| string.Equals(enabled, "on", StringComparison.OrdinalIgnoreCase))
|
|
139
|
+
{
|
|
140
|
+
Console.WriteLine("");
|
|
141
|
+
Console.WriteLine("[Telegram] " + normalized);
|
|
142
|
+
}
|
|
136
143
|
}
|
|
137
144
|
catch
|
|
138
145
|
{
|
|
@@ -154,13 +161,13 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
154
161
|
{
|
|
155
162
|
return;
|
|
156
163
|
}
|
|
157
|
-
|
|
158
|
-
var raw = File.ReadAllText(_stateFile);
|
|
159
|
-
if (string.IsNullOrWhiteSpace(raw))
|
|
160
|
-
{
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
+
|
|
165
|
+
var raw = File.ReadAllText(_stateFile);
|
|
166
|
+
if (string.IsNullOrWhiteSpace(raw))
|
|
167
|
+
{
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
164
171
|
var serializer = new JavaScriptSerializer();
|
|
165
172
|
var root = serializer.DeserializeObject(raw) as Dictionary<string, object>;
|
|
166
173
|
if (root == null || !root.ContainsKey("queue"))
|
|
@@ -210,20 +217,20 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
210
217
|
var entry = item as Dictionary<string, object>;
|
|
211
218
|
if (entry == null)
|
|
212
219
|
{
|
|
213
|
-
continue;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
var status = GetString(entry, "status");
|
|
217
|
-
if (!string.Equals(status, "queued", StringComparison.OrdinalIgnoreCase))
|
|
218
|
-
{
|
|
219
|
-
continue;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
var relevance = GetString(entry, "relevance");
|
|
223
|
-
if (string.Equals(relevance, "ambient", StringComparison.OrdinalIgnoreCase) && IsOlderThan(entry, _ambientTtlMs))
|
|
224
|
-
{
|
|
225
|
-
continue;
|
|
226
|
-
}
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
var status = GetString(entry, "status");
|
|
224
|
+
if (!string.Equals(status, "queued", StringComparison.OrdinalIgnoreCase))
|
|
225
|
+
{
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
var relevance = GetString(entry, "relevance");
|
|
230
|
+
if (string.Equals(relevance, "ambient", StringComparison.OrdinalIgnoreCase) && IsOlderThan(entry, _ambientTtlMs))
|
|
231
|
+
{
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
227
234
|
|
|
228
235
|
total += 1;
|
|
229
236
|
CountRelevance(entry, ref direct, ref ambient, ref escalation);
|
|
@@ -236,8 +243,8 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
236
243
|
|
|
237
244
|
if (total == 0)
|
|
238
245
|
{
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
241
248
|
|
|
242
249
|
var parts = new List<string> { "Q:" + total.ToString() };
|
|
243
250
|
if (pending > 0) parts.Add("P:" + pending.ToString());
|
|
@@ -252,15 +259,15 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
252
259
|
if (direct > 0) noticeParts.Add("direct " + direct.ToString());
|
|
253
260
|
if (ambient > 0) noticeParts.Add("group " + ambient.ToString());
|
|
254
261
|
if (escalation > 0) noticeParts.Add("escalation " + escalation.ToString());
|
|
255
|
-
notice = string.Join(" | ", noticeParts.ToArray());
|
|
256
|
-
if (string.IsNullOrWhiteSpace(preview))
|
|
257
|
-
{
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
title = title + " | " + preview;
|
|
261
|
-
notice = notice + " | " + preview;
|
|
262
|
-
}
|
|
263
|
-
|
|
262
|
+
notice = string.Join(" | ", noticeParts.ToArray());
|
|
263
|
+
if (string.IsNullOrWhiteSpace(preview))
|
|
264
|
+
{
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
title = title + " | " + preview;
|
|
268
|
+
notice = notice + " | " + preview;
|
|
269
|
+
}
|
|
270
|
+
|
|
264
271
|
private static object[] AsObjects(object value)
|
|
265
272
|
{
|
|
266
273
|
var arr = value as object[];
|
|
@@ -273,16 +280,16 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
273
280
|
{
|
|
274
281
|
return list.ToArray();
|
|
275
282
|
}
|
|
276
|
-
return new object[0];
|
|
277
|
-
}
|
|
278
|
-
|
|
283
|
+
return new object[0];
|
|
284
|
+
}
|
|
285
|
+
|
|
279
286
|
private static string GetString(Dictionary<string, object> entry, string key)
|
|
280
287
|
{
|
|
281
|
-
if (!entry.ContainsKey(key) || entry[key] == null)
|
|
282
|
-
{
|
|
283
|
-
return "";
|
|
284
|
-
}
|
|
285
|
-
return Convert.ToString(entry[key]) ?? "";
|
|
288
|
+
if (!entry.ContainsKey(key) || entry[key] == null)
|
|
289
|
+
{
|
|
290
|
+
return "";
|
|
291
|
+
}
|
|
292
|
+
return Convert.ToString(entry[key]) ?? "";
|
|
286
293
|
}
|
|
287
294
|
|
|
288
295
|
private static void CountRelevance(Dictionary<string, object> entry, ref int direct, ref int ambient, ref int escalation)
|
|
@@ -337,7 +344,7 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
337
344
|
}
|
|
338
345
|
return state + text;
|
|
339
346
|
}
|
|
340
|
-
|
|
347
|
+
|
|
341
348
|
private static string Normalize(string value, int maxLength)
|
|
342
349
|
{
|
|
343
350
|
if (string.IsNullOrWhiteSpace(value))
|
|
@@ -350,11 +357,11 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
350
357
|
{
|
|
351
358
|
compact = compact.Replace(" ", " ");
|
|
352
359
|
}
|
|
353
|
-
|
|
354
|
-
if (compact.Length <= maxLength)
|
|
355
|
-
{
|
|
356
|
-
return compact;
|
|
357
|
-
}
|
|
360
|
+
|
|
361
|
+
if (compact.Length <= maxLength)
|
|
362
|
+
{
|
|
363
|
+
return compact;
|
|
364
|
+
}
|
|
358
365
|
|
|
359
366
|
return compact.Substring(0, Math.Max(0, maxLength - 3)).TrimEnd() + "...";
|
|
360
367
|
}
|
|
@@ -384,21 +391,21 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
384
391
|
.Replace("ü", "ü")
|
|
385
392
|
.Replace("ß", "ß");
|
|
386
393
|
}
|
|
387
|
-
|
|
394
|
+
|
|
388
395
|
private static bool IsOlderThan(Dictionary<string, object> entry, long ttlMs)
|
|
389
396
|
{
|
|
390
|
-
if (!entry.ContainsKey("ts") || entry["ts"] == null)
|
|
391
|
-
{
|
|
392
|
-
return true;
|
|
393
|
-
}
|
|
394
|
-
try
|
|
395
|
-
{
|
|
396
|
-
var parsed = DateTimeOffset.Parse(Convert.ToString(entry["ts"]) ?? "");
|
|
397
|
-
return (DateTimeOffset.UtcNow - parsed.ToUniversalTime()).TotalMilliseconds >= ttlMs;
|
|
398
|
-
}
|
|
399
|
-
catch
|
|
400
|
-
{
|
|
401
|
-
return true;
|
|
397
|
+
if (!entry.ContainsKey("ts") || entry["ts"] == null)
|
|
398
|
+
{
|
|
399
|
+
return true;
|
|
400
|
+
}
|
|
401
|
+
try
|
|
402
|
+
{
|
|
403
|
+
var parsed = DateTimeOffset.Parse(Convert.ToString(entry["ts"]) ?? "");
|
|
404
|
+
return (DateTimeOffset.UtcNow - parsed.ToUniversalTime()).TotalMilliseconds >= ttlMs;
|
|
405
|
+
}
|
|
406
|
+
catch
|
|
407
|
+
{
|
|
408
|
+
return true;
|
|
402
409
|
}
|
|
403
410
|
}
|
|
404
411
|
|
|
@@ -419,24 +426,24 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
419
426
|
}
|
|
420
427
|
"@
|
|
421
428
|
}
|
|
422
|
-
|
|
423
|
-
$ambientTtlMs = 600000
|
|
424
|
-
try {
|
|
425
|
-
$stateDir = Split-Path -Parent $StateFile
|
|
426
|
-
$envPath = Join-Path $stateDir ".env"
|
|
427
|
-
if (Test-Path $envPath) {
|
|
428
|
-
foreach ($line in (Get-Content -Path $envPath)) {
|
|
429
|
-
if (-not $line) { continue }
|
|
430
|
-
if ($line.Trim().StartsWith("#")) { continue }
|
|
431
|
-
$parts = $line -split "=", 2
|
|
432
|
-
if ($parts.Count -ne 2) { continue }
|
|
433
|
-
if ($parts[0].Trim() -eq "BLUN_TELEGRAM_AMBIENT_QUEUE_TTL_MS") {
|
|
434
|
-
$ambientTtlMs = [int64]$parts[1].Trim()
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
} catch {
|
|
439
|
-
$ambientTtlMs = 600000
|
|
440
|
-
}
|
|
441
|
-
|
|
429
|
+
|
|
430
|
+
$ambientTtlMs = 600000
|
|
431
|
+
try {
|
|
432
|
+
$stateDir = Split-Path -Parent $StateFile
|
|
433
|
+
$envPath = Join-Path $stateDir ".env"
|
|
434
|
+
if (Test-Path $envPath) {
|
|
435
|
+
foreach ($line in (Get-Content -Path $envPath)) {
|
|
436
|
+
if (-not $line) { continue }
|
|
437
|
+
if ($line.Trim().StartsWith("#")) { continue }
|
|
438
|
+
$parts = $line -split "=", 2
|
|
439
|
+
if ($parts.Count -ne 2) { continue }
|
|
440
|
+
if ($parts[0].Trim() -eq "BLUN_TELEGRAM_AMBIENT_QUEUE_TTL_MS") {
|
|
441
|
+
$ambientTtlMs = [int64]$parts[1].Trim()
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
} catch {
|
|
446
|
+
$ambientTtlMs = 600000
|
|
447
|
+
}
|
|
448
|
+
|
|
442
449
|
[BlunEmbeddedQueueTitleWatcher]::Start($StateFile, $BaseTitle, $ambientTtlMs, $LogFile)
|
|
@@ -6,18 +6,18 @@ param(
|
|
|
6
6
|
|
|
7
7
|
[Parameter(Mandatory = $true)]
|
|
8
8
|
[string]$RuntimeFile,
|
|
9
|
-
|
|
10
|
-
[Parameter(Mandatory = $true)]
|
|
11
|
-
[string]$StateFile,
|
|
12
|
-
|
|
13
|
-
[Parameter(Mandatory = $true)]
|
|
14
|
-
[string]$BaseTitle,
|
|
15
|
-
|
|
16
|
-
[string]$LogFile = ""
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
$ErrorActionPreference = "SilentlyContinue"
|
|
20
|
-
|
|
9
|
+
|
|
10
|
+
[Parameter(Mandatory = $true)]
|
|
11
|
+
[string]$StateFile,
|
|
12
|
+
|
|
13
|
+
[Parameter(Mandatory = $true)]
|
|
14
|
+
[string]$BaseTitle,
|
|
15
|
+
|
|
16
|
+
[string]$LogFile = ""
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
$ErrorActionPreference = "SilentlyContinue"
|
|
20
|
+
|
|
21
21
|
if (-not ("CodexLink.NativeMethods" -as [type])) {
|
|
22
22
|
Add-Type -TypeDefinition @"
|
|
23
23
|
using System;
|
|
@@ -45,28 +45,28 @@ namespace CodexLink
|
|
|
45
45
|
}
|
|
46
46
|
"@
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
function Try-ReadJson {
|
|
50
|
-
param([string]$Path)
|
|
51
|
-
if (-not (Test-Path $Path)) { return $null }
|
|
52
|
-
try {
|
|
53
|
-
$raw = Get-Content -Raw -Path $Path
|
|
54
|
-
if ($null -eq $raw) { return $null }
|
|
55
|
-
return ($raw -replace "^\uFEFF", "") | ConvertFrom-Json
|
|
56
|
-
} catch {
|
|
57
|
-
return $null
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function Write-WatcherLog {
|
|
62
|
-
param([string]$Message)
|
|
63
|
-
if (-not $LogFile) { return }
|
|
64
|
-
try {
|
|
65
|
-
Add-Content -Path $LogFile -Value (((Get-Date).ToUniversalTime().ToString("o")) + " " + $Message) -Encoding UTF8
|
|
66
|
-
} catch {
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
48
|
+
|
|
49
|
+
function Try-ReadJson {
|
|
50
|
+
param([string]$Path)
|
|
51
|
+
if (-not (Test-Path $Path)) { return $null }
|
|
52
|
+
try {
|
|
53
|
+
$raw = Get-Content -Raw -Path $Path
|
|
54
|
+
if ($null -eq $raw) { return $null }
|
|
55
|
+
return ($raw -replace "^\uFEFF", "") | ConvertFrom-Json
|
|
56
|
+
} catch {
|
|
57
|
+
return $null
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function Write-WatcherLog {
|
|
62
|
+
param([string]$Message)
|
|
63
|
+
if (-not $LogFile) { return }
|
|
64
|
+
try {
|
|
65
|
+
Add-Content -Path $LogFile -Value (((Get-Date).ToUniversalTime().ToString("o")) + " " + $Message) -Encoding UTF8
|
|
66
|
+
} catch {
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
70
|
function Test-PidAlive {
|
|
71
71
|
param([int]$ProcId)
|
|
72
72
|
if ($ProcId -le 0) { return $false }
|
|
@@ -103,14 +103,14 @@ function Get-EffectiveAttachPid {
|
|
|
103
103
|
|
|
104
104
|
return 0
|
|
105
105
|
}
|
|
106
|
-
|
|
106
|
+
|
|
107
107
|
function Normalize-Preview {
|
|
108
108
|
param([string]$Value, [int]$MaxLength = 44)
|
|
109
|
-
$text = [string]$Value
|
|
110
|
-
$text = $text -replace "\s+", " "
|
|
111
|
-
$text = $text.Trim()
|
|
112
|
-
if (-not $text) { return "" }
|
|
113
|
-
if ($text.Length -le $MaxLength) { return $text }
|
|
109
|
+
$text = [string]$Value
|
|
110
|
+
$text = $text -replace "\s+", " "
|
|
111
|
+
$text = $text.Trim()
|
|
112
|
+
if (-not $text) { return "" }
|
|
113
|
+
if ($text.Length -le $MaxLength) { return $text }
|
|
114
114
|
return ($text.Substring(0, [Math]::Max(0, $MaxLength - 3)).TrimEnd() + "...")
|
|
115
115
|
}
|
|
116
116
|
|
|
@@ -178,18 +178,18 @@ function Format-QueuePreview {
|
|
|
178
178
|
}
|
|
179
179
|
return "${prefix}${text}"
|
|
180
180
|
}
|
|
181
|
-
|
|
181
|
+
|
|
182
182
|
function Get-QueueTitle {
|
|
183
183
|
param(
|
|
184
184
|
[object]$State,
|
|
185
185
|
[string]$FallbackTitle,
|
|
186
186
|
[int]$IdleCooldownMs = 15000
|
|
187
187
|
)
|
|
188
|
-
|
|
189
|
-
if ($null -eq $State -or $null -eq $State.queue) {
|
|
190
|
-
return $FallbackTitle
|
|
191
|
-
}
|
|
192
|
-
|
|
188
|
+
|
|
189
|
+
if ($null -eq $State -or $null -eq $State.queue) {
|
|
190
|
+
return $FallbackTitle
|
|
191
|
+
}
|
|
192
|
+
|
|
193
193
|
$queued = @($State.queue | Where-Object { $_.status -eq "queued" })
|
|
194
194
|
$pendingReplies = @(Get-OpenPendingReplies -State $State)
|
|
195
195
|
$totalWaiting = $queued.Count + $pendingReplies.Count
|
|
@@ -212,8 +212,8 @@ function Get-QueueTitle {
|
|
|
212
212
|
if ($pendingCount -gt 0) { $parts += "P:$pendingCount" }
|
|
213
213
|
if ($directCount -gt 0) { $parts += "D:$directCount" }
|
|
214
214
|
if ($ambientCount -gt 0) { $parts += "G:$ambientCount" }
|
|
215
|
-
if ($escalationCount -gt 0) { $parts += "E:$escalationCount" }
|
|
216
|
-
|
|
215
|
+
if ($escalationCount -gt 0) { $parts += "E:$escalationCount" }
|
|
216
|
+
|
|
217
217
|
$summary = ($parts -join " ")
|
|
218
218
|
$waitReason = Get-QueueWaitReason -State $State -IdleCooldownMs $IdleCooldownMs
|
|
219
219
|
if ($preview) {
|
|
@@ -221,7 +221,7 @@ function Get-QueueTitle {
|
|
|
221
221
|
}
|
|
222
222
|
return "$FallbackTitle | $summary | $waitReason"
|
|
223
223
|
}
|
|
224
|
-
|
|
224
|
+
|
|
225
225
|
function Update-ConsoleTitle {
|
|
226
226
|
param([string]$Title)
|
|
227
227
|
try {
|
|
@@ -235,11 +235,11 @@ function Update-ConsoleTitle {
|
|
|
235
235
|
$updated = [CodexLink.NativeMethods]::SetConsoleTitle($Title)
|
|
236
236
|
[void][CodexLink.NativeMethods]::FreeConsole()
|
|
237
237
|
return $updated
|
|
238
|
-
} catch {
|
|
239
|
-
return $false
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
238
|
+
} catch {
|
|
239
|
+
return $false
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
243
|
function Write-ConsoleNotice {
|
|
244
244
|
param([string]$Notice)
|
|
245
245
|
if ($env:BLUN_TELEGRAM_CONSOLE_NOTICES -ne "1") {
|
|
@@ -253,15 +253,15 @@ function Write-ConsoleNotice {
|
|
|
253
253
|
Write-WatcherLog ("WAIT attach_console_failed_notice target=" + $targetPid)
|
|
254
254
|
return $false
|
|
255
255
|
}
|
|
256
|
-
$handle = [CodexLink.NativeMethods]::GetStdHandle(-11)
|
|
257
|
-
if ($handle -eq [IntPtr]::Zero -or $handle -eq [IntPtr](-1)) {
|
|
258
|
-
[void][CodexLink.NativeMethods]::FreeConsole()
|
|
259
|
-
return $false
|
|
260
|
-
}
|
|
261
|
-
$line = "[CodexLink Queue] $Notice`r`n"
|
|
262
|
-
[uint32]$written = 0
|
|
263
|
-
$ok = [CodexLink.NativeMethods]::WriteConsole($handle, $line, [uint32]$line.Length, [ref]$written, [IntPtr]::Zero)
|
|
264
|
-
[void][CodexLink.NativeMethods]::FreeConsole()
|
|
256
|
+
$handle = [CodexLink.NativeMethods]::GetStdHandle(-11)
|
|
257
|
+
if ($handle -eq [IntPtr]::Zero -or $handle -eq [IntPtr](-1)) {
|
|
258
|
+
[void][CodexLink.NativeMethods]::FreeConsole()
|
|
259
|
+
return $false
|
|
260
|
+
}
|
|
261
|
+
$line = "[CodexLink Queue] $Notice`r`n"
|
|
262
|
+
[uint32]$written = 0
|
|
263
|
+
$ok = [CodexLink.NativeMethods]::WriteConsole($handle, $line, [uint32]$line.Length, [ref]$written, [IntPtr]::Zero)
|
|
264
|
+
[void][CodexLink.NativeMethods]::FreeConsole()
|
|
265
265
|
return $ok
|
|
266
266
|
} catch {
|
|
267
267
|
return $false
|
|
@@ -273,6 +273,12 @@ function Write-ConsoleUiNotice {
|
|
|
273
273
|
[string]$Kind,
|
|
274
274
|
[string]$Notice
|
|
275
275
|
)
|
|
276
|
+
if ($env:BLUN_TELEGRAM_CONSOLE_UI_NOTICES -ne "1" -and
|
|
277
|
+
$env:BLUN_TELEGRAM_CONSOLE_UI_NOTICES -ine "true" -and
|
|
278
|
+
$env:BLUN_TELEGRAM_CONSOLE_UI_NOTICES -ine "yes" -and
|
|
279
|
+
$env:BLUN_TELEGRAM_CONSOLE_UI_NOTICES -ine "on") {
|
|
280
|
+
return $false
|
|
281
|
+
}
|
|
276
282
|
try {
|
|
277
283
|
[void][CodexLink.NativeMethods]::FreeConsole()
|
|
278
284
|
$targetPid = Get-EffectiveAttachPid
|
|
@@ -318,17 +324,17 @@ function Get-UiNoticeSnapshot {
|
|
|
318
324
|
text = $text
|
|
319
325
|
}
|
|
320
326
|
}
|
|
321
|
-
|
|
327
|
+
|
|
322
328
|
function Get-QueueNotice {
|
|
323
329
|
param(
|
|
324
330
|
[object]$State,
|
|
325
331
|
[int]$IdleCooldownMs = 15000
|
|
326
332
|
)
|
|
327
|
-
|
|
328
|
-
if ($null -eq $State -or $null -eq $State.queue) {
|
|
329
|
-
return ""
|
|
330
|
-
}
|
|
331
|
-
|
|
333
|
+
|
|
334
|
+
if ($null -eq $State -or $null -eq $State.queue) {
|
|
335
|
+
return ""
|
|
336
|
+
}
|
|
337
|
+
|
|
332
338
|
$queued = @($State.queue | Where-Object { $_.status -eq "queued" })
|
|
333
339
|
$pendingReplies = @(Get-OpenPendingReplies -State $State)
|
|
334
340
|
$totalWaiting = $queued.Count + $pendingReplies.Count
|
|
@@ -365,7 +371,7 @@ function Get-QueueNotice {
|
|
|
365
371
|
$parts += $preview
|
|
366
372
|
}
|
|
367
373
|
}
|
|
368
|
-
|
|
374
|
+
|
|
369
375
|
return ($parts -join " | ")
|
|
370
376
|
}
|
|
371
377
|
|
|
@@ -396,48 +402,48 @@ $lastNotice = ""
|
|
|
396
402
|
$lastUiKind = ""
|
|
397
403
|
$lastUiNotice = ""
|
|
398
404
|
Write-WatcherLog "START"
|
|
399
|
-
|
|
400
|
-
while ($true) {
|
|
401
|
-
if (-not (Test-PidAlive -ProcId $FrontendPid)) {
|
|
402
|
-
Write-WatcherLog "EXIT frontend_dead"
|
|
403
|
-
break
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
$runtime = Try-ReadJson -Path $RuntimeFile
|
|
407
|
-
if ($null -eq $runtime) {
|
|
408
|
-
Write-WatcherLog "WAIT runtime_missing"
|
|
409
|
-
Start-Sleep -Milliseconds 300
|
|
410
|
-
continue
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
$runtimeOwnerPid = 0
|
|
414
|
-
try { $runtimeOwnerPid = [int]$runtime.frontend_host_pid } catch { $runtimeOwnerPid = 0 }
|
|
415
|
-
if ($runtimeOwnerPid -ne $FrontendPid) {
|
|
416
|
-
Write-WatcherLog ("EXIT owner_changed owner=" + $runtimeOwnerPid)
|
|
417
|
-
break
|
|
418
|
-
}
|
|
419
|
-
|
|
405
|
+
|
|
406
|
+
while ($true) {
|
|
407
|
+
if (-not (Test-PidAlive -ProcId $FrontendPid)) {
|
|
408
|
+
Write-WatcherLog "EXIT frontend_dead"
|
|
409
|
+
break
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
$runtime = Try-ReadJson -Path $RuntimeFile
|
|
413
|
+
if ($null -eq $runtime) {
|
|
414
|
+
Write-WatcherLog "WAIT runtime_missing"
|
|
415
|
+
Start-Sleep -Milliseconds 300
|
|
416
|
+
continue
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
$runtimeOwnerPid = 0
|
|
420
|
+
try { $runtimeOwnerPid = [int]$runtime.frontend_host_pid } catch { $runtimeOwnerPid = 0 }
|
|
421
|
+
if ($runtimeOwnerPid -ne $FrontendPid) {
|
|
422
|
+
Write-WatcherLog ("EXIT owner_changed owner=" + $runtimeOwnerPid)
|
|
423
|
+
break
|
|
424
|
+
}
|
|
425
|
+
|
|
420
426
|
$state = Try-ReadJson -Path $StateFile
|
|
421
427
|
if ($null -eq $state) {
|
|
422
428
|
Write-WatcherLog "WAIT state_missing"
|
|
423
|
-
Start-Sleep -Milliseconds 700
|
|
424
|
-
continue
|
|
425
|
-
}
|
|
426
|
-
|
|
429
|
+
Start-Sleep -Milliseconds 700
|
|
430
|
+
continue
|
|
431
|
+
}
|
|
432
|
+
|
|
427
433
|
$title = Get-QueueTitle -State $state -FallbackTitle $BaseTitle -IdleCooldownMs $idleCooldownMs
|
|
428
434
|
$notice = Get-QueueNotice -State $state -IdleCooldownMs $idleCooldownMs
|
|
429
435
|
$ui = Get-UiNoticeSnapshot -State $state
|
|
430
436
|
if ($title -ne $lastTitle) {
|
|
431
437
|
$updated = Update-ConsoleTitle -Title $title
|
|
432
438
|
Write-WatcherLog ("TITLE updated=" + $updated + " text=" + $title)
|
|
433
|
-
$lastTitle = $title
|
|
434
|
-
}
|
|
435
|
-
if ($notice -ne $lastNotice) {
|
|
436
|
-
if ($notice) {
|
|
437
|
-
$noticeUpdated = Write-ConsoleNotice -Notice $notice
|
|
438
|
-
Write-WatcherLog ("NOTICE updated=" + $noticeUpdated + " text=" + $notice)
|
|
439
|
-
} else {
|
|
440
|
-
Write-WatcherLog "NOTICE clear"
|
|
439
|
+
$lastTitle = $title
|
|
440
|
+
}
|
|
441
|
+
if ($notice -ne $lastNotice) {
|
|
442
|
+
if ($notice) {
|
|
443
|
+
$noticeUpdated = Write-ConsoleNotice -Notice $notice
|
|
444
|
+
Write-WatcherLog ("NOTICE updated=" + $noticeUpdated + " text=" + $notice)
|
|
445
|
+
} else {
|
|
446
|
+
Write-WatcherLog "NOTICE clear"
|
|
441
447
|
}
|
|
442
448
|
$lastNotice = $notice
|
|
443
449
|
}
|