@blunking/codexlink 0.1.9 → 0.1.12
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 +253 -251
- 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/dispatcher.js +1 -1
- package/telegram-plugin/lib/bridge.js +49 -19
- package/telegram-plugin/lib/storage.js +25 -25
- package/telegram-plugin/lib/telegram.js +2 -1
- package/telegram-plugin/poller.js +1 -1
- package/telegram-setup.ps1 +318 -168
- package/telegram-status.ps1 +256 -256
- package/telegram-title-embed.ps1 +105 -105
- package/telegram-title-watcher.ps1 +103 -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
|
|
@@ -154,13 +154,13 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
154
154
|
{
|
|
155
155
|
return;
|
|
156
156
|
}
|
|
157
|
-
|
|
158
|
-
var raw = File.ReadAllText(_stateFile);
|
|
159
|
-
if (string.IsNullOrWhiteSpace(raw))
|
|
160
|
-
{
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
|
|
157
|
+
|
|
158
|
+
var raw = File.ReadAllText(_stateFile);
|
|
159
|
+
if (string.IsNullOrWhiteSpace(raw))
|
|
160
|
+
{
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
164
|
var serializer = new JavaScriptSerializer();
|
|
165
165
|
var root = serializer.DeserializeObject(raw) as Dictionary<string, object>;
|
|
166
166
|
if (root == null || !root.ContainsKey("queue"))
|
|
@@ -210,20 +210,20 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
210
210
|
var entry = item as Dictionary<string, object>;
|
|
211
211
|
if (entry == null)
|
|
212
212
|
{
|
|
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
|
-
}
|
|
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
|
+
}
|
|
227
227
|
|
|
228
228
|
total += 1;
|
|
229
229
|
CountRelevance(entry, ref direct, ref ambient, ref escalation);
|
|
@@ -236,8 +236,8 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
236
236
|
|
|
237
237
|
if (total == 0)
|
|
238
238
|
{
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
241
|
|
|
242
242
|
var parts = new List<string> { "Q:" + total.ToString() };
|
|
243
243
|
if (pending > 0) parts.Add("P:" + pending.ToString());
|
|
@@ -252,15 +252,15 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
252
252
|
if (direct > 0) noticeParts.Add("direct " + direct.ToString());
|
|
253
253
|
if (ambient > 0) noticeParts.Add("group " + ambient.ToString());
|
|
254
254
|
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
|
-
|
|
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
|
+
|
|
264
264
|
private static object[] AsObjects(object value)
|
|
265
265
|
{
|
|
266
266
|
var arr = value as object[];
|
|
@@ -273,16 +273,16 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
273
273
|
{
|
|
274
274
|
return list.ToArray();
|
|
275
275
|
}
|
|
276
|
-
return new object[0];
|
|
277
|
-
}
|
|
278
|
-
|
|
276
|
+
return new object[0];
|
|
277
|
+
}
|
|
278
|
+
|
|
279
279
|
private static string GetString(Dictionary<string, object> entry, string key)
|
|
280
280
|
{
|
|
281
|
-
if (!entry.ContainsKey(key) || entry[key] == null)
|
|
282
|
-
{
|
|
283
|
-
return "";
|
|
284
|
-
}
|
|
285
|
-
return Convert.ToString(entry[key]) ?? "";
|
|
281
|
+
if (!entry.ContainsKey(key) || entry[key] == null)
|
|
282
|
+
{
|
|
283
|
+
return "";
|
|
284
|
+
}
|
|
285
|
+
return Convert.ToString(entry[key]) ?? "";
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
private static void CountRelevance(Dictionary<string, object> entry, ref int direct, ref int ambient, ref int escalation)
|
|
@@ -337,7 +337,7 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
337
337
|
}
|
|
338
338
|
return state + text;
|
|
339
339
|
}
|
|
340
|
-
|
|
340
|
+
|
|
341
341
|
private static string Normalize(string value, int maxLength)
|
|
342
342
|
{
|
|
343
343
|
if (string.IsNullOrWhiteSpace(value))
|
|
@@ -350,11 +350,11 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
350
350
|
{
|
|
351
351
|
compact = compact.Replace(" ", " ");
|
|
352
352
|
}
|
|
353
|
-
|
|
354
|
-
if (compact.Length <= maxLength)
|
|
355
|
-
{
|
|
356
|
-
return compact;
|
|
357
|
-
}
|
|
353
|
+
|
|
354
|
+
if (compact.Length <= maxLength)
|
|
355
|
+
{
|
|
356
|
+
return compact;
|
|
357
|
+
}
|
|
358
358
|
|
|
359
359
|
return compact.Substring(0, Math.Max(0, maxLength - 3)).TrimEnd() + "...";
|
|
360
360
|
}
|
|
@@ -384,21 +384,21 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
384
384
|
.Replace("ü", "ü")
|
|
385
385
|
.Replace("ß", "ß");
|
|
386
386
|
}
|
|
387
|
-
|
|
387
|
+
|
|
388
388
|
private static bool IsOlderThan(Dictionary<string, object> entry, long ttlMs)
|
|
389
389
|
{
|
|
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;
|
|
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;
|
|
402
402
|
}
|
|
403
403
|
}
|
|
404
404
|
|
|
@@ -419,24 +419,24 @@ public static class BlunEmbeddedQueueTitleWatcher
|
|
|
419
419
|
}
|
|
420
420
|
"@
|
|
421
421
|
}
|
|
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
|
-
|
|
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
|
+
|
|
442
442
|
[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
|
|
@@ -318,17 +318,17 @@ function Get-UiNoticeSnapshot {
|
|
|
318
318
|
text = $text
|
|
319
319
|
}
|
|
320
320
|
}
|
|
321
|
-
|
|
321
|
+
|
|
322
322
|
function Get-QueueNotice {
|
|
323
323
|
param(
|
|
324
324
|
[object]$State,
|
|
325
325
|
[int]$IdleCooldownMs = 15000
|
|
326
326
|
)
|
|
327
|
-
|
|
328
|
-
if ($null -eq $State -or $null -eq $State.queue) {
|
|
329
|
-
return ""
|
|
330
|
-
}
|
|
331
|
-
|
|
327
|
+
|
|
328
|
+
if ($null -eq $State -or $null -eq $State.queue) {
|
|
329
|
+
return ""
|
|
330
|
+
}
|
|
331
|
+
|
|
332
332
|
$queued = @($State.queue | Where-Object { $_.status -eq "queued" })
|
|
333
333
|
$pendingReplies = @(Get-OpenPendingReplies -State $State)
|
|
334
334
|
$totalWaiting = $queued.Count + $pendingReplies.Count
|
|
@@ -365,7 +365,7 @@ function Get-QueueNotice {
|
|
|
365
365
|
$parts += $preview
|
|
366
366
|
}
|
|
367
367
|
}
|
|
368
|
-
|
|
368
|
+
|
|
369
369
|
return ($parts -join " | ")
|
|
370
370
|
}
|
|
371
371
|
|
|
@@ -396,48 +396,48 @@ $lastNotice = ""
|
|
|
396
396
|
$lastUiKind = ""
|
|
397
397
|
$lastUiNotice = ""
|
|
398
398
|
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
|
-
|
|
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
|
+
|
|
420
420
|
$state = Try-ReadJson -Path $StateFile
|
|
421
421
|
if ($null -eq $state) {
|
|
422
422
|
Write-WatcherLog "WAIT state_missing"
|
|
423
|
-
Start-Sleep -Milliseconds 700
|
|
424
|
-
continue
|
|
425
|
-
}
|
|
426
|
-
|
|
423
|
+
Start-Sleep -Milliseconds 700
|
|
424
|
+
continue
|
|
425
|
+
}
|
|
426
|
+
|
|
427
427
|
$title = Get-QueueTitle -State $state -FallbackTitle $BaseTitle -IdleCooldownMs $idleCooldownMs
|
|
428
428
|
$notice = Get-QueueNotice -State $state -IdleCooldownMs $idleCooldownMs
|
|
429
429
|
$ui = Get-UiNoticeSnapshot -State $state
|
|
430
430
|
if ($title -ne $lastTitle) {
|
|
431
431
|
$updated = Update-ConsoleTitle -Title $title
|
|
432
432
|
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"
|
|
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"
|
|
441
441
|
}
|
|
442
442
|
$lastNotice = $notice
|
|
443
443
|
}
|