@blunking/codexlink 0.1.19 → 0.1.20
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 +222 -220
- package/blun-codex.ps1 +140 -140
- package/package.json +37 -37
- package/start-codex-agent.ps1 +715 -715
- package/telegram-doctor.ps1 +205 -205
- package/telegram-plugin/lib/bridge.js +14 -1
- package/telegram-plugin/lib/storage.js +25 -25
- package/telegram-setup.ps1 +143 -143
- package/telegram-status.ps1 +256 -256
- package/telegram-title-embed.ps1 +98 -98
- package/telegram-title-watcher.ps1 +102 -102
package/telegram-title-embed.ps1
CHANGED
|
@@ -7,7 +7,7 @@ param(
|
|
|
7
7
|
|
|
8
8
|
[string]$LogFile = ""
|
|
9
9
|
)
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
$ErrorActionPreference = "SilentlyContinue"
|
|
12
12
|
|
|
13
13
|
function Stop-EmbeddedQueueTitleWatcher {
|
|
@@ -35,9 +35,9 @@ Stop-EmbeddedQueueTitleWatcher -TypeName "BlunEmbeddedQueueTitleWatcherQueueOnly
|
|
|
35
35
|
if (-not ("BlunEmbeddedQueueTitleWatcherQueueOnlyV2" -as [type])) {
|
|
36
36
|
Add-Type -ReferencedAssemblies "System.Web.Extensions" -TypeDefinition @"
|
|
37
37
|
using System;
|
|
38
|
-
using System.Collections;
|
|
39
|
-
using System.Collections.Generic;
|
|
40
|
-
using System.IO;
|
|
38
|
+
using System.Collections;
|
|
39
|
+
using System.Collections.Generic;
|
|
40
|
+
using System.IO;
|
|
41
41
|
using System.Threading;
|
|
42
42
|
using System.Web.Script.Serialization;
|
|
43
43
|
|
|
@@ -74,14 +74,14 @@ public static class BlunEmbeddedQueueTitleWatcherQueueOnlyV2
|
|
|
74
74
|
TrySetTitle(_baseTitle);
|
|
75
75
|
if (_timer != null)
|
|
76
76
|
{
|
|
77
|
-
_timer.Dispose();
|
|
78
|
-
}
|
|
79
|
-
_timer = new Timer(_ => Tick(), null, 0, 900);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
private static void Tick()
|
|
84
|
-
{
|
|
77
|
+
_timer.Dispose();
|
|
78
|
+
}
|
|
79
|
+
_timer = new Timer(_ => Tick(), null, 0, 900);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private static void Tick()
|
|
84
|
+
{
|
|
85
85
|
try
|
|
86
86
|
{
|
|
87
87
|
string title;
|
|
@@ -117,15 +117,15 @@ public static class BlunEmbeddedQueueTitleWatcherQueueOnlyV2
|
|
|
117
117
|
WriteLog("TITLE_ERROR");
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
-
|
|
121
|
-
private static void TryWriteNotice(string notice)
|
|
122
|
-
{
|
|
123
|
-
var normalized = notice ?? "";
|
|
124
|
-
if (string.Equals(normalized, _lastNotice, StringComparison.Ordinal))
|
|
125
|
-
{
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
|
|
120
|
+
|
|
121
|
+
private static void TryWriteNotice(string notice)
|
|
122
|
+
{
|
|
123
|
+
var normalized = notice ?? "";
|
|
124
|
+
if (string.Equals(normalized, _lastNotice, StringComparison.Ordinal))
|
|
125
|
+
{
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
129
|
try
|
|
130
130
|
{
|
|
131
131
|
// Do not write background queue notices into the interactive Codex
|
|
@@ -275,13 +275,13 @@ public static class BlunEmbeddedQueueTitleWatcherQueueOnlyV2
|
|
|
275
275
|
{
|
|
276
276
|
return;
|
|
277
277
|
}
|
|
278
|
-
|
|
279
|
-
var raw = File.ReadAllText(_stateFile);
|
|
280
|
-
if (string.IsNullOrWhiteSpace(raw))
|
|
281
|
-
{
|
|
282
|
-
return;
|
|
283
|
-
}
|
|
284
|
-
|
|
278
|
+
|
|
279
|
+
var raw = File.ReadAllText(_stateFile);
|
|
280
|
+
if (string.IsNullOrWhiteSpace(raw))
|
|
281
|
+
{
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
285
|
var serializer = new JavaScriptSerializer();
|
|
286
286
|
var root = serializer.DeserializeObject(raw) as Dictionary<string, object>;
|
|
287
287
|
if (root == null || !root.ContainsKey("queue"))
|
|
@@ -311,20 +311,20 @@ public static class BlunEmbeddedQueueTitleWatcherQueueOnlyV2
|
|
|
311
311
|
var entry = item as Dictionary<string, object>;
|
|
312
312
|
if (entry == null)
|
|
313
313
|
{
|
|
314
|
-
continue;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
var status = GetString(entry, "status");
|
|
318
|
-
if (!string.Equals(status, "queued", StringComparison.OrdinalIgnoreCase))
|
|
319
|
-
{
|
|
320
|
-
continue;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
var relevance = GetString(entry, "relevance");
|
|
324
|
-
if (string.Equals(relevance, "ambient", StringComparison.OrdinalIgnoreCase) && IsOlderThan(entry, _ambientTtlMs))
|
|
325
|
-
{
|
|
326
|
-
continue;
|
|
327
|
-
}
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
var status = GetString(entry, "status");
|
|
318
|
+
if (!string.Equals(status, "queued", StringComparison.OrdinalIgnoreCase))
|
|
319
|
+
{
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
var relevance = GetString(entry, "relevance");
|
|
324
|
+
if (string.Equals(relevance, "ambient", StringComparison.OrdinalIgnoreCase) && IsOlderThan(entry, _ambientTtlMs))
|
|
325
|
+
{
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
328
|
|
|
329
329
|
total += 1;
|
|
330
330
|
CountRelevance(entry, ref direct, ref ambient, ref escalation);
|
|
@@ -337,8 +337,8 @@ public static class BlunEmbeddedQueueTitleWatcherQueueOnlyV2
|
|
|
337
337
|
|
|
338
338
|
if (total == 0)
|
|
339
339
|
{
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
342
|
|
|
343
343
|
var parts = new List<string> { "Q:" + total.ToString() };
|
|
344
344
|
if (direct > 0) parts.Add("D:" + direct.ToString());
|
|
@@ -351,15 +351,15 @@ public static class BlunEmbeddedQueueTitleWatcherQueueOnlyV2
|
|
|
351
351
|
if (direct > 0) noticeParts.Add("direct " + direct.ToString());
|
|
352
352
|
if (ambient > 0) noticeParts.Add("group " + ambient.ToString());
|
|
353
353
|
if (escalation > 0) noticeParts.Add("escalation " + escalation.ToString());
|
|
354
|
-
notice = string.Join(" | ", noticeParts.ToArray());
|
|
355
|
-
if (string.IsNullOrWhiteSpace(preview))
|
|
356
|
-
{
|
|
357
|
-
return;
|
|
358
|
-
}
|
|
354
|
+
notice = string.Join(" | ", noticeParts.ToArray());
|
|
355
|
+
if (string.IsNullOrWhiteSpace(preview))
|
|
356
|
+
{
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
359
|
title = title + " | " + preview;
|
|
360
360
|
notice = notice + " | " + preview;
|
|
361
|
-
}
|
|
362
|
-
|
|
361
|
+
}
|
|
362
|
+
|
|
363
363
|
private static object[] AsObjects(object value)
|
|
364
364
|
{
|
|
365
365
|
var arr = value as object[];
|
|
@@ -372,16 +372,16 @@ public static class BlunEmbeddedQueueTitleWatcherQueueOnlyV2
|
|
|
372
372
|
{
|
|
373
373
|
return list.ToArray();
|
|
374
374
|
}
|
|
375
|
-
return new object[0];
|
|
376
|
-
}
|
|
377
|
-
|
|
375
|
+
return new object[0];
|
|
376
|
+
}
|
|
377
|
+
|
|
378
378
|
private static string GetString(Dictionary<string, object> entry, string key)
|
|
379
379
|
{
|
|
380
|
-
if (!entry.ContainsKey(key) || entry[key] == null)
|
|
381
|
-
{
|
|
382
|
-
return "";
|
|
383
|
-
}
|
|
384
|
-
return Convert.ToString(entry[key]) ?? "";
|
|
380
|
+
if (!entry.ContainsKey(key) || entry[key] == null)
|
|
381
|
+
{
|
|
382
|
+
return "";
|
|
383
|
+
}
|
|
384
|
+
return Convert.ToString(entry[key]) ?? "";
|
|
385
385
|
}
|
|
386
386
|
|
|
387
387
|
private static void CountRelevance(Dictionary<string, object> entry, ref int direct, ref int ambient, ref int escalation)
|
|
@@ -436,7 +436,7 @@ public static class BlunEmbeddedQueueTitleWatcherQueueOnlyV2
|
|
|
436
436
|
}
|
|
437
437
|
return state + text;
|
|
438
438
|
}
|
|
439
|
-
|
|
439
|
+
|
|
440
440
|
private static string Normalize(string value, int maxLength)
|
|
441
441
|
{
|
|
442
442
|
if (string.IsNullOrWhiteSpace(value))
|
|
@@ -449,11 +449,11 @@ public static class BlunEmbeddedQueueTitleWatcherQueueOnlyV2
|
|
|
449
449
|
{
|
|
450
450
|
compact = compact.Replace(" ", " ");
|
|
451
451
|
}
|
|
452
|
-
|
|
453
|
-
if (compact.Length <= maxLength)
|
|
454
|
-
{
|
|
455
|
-
return compact;
|
|
456
|
-
}
|
|
452
|
+
|
|
453
|
+
if (compact.Length <= maxLength)
|
|
454
|
+
{
|
|
455
|
+
return compact;
|
|
456
|
+
}
|
|
457
457
|
|
|
458
458
|
return compact.Substring(0, Math.Max(0, maxLength - 3)).TrimEnd() + "...";
|
|
459
459
|
}
|
|
@@ -483,21 +483,21 @@ public static class BlunEmbeddedQueueTitleWatcherQueueOnlyV2
|
|
|
483
483
|
.Replace("ü", "ü")
|
|
484
484
|
.Replace("ß", "ß");
|
|
485
485
|
}
|
|
486
|
-
|
|
486
|
+
|
|
487
487
|
private static bool IsOlderThan(Dictionary<string, object> entry, long ttlMs)
|
|
488
488
|
{
|
|
489
|
-
if (!entry.ContainsKey("ts") || entry["ts"] == null)
|
|
490
|
-
{
|
|
491
|
-
return true;
|
|
492
|
-
}
|
|
493
|
-
try
|
|
494
|
-
{
|
|
495
|
-
var parsed = DateTimeOffset.Parse(Convert.ToString(entry["ts"]) ?? "");
|
|
496
|
-
return (DateTimeOffset.UtcNow - parsed.ToUniversalTime()).TotalMilliseconds >= ttlMs;
|
|
497
|
-
}
|
|
498
|
-
catch
|
|
499
|
-
{
|
|
500
|
-
return true;
|
|
489
|
+
if (!entry.ContainsKey("ts") || entry["ts"] == null)
|
|
490
|
+
{
|
|
491
|
+
return true;
|
|
492
|
+
}
|
|
493
|
+
try
|
|
494
|
+
{
|
|
495
|
+
var parsed = DateTimeOffset.Parse(Convert.ToString(entry["ts"]) ?? "");
|
|
496
|
+
return (DateTimeOffset.UtcNow - parsed.ToUniversalTime()).TotalMilliseconds >= ttlMs;
|
|
497
|
+
}
|
|
498
|
+
catch
|
|
499
|
+
{
|
|
500
|
+
return true;
|
|
501
501
|
}
|
|
502
502
|
}
|
|
503
503
|
|
|
@@ -518,24 +518,24 @@ public static class BlunEmbeddedQueueTitleWatcherQueueOnlyV2
|
|
|
518
518
|
}
|
|
519
519
|
"@
|
|
520
520
|
}
|
|
521
|
-
|
|
522
|
-
$ambientTtlMs = 600000
|
|
523
|
-
try {
|
|
524
|
-
$stateDir = Split-Path -Parent $StateFile
|
|
525
|
-
$envPath = Join-Path $stateDir ".env"
|
|
526
|
-
if (Test-Path $envPath) {
|
|
527
|
-
foreach ($line in (Get-Content -Path $envPath)) {
|
|
528
|
-
if (-not $line) { continue }
|
|
529
|
-
if ($line.Trim().StartsWith("#")) { continue }
|
|
530
|
-
$parts = $line -split "=", 2
|
|
531
|
-
if ($parts.Count -ne 2) { continue }
|
|
532
|
-
if ($parts[0].Trim() -eq "BLUN_TELEGRAM_AMBIENT_QUEUE_TTL_MS") {
|
|
533
|
-
$ambientTtlMs = [int64]$parts[1].Trim()
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
} catch {
|
|
538
|
-
$ambientTtlMs = 600000
|
|
539
|
-
}
|
|
540
|
-
|
|
521
|
+
|
|
522
|
+
$ambientTtlMs = 600000
|
|
523
|
+
try {
|
|
524
|
+
$stateDir = Split-Path -Parent $StateFile
|
|
525
|
+
$envPath = Join-Path $stateDir ".env"
|
|
526
|
+
if (Test-Path $envPath) {
|
|
527
|
+
foreach ($line in (Get-Content -Path $envPath)) {
|
|
528
|
+
if (-not $line) { continue }
|
|
529
|
+
if ($line.Trim().StartsWith("#")) { continue }
|
|
530
|
+
$parts = $line -split "=", 2
|
|
531
|
+
if ($parts.Count -ne 2) { continue }
|
|
532
|
+
if ($parts[0].Trim() -eq "BLUN_TELEGRAM_AMBIENT_QUEUE_TTL_MS") {
|
|
533
|
+
$ambientTtlMs = [int64]$parts[1].Trim()
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
} catch {
|
|
538
|
+
$ambientTtlMs = 600000
|
|
539
|
+
}
|
|
540
|
+
|
|
541
541
|
[BlunEmbeddedQueueTitleWatcherQueueOnlyV2]::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
|
if ($queued.Count -eq 0) {
|
|
195
195
|
return $FallbackTitle
|
|
@@ -208,7 +208,7 @@ function Get-QueueTitle {
|
|
|
208
208
|
if ($directCount -gt 0) { $parts += "D:$directCount" }
|
|
209
209
|
if ($ambientCount -gt 0) { $parts += "G:$ambientCount" }
|
|
210
210
|
if ($escalationCount -gt 0) { $parts += "E:$escalationCount" }
|
|
211
|
-
|
|
211
|
+
|
|
212
212
|
$summary = ($parts -join " ")
|
|
213
213
|
$waitReason = Get-QueueWaitReason -State $State -IdleCooldownMs $IdleCooldownMs
|
|
214
214
|
if ($preview) {
|
|
@@ -216,7 +216,7 @@ function Get-QueueTitle {
|
|
|
216
216
|
}
|
|
217
217
|
return "$FallbackTitle | $summary | $waitReason"
|
|
218
218
|
}
|
|
219
|
-
|
|
219
|
+
|
|
220
220
|
function Update-ConsoleTitle {
|
|
221
221
|
param([string]$Title)
|
|
222
222
|
try {
|
|
@@ -230,11 +230,11 @@ function Update-ConsoleTitle {
|
|
|
230
230
|
$updated = [CodexLink.NativeMethods]::SetConsoleTitle($Title)
|
|
231
231
|
[void][CodexLink.NativeMethods]::FreeConsole()
|
|
232
232
|
return $updated
|
|
233
|
-
} catch {
|
|
234
|
-
return $false
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
233
|
+
} catch {
|
|
234
|
+
return $false
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
238
|
function Write-ConsoleNotice {
|
|
239
239
|
param([string]$Notice)
|
|
240
240
|
if ($env:BLUN_TELEGRAM_CONSOLE_NOTICES -ne "1") {
|
|
@@ -248,15 +248,15 @@ function Write-ConsoleNotice {
|
|
|
248
248
|
Write-WatcherLog ("WAIT attach_console_failed_notice target=" + $targetPid)
|
|
249
249
|
return $false
|
|
250
250
|
}
|
|
251
|
-
$handle = [CodexLink.NativeMethods]::GetStdHandle(-11)
|
|
252
|
-
if ($handle -eq [IntPtr]::Zero -or $handle -eq [IntPtr](-1)) {
|
|
253
|
-
[void][CodexLink.NativeMethods]::FreeConsole()
|
|
254
|
-
return $false
|
|
255
|
-
}
|
|
256
|
-
$line = "[CodexLink Queue] $Notice`r`n"
|
|
257
|
-
[uint32]$written = 0
|
|
258
|
-
$ok = [CodexLink.NativeMethods]::WriteConsole($handle, $line, [uint32]$line.Length, [ref]$written, [IntPtr]::Zero)
|
|
259
|
-
[void][CodexLink.NativeMethods]::FreeConsole()
|
|
251
|
+
$handle = [CodexLink.NativeMethods]::GetStdHandle(-11)
|
|
252
|
+
if ($handle -eq [IntPtr]::Zero -or $handle -eq [IntPtr](-1)) {
|
|
253
|
+
[void][CodexLink.NativeMethods]::FreeConsole()
|
|
254
|
+
return $false
|
|
255
|
+
}
|
|
256
|
+
$line = "[CodexLink Queue] $Notice`r`n"
|
|
257
|
+
[uint32]$written = 0
|
|
258
|
+
$ok = [CodexLink.NativeMethods]::WriteConsole($handle, $line, [uint32]$line.Length, [ref]$written, [IntPtr]::Zero)
|
|
259
|
+
[void][CodexLink.NativeMethods]::FreeConsole()
|
|
260
260
|
return $ok
|
|
261
261
|
} catch {
|
|
262
262
|
return $false
|
|
@@ -320,17 +320,17 @@ function Get-UiNoticeSnapshot {
|
|
|
320
320
|
text = $text
|
|
321
321
|
}
|
|
322
322
|
}
|
|
323
|
-
|
|
323
|
+
|
|
324
324
|
function Get-QueueNotice {
|
|
325
325
|
param(
|
|
326
326
|
[object]$State,
|
|
327
327
|
[int]$IdleCooldownMs = 15000
|
|
328
328
|
)
|
|
329
|
-
|
|
330
|
-
if ($null -eq $State -or $null -eq $State.queue) {
|
|
331
|
-
return ""
|
|
332
|
-
}
|
|
333
|
-
|
|
329
|
+
|
|
330
|
+
if ($null -eq $State -or $null -eq $State.queue) {
|
|
331
|
+
return ""
|
|
332
|
+
}
|
|
333
|
+
|
|
334
334
|
$queued = @($State.queue | Where-Object { $_.status -eq "queued" })
|
|
335
335
|
if ($queued.Count -eq 0) {
|
|
336
336
|
return ""
|
|
@@ -357,7 +357,7 @@ function Get-QueueNotice {
|
|
|
357
357
|
$parts += $preview
|
|
358
358
|
}
|
|
359
359
|
}
|
|
360
|
-
|
|
360
|
+
|
|
361
361
|
return ($parts -join " | ")
|
|
362
362
|
}
|
|
363
363
|
|
|
@@ -388,48 +388,48 @@ $lastNotice = ""
|
|
|
388
388
|
$lastUiKind = ""
|
|
389
389
|
$lastUiNotice = ""
|
|
390
390
|
Write-WatcherLog "START"
|
|
391
|
-
|
|
392
|
-
while ($true) {
|
|
393
|
-
if (-not (Test-PidAlive -ProcId $FrontendPid)) {
|
|
394
|
-
Write-WatcherLog "EXIT frontend_dead"
|
|
395
|
-
break
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
$runtime = Try-ReadJson -Path $RuntimeFile
|
|
399
|
-
if ($null -eq $runtime) {
|
|
400
|
-
Write-WatcherLog "WAIT runtime_missing"
|
|
401
|
-
Start-Sleep -Milliseconds 300
|
|
402
|
-
continue
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
$runtimeOwnerPid = 0
|
|
406
|
-
try { $runtimeOwnerPid = [int]$runtime.frontend_host_pid } catch { $runtimeOwnerPid = 0 }
|
|
407
|
-
if ($runtimeOwnerPid -ne $FrontendPid) {
|
|
408
|
-
Write-WatcherLog ("EXIT owner_changed owner=" + $runtimeOwnerPid)
|
|
409
|
-
break
|
|
410
|
-
}
|
|
411
|
-
|
|
391
|
+
|
|
392
|
+
while ($true) {
|
|
393
|
+
if (-not (Test-PidAlive -ProcId $FrontendPid)) {
|
|
394
|
+
Write-WatcherLog "EXIT frontend_dead"
|
|
395
|
+
break
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
$runtime = Try-ReadJson -Path $RuntimeFile
|
|
399
|
+
if ($null -eq $runtime) {
|
|
400
|
+
Write-WatcherLog "WAIT runtime_missing"
|
|
401
|
+
Start-Sleep -Milliseconds 300
|
|
402
|
+
continue
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
$runtimeOwnerPid = 0
|
|
406
|
+
try { $runtimeOwnerPid = [int]$runtime.frontend_host_pid } catch { $runtimeOwnerPid = 0 }
|
|
407
|
+
if ($runtimeOwnerPid -ne $FrontendPid) {
|
|
408
|
+
Write-WatcherLog ("EXIT owner_changed owner=" + $runtimeOwnerPid)
|
|
409
|
+
break
|
|
410
|
+
}
|
|
411
|
+
|
|
412
412
|
$state = Try-ReadJson -Path $StateFile
|
|
413
413
|
if ($null -eq $state) {
|
|
414
414
|
Write-WatcherLog "WAIT state_missing"
|
|
415
|
-
Start-Sleep -Milliseconds 700
|
|
416
|
-
continue
|
|
417
|
-
}
|
|
418
|
-
|
|
415
|
+
Start-Sleep -Milliseconds 700
|
|
416
|
+
continue
|
|
417
|
+
}
|
|
418
|
+
|
|
419
419
|
$title = Get-QueueTitle -State $state -FallbackTitle $BaseTitle -IdleCooldownMs $idleCooldownMs
|
|
420
420
|
$notice = Get-QueueNotice -State $state -IdleCooldownMs $idleCooldownMs
|
|
421
421
|
$ui = Get-UiNoticeSnapshot -State $state
|
|
422
422
|
if ($title -ne $lastTitle) {
|
|
423
423
|
$updated = Update-ConsoleTitle -Title $title
|
|
424
424
|
Write-WatcherLog ("TITLE updated=" + $updated + " text=" + $title)
|
|
425
|
-
$lastTitle = $title
|
|
426
|
-
}
|
|
427
|
-
if ($notice -ne $lastNotice) {
|
|
428
|
-
if ($notice) {
|
|
429
|
-
$noticeUpdated = Write-ConsoleNotice -Notice $notice
|
|
430
|
-
Write-WatcherLog ("NOTICE updated=" + $noticeUpdated + " text=" + $notice)
|
|
431
|
-
} else {
|
|
432
|
-
Write-WatcherLog "NOTICE clear"
|
|
425
|
+
$lastTitle = $title
|
|
426
|
+
}
|
|
427
|
+
if ($notice -ne $lastNotice) {
|
|
428
|
+
if ($notice) {
|
|
429
|
+
$noticeUpdated = Write-ConsoleNotice -Notice $notice
|
|
430
|
+
Write-WatcherLog ("NOTICE updated=" + $noticeUpdated + " text=" + $notice)
|
|
431
|
+
} else {
|
|
432
|
+
Write-WatcherLog "NOTICE clear"
|
|
433
433
|
}
|
|
434
434
|
$lastNotice = $notice
|
|
435
435
|
}
|