@integrity-labs/agt-cli 0.28.404 → 0.28.406
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/dist/bin/agt.js +4 -4
- package/dist/{chunk-V5CRVBVC.js → chunk-RD7MIR3G.js} +12 -1
- package/dist/{chunk-V5CRVBVC.js.map → chunk-RD7MIR3G.js.map} +1 -1
- package/dist/{chunk-SW3FOBHR.js → chunk-UTFTZ4WD.js} +30 -7
- package/dist/{chunk-SW3FOBHR.js.map → chunk-UTFTZ4WD.js.map} +1 -1
- package/dist/{claude-pair-runtime-HDSV7CKE.js → claude-pair-runtime-W5Z4K7XK.js} +2 -2
- package/dist/lib/manager-worker.js +146 -93
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +63 -3
- package/dist/mcp/origami.js +11 -0
- package/dist/mcp/slack-channel.js +70 -10
- package/dist/mcp/telegram-channel.js +68 -8
- package/dist/{persistent-session-GRCJPRH5.js → persistent-session-2AC3P5DJ.js} +2 -2
- package/dist/{responsiveness-probe-DNM5APN5.js → responsiveness-probe-LGJNUSPU.js} +2 -2
- package/package.json +1 -1
- /package/dist/{claude-pair-runtime-HDSV7CKE.js.map → claude-pair-runtime-W5Z4K7XK.js.map} +0 -0
- /package/dist/{persistent-session-GRCJPRH5.js.map → persistent-session-2AC3P5DJ.js.map} +0 -0
- /package/dist/{responsiveness-probe-DNM5APN5.js.map → responsiveness-probe-LGJNUSPU.js.map} +0 -0
|
@@ -30279,10 +30279,14 @@ import {
|
|
|
30279
30279
|
mkdirSync as mkdirSync4,
|
|
30280
30280
|
readFileSync as readFileSync7,
|
|
30281
30281
|
renameSync as renameSync4,
|
|
30282
|
+
statSync,
|
|
30282
30283
|
unlinkSync as unlinkSync2,
|
|
30284
|
+
utimesSync,
|
|
30283
30285
|
writeFileSync as writeFileSync5
|
|
30284
30286
|
} from "fs";
|
|
30285
30287
|
import { join as join7 } from "path";
|
|
30288
|
+
var STALE_LOCK_MS = 9e4;
|
|
30289
|
+
var HEARTBEAT_INTERVAL_MS = 3e4;
|
|
30286
30290
|
function defaultIsPidAlive(pid) {
|
|
30287
30291
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
30288
30292
|
try {
|
|
@@ -30300,6 +30304,9 @@ function acquireMcpSpawnLock(args) {
|
|
|
30300
30304
|
const isPidAlive = options.isPidAlive ?? defaultIsPidAlive;
|
|
30301
30305
|
const selfPid = options.selfPid ?? process.pid;
|
|
30302
30306
|
const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
30307
|
+
const nowMs = options.nowMs ?? (() => Date.now());
|
|
30308
|
+
const lockMtimeMs = options.lockMtimeMs ?? defaultLockMtimeMs;
|
|
30309
|
+
const staleMs = options.staleMs ?? STALE_LOCK_MS;
|
|
30303
30310
|
const path = join7(agentDir, basename);
|
|
30304
30311
|
const existing = readLockHolder(path);
|
|
30305
30312
|
if (existing) {
|
|
@@ -30307,7 +30314,11 @@ function acquireMcpSpawnLock(args) {
|
|
|
30307
30314
|
return { kind: "acquired", path };
|
|
30308
30315
|
}
|
|
30309
30316
|
if (isPidAlive(existing.pid)) {
|
|
30310
|
-
|
|
30317
|
+
const mtime = lockMtimeMs(path);
|
|
30318
|
+
const fresh = mtime !== null && nowMs() - mtime <= staleMs;
|
|
30319
|
+
if (fresh) {
|
|
30320
|
+
return { kind: "blocked", path, holder: existing };
|
|
30321
|
+
}
|
|
30311
30322
|
}
|
|
30312
30323
|
}
|
|
30313
30324
|
mkdirSync4(agentDir, { recursive: true, mode: 448 });
|
|
@@ -30328,6 +30339,38 @@ function releaseMcpSpawnLock(lockPath, opts = {}) {
|
|
|
30328
30339
|
} catch {
|
|
30329
30340
|
}
|
|
30330
30341
|
}
|
|
30342
|
+
function refreshMcpSpawnLock(lockPath, opts = {}) {
|
|
30343
|
+
if (!lockPath) return false;
|
|
30344
|
+
const selfPid = opts.selfPid ?? process.pid;
|
|
30345
|
+
const existing = readLockHolder(lockPath);
|
|
30346
|
+
if (!existing || existing.pid !== selfPid) return false;
|
|
30347
|
+
try {
|
|
30348
|
+
const t = (opts.nowMs ?? (() => Date.now()))() / 1e3;
|
|
30349
|
+
utimesSync(lockPath, t, t);
|
|
30350
|
+
return true;
|
|
30351
|
+
} catch {
|
|
30352
|
+
return false;
|
|
30353
|
+
}
|
|
30354
|
+
}
|
|
30355
|
+
function startMcpSpawnLockHeartbeat(lockPath, opts = {}) {
|
|
30356
|
+
if (!lockPath) return () => {
|
|
30357
|
+
};
|
|
30358
|
+
const intervalMs = opts.intervalMs ?? HEARTBEAT_INTERVAL_MS;
|
|
30359
|
+
const handle = setInterval(() => {
|
|
30360
|
+
if (!refreshMcpSpawnLock(lockPath, { selfPid: opts.selfPid })) {
|
|
30361
|
+
clearInterval(handle);
|
|
30362
|
+
}
|
|
30363
|
+
}, intervalMs);
|
|
30364
|
+
handle.unref?.();
|
|
30365
|
+
return () => clearInterval(handle);
|
|
30366
|
+
}
|
|
30367
|
+
function defaultLockMtimeMs(path) {
|
|
30368
|
+
try {
|
|
30369
|
+
return statSync(path).mtimeMs;
|
|
30370
|
+
} catch {
|
|
30371
|
+
return null;
|
|
30372
|
+
}
|
|
30373
|
+
}
|
|
30331
30374
|
function readLockHolder(path) {
|
|
30332
30375
|
if (!existsSync5(path)) return null;
|
|
30333
30376
|
try {
|
|
@@ -30355,7 +30398,7 @@ import {
|
|
|
30355
30398
|
existsSync as existsSync6,
|
|
30356
30399
|
renameSync as renameSync5,
|
|
30357
30400
|
unlinkSync as unlinkSync3,
|
|
30358
|
-
statSync,
|
|
30401
|
+
statSync as statSync2,
|
|
30359
30402
|
createWriteStream
|
|
30360
30403
|
} from "fs";
|
|
30361
30404
|
|
|
@@ -35186,6 +35229,17 @@ var FLAG_REGISTRY = [
|
|
|
35186
35229
|
// call the flag evaluator) can gate the kanban_move `waiting` option. Also the
|
|
35187
35230
|
// highest-precedence operator override, per ADR-0022.
|
|
35188
35231
|
envVar: "AGT_KANBAN_WAITING_ENABLED"
|
|
35232
|
+
},
|
|
35233
|
+
{
|
|
35234
|
+
key: "scheduled-task-nudge-durable",
|
|
35235
|
+
description: 'Deliver the scheduled-task "work this card" nudge over the durable direct-chat notice rail instead of unverified tmux send-keys (ENG-8068, re-landing ENG-7971). When ON, routeScheduledTaskViaKanban enqueues the nudge via POST /host/scheduled-task/notify (kind:notice, push-and-consumed by the in-session MCP with a per-card consume-time revalidation) and closes the card + run on an enqueue failure, retiring the ENG-6351 orphaned-card gap where an unsubmitted keystroke left a scheduled task silently unrun. When OFF (default) the manager keeps the current tmux send-keys delivery, byte-for-byte as today. This is the kill switch: ENG-7971 was reverted once because the durable rail 500d on a session_id bug (fixed in ENG-8061); flip OFF to fall back to send-keys instantly without a code rollback if the durable path misbehaves. Resolved host-side by the manager via hostFlagStore().getBoolean (the manager evaluates the decision itself, so no spawn-env materialization is needed). Ships dark.',
|
|
35236
|
+
flagType: "boolean",
|
|
35237
|
+
// Declared safe value is `false`: the current, reverted-to send-keys delivery. Turning
|
|
35238
|
+
// it ON activates the durable rail per org/host once operators are confident. `false`
|
|
35239
|
+
// is also the fail-safe direction - a flag-DB read error must never silently switch a
|
|
35240
|
+
// fleet onto the rail that broke prod twice. Net-new gate, so registry-only (ADR-0022);
|
|
35241
|
+
// consumed by the manager's own logic, not an in-container MCP, so no env materialization.
|
|
35242
|
+
defaultValue: false
|
|
35189
35243
|
}
|
|
35190
35244
|
];
|
|
35191
35245
|
var REGISTRY_BY_KEY = new Map(FLAG_REGISTRY.map((definition) => [definition.key, definition]));
|
|
@@ -35819,7 +35873,7 @@ function scheduleDirectChatBusyAck(sessionId, messageId, arrivedWhileBusy) {
|
|
|
35819
35873
|
let paneLogFreshAgeMs = null;
|
|
35820
35874
|
if (DIRECT_CHAT_CODE_NAME_AGENT_DIR) {
|
|
35821
35875
|
try {
|
|
35822
|
-
const paneMtimeMs =
|
|
35876
|
+
const paneMtimeMs = statSync2(join10(DIRECT_CHAT_CODE_NAME_AGENT_DIR, "pane.log")).mtimeMs;
|
|
35823
35877
|
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
35824
35878
|
} catch {
|
|
35825
35879
|
}
|
|
@@ -36045,6 +36099,7 @@ async function pollForMessages(sinceMs) {
|
|
|
36045
36099
|
}
|
|
36046
36100
|
}
|
|
36047
36101
|
var acquiredLockPath = null;
|
|
36102
|
+
var stopLockHeartbeat = null;
|
|
36048
36103
|
{
|
|
36049
36104
|
const lockResult = acquireMcpSpawnLock({
|
|
36050
36105
|
agentDir: DIRECT_CHAT_AGENT_DIR,
|
|
@@ -36058,6 +36113,7 @@ var acquiredLockPath = null;
|
|
|
36058
36113
|
process.exit(0);
|
|
36059
36114
|
} else if (lockResult.kind === "acquired") {
|
|
36060
36115
|
acquiredLockPath = lockResult.path;
|
|
36116
|
+
stopLockHeartbeat = startMcpSpawnLockHeartbeat(acquiredLockPath);
|
|
36061
36117
|
}
|
|
36062
36118
|
}
|
|
36063
36119
|
var DOORBELL_ENABLED = resolveHostBooleanFlag({
|
|
@@ -36277,6 +36333,10 @@ function shutdown(reason) {
|
|
|
36277
36333
|
}
|
|
36278
36334
|
if (safetyNetTimer) clearInterval(safetyNetTimer);
|
|
36279
36335
|
if (progressTickTimer) clearInterval(progressTickTimer);
|
|
36336
|
+
try {
|
|
36337
|
+
stopLockHeartbeat?.();
|
|
36338
|
+
} catch {
|
|
36339
|
+
}
|
|
36280
36340
|
try {
|
|
36281
36341
|
releaseMcpSpawnLock(acquiredLockPath);
|
|
36282
36342
|
} catch {
|
package/dist/mcp/origami.js
CHANGED
|
@@ -40845,6 +40845,17 @@ var FLAG_REGISTRY = [
|
|
|
40845
40845
|
// call the flag evaluator) can gate the kanban_move `waiting` option. Also the
|
|
40846
40846
|
// highest-precedence operator override, per ADR-0022.
|
|
40847
40847
|
envVar: "AGT_KANBAN_WAITING_ENABLED"
|
|
40848
|
+
},
|
|
40849
|
+
{
|
|
40850
|
+
key: "scheduled-task-nudge-durable",
|
|
40851
|
+
description: 'Deliver the scheduled-task "work this card" nudge over the durable direct-chat notice rail instead of unverified tmux send-keys (ENG-8068, re-landing ENG-7971). When ON, routeScheduledTaskViaKanban enqueues the nudge via POST /host/scheduled-task/notify (kind:notice, push-and-consumed by the in-session MCP with a per-card consume-time revalidation) and closes the card + run on an enqueue failure, retiring the ENG-6351 orphaned-card gap where an unsubmitted keystroke left a scheduled task silently unrun. When OFF (default) the manager keeps the current tmux send-keys delivery, byte-for-byte as today. This is the kill switch: ENG-7971 was reverted once because the durable rail 500d on a session_id bug (fixed in ENG-8061); flip OFF to fall back to send-keys instantly without a code rollback if the durable path misbehaves. Resolved host-side by the manager via hostFlagStore().getBoolean (the manager evaluates the decision itself, so no spawn-env materialization is needed). Ships dark.',
|
|
40852
|
+
flagType: "boolean",
|
|
40853
|
+
// Declared safe value is `false`: the current, reverted-to send-keys delivery. Turning
|
|
40854
|
+
// it ON activates the durable rail per org/host once operators are confident. `false`
|
|
40855
|
+
// is also the fail-safe direction - a flag-DB read error must never silently switch a
|
|
40856
|
+
// fleet onto the rail that broke prod twice. Net-new gate, so registry-only (ADR-0022);
|
|
40857
|
+
// consumed by the manager's own logic, not an in-container MCP, so no env materialization.
|
|
40858
|
+
defaultValue: false
|
|
40848
40859
|
}
|
|
40849
40860
|
];
|
|
40850
40861
|
var REGISTRY_BY_KEY = new Map(FLAG_REGISTRY.map((definition) => [definition.key, definition]));
|
|
@@ -34764,6 +34764,17 @@ var FLAG_REGISTRY = [
|
|
|
34764
34764
|
// call the flag evaluator) can gate the kanban_move `waiting` option. Also the
|
|
34765
34765
|
// highest-precedence operator override, per ADR-0022.
|
|
34766
34766
|
envVar: "AGT_KANBAN_WAITING_ENABLED"
|
|
34767
|
+
},
|
|
34768
|
+
{
|
|
34769
|
+
key: "scheduled-task-nudge-durable",
|
|
34770
|
+
description: 'Deliver the scheduled-task "work this card" nudge over the durable direct-chat notice rail instead of unverified tmux send-keys (ENG-8068, re-landing ENG-7971). When ON, routeScheduledTaskViaKanban enqueues the nudge via POST /host/scheduled-task/notify (kind:notice, push-and-consumed by the in-session MCP with a per-card consume-time revalidation) and closes the card + run on an enqueue failure, retiring the ENG-6351 orphaned-card gap where an unsubmitted keystroke left a scheduled task silently unrun. When OFF (default) the manager keeps the current tmux send-keys delivery, byte-for-byte as today. This is the kill switch: ENG-7971 was reverted once because the durable rail 500d on a session_id bug (fixed in ENG-8061); flip OFF to fall back to send-keys instantly without a code rollback if the durable path misbehaves. Resolved host-side by the manager via hostFlagStore().getBoolean (the manager evaluates the decision itself, so no spawn-env materialization is needed). Ships dark.',
|
|
34771
|
+
flagType: "boolean",
|
|
34772
|
+
// Declared safe value is `false`: the current, reverted-to send-keys delivery. Turning
|
|
34773
|
+
// it ON activates the durable rail per org/host once operators are confident. `false`
|
|
34774
|
+
// is also the fail-safe direction - a flag-DB read error must never silently switch a
|
|
34775
|
+
// fleet onto the rail that broke prod twice. Net-new gate, so registry-only (ADR-0022);
|
|
34776
|
+
// consumed by the manager's own logic, not an in-container MCP, so no env materialization.
|
|
34777
|
+
defaultValue: false
|
|
34767
34778
|
}
|
|
34768
34779
|
];
|
|
34769
34780
|
var REGISTRY_BY_KEY = new Map(FLAG_REGISTRY.map((definition) => [definition.key, definition]));
|
|
@@ -36683,7 +36694,7 @@ import {
|
|
|
36683
36694
|
readFileSync as readFileSync17,
|
|
36684
36695
|
readdirSync as readdirSync5,
|
|
36685
36696
|
renameSync as renameSync5,
|
|
36686
|
-
statSync as
|
|
36697
|
+
statSync as statSync3,
|
|
36687
36698
|
unlinkSync as unlinkSync7,
|
|
36688
36699
|
watch,
|
|
36689
36700
|
writeFileSync as writeFileSync13,
|
|
@@ -38494,10 +38505,14 @@ import {
|
|
|
38494
38505
|
mkdirSync as mkdirSync8,
|
|
38495
38506
|
readFileSync as readFileSync16,
|
|
38496
38507
|
renameSync as renameSync4,
|
|
38508
|
+
statSync as statSync2,
|
|
38497
38509
|
unlinkSync as unlinkSync6,
|
|
38510
|
+
utimesSync,
|
|
38498
38511
|
writeFileSync as writeFileSync12
|
|
38499
38512
|
} from "fs";
|
|
38500
38513
|
import { join as join16 } from "path";
|
|
38514
|
+
var STALE_LOCK_MS = 9e4;
|
|
38515
|
+
var HEARTBEAT_INTERVAL_MS = 3e4;
|
|
38501
38516
|
function defaultIsPidAlive(pid) {
|
|
38502
38517
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
38503
38518
|
try {
|
|
@@ -38515,6 +38530,9 @@ function acquireMcpSpawnLock(args) {
|
|
|
38515
38530
|
const isPidAlive = options.isPidAlive ?? defaultIsPidAlive;
|
|
38516
38531
|
const selfPid = options.selfPid ?? process.pid;
|
|
38517
38532
|
const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
38533
|
+
const nowMs = options.nowMs ?? (() => Date.now());
|
|
38534
|
+
const lockMtimeMs = options.lockMtimeMs ?? defaultLockMtimeMs;
|
|
38535
|
+
const staleMs = options.staleMs ?? STALE_LOCK_MS;
|
|
38518
38536
|
const path = join16(agentDir, basename2);
|
|
38519
38537
|
const existing = readLockHolder(path);
|
|
38520
38538
|
if (existing) {
|
|
@@ -38522,7 +38540,11 @@ function acquireMcpSpawnLock(args) {
|
|
|
38522
38540
|
return { kind: "acquired", path };
|
|
38523
38541
|
}
|
|
38524
38542
|
if (isPidAlive(existing.pid)) {
|
|
38525
|
-
|
|
38543
|
+
const mtime = lockMtimeMs(path);
|
|
38544
|
+
const fresh = mtime !== null && nowMs() - mtime <= staleMs;
|
|
38545
|
+
if (fresh) {
|
|
38546
|
+
return { kind: "blocked", path, holder: existing };
|
|
38547
|
+
}
|
|
38526
38548
|
}
|
|
38527
38549
|
}
|
|
38528
38550
|
mkdirSync8(agentDir, { recursive: true, mode: 448 });
|
|
@@ -38543,6 +38565,38 @@ function releaseMcpSpawnLock(lockPath, opts = {}) {
|
|
|
38543
38565
|
} catch {
|
|
38544
38566
|
}
|
|
38545
38567
|
}
|
|
38568
|
+
function refreshMcpSpawnLock(lockPath, opts = {}) {
|
|
38569
|
+
if (!lockPath) return false;
|
|
38570
|
+
const selfPid = opts.selfPid ?? process.pid;
|
|
38571
|
+
const existing = readLockHolder(lockPath);
|
|
38572
|
+
if (!existing || existing.pid !== selfPid) return false;
|
|
38573
|
+
try {
|
|
38574
|
+
const t = (opts.nowMs ?? (() => Date.now()))() / 1e3;
|
|
38575
|
+
utimesSync(lockPath, t, t);
|
|
38576
|
+
return true;
|
|
38577
|
+
} catch {
|
|
38578
|
+
return false;
|
|
38579
|
+
}
|
|
38580
|
+
}
|
|
38581
|
+
function startMcpSpawnLockHeartbeat(lockPath, opts = {}) {
|
|
38582
|
+
if (!lockPath) return () => {
|
|
38583
|
+
};
|
|
38584
|
+
const intervalMs = opts.intervalMs ?? HEARTBEAT_INTERVAL_MS;
|
|
38585
|
+
const handle = setInterval(() => {
|
|
38586
|
+
if (!refreshMcpSpawnLock(lockPath, { selfPid: opts.selfPid })) {
|
|
38587
|
+
clearInterval(handle);
|
|
38588
|
+
}
|
|
38589
|
+
}, intervalMs);
|
|
38590
|
+
handle.unref?.();
|
|
38591
|
+
return () => clearInterval(handle);
|
|
38592
|
+
}
|
|
38593
|
+
function defaultLockMtimeMs(path) {
|
|
38594
|
+
try {
|
|
38595
|
+
return statSync2(path).mtimeMs;
|
|
38596
|
+
} catch {
|
|
38597
|
+
return null;
|
|
38598
|
+
}
|
|
38599
|
+
}
|
|
38546
38600
|
function readLockHolder(path) {
|
|
38547
38601
|
if (!existsSync9(path)) return null;
|
|
38548
38602
|
try {
|
|
@@ -38858,7 +38912,7 @@ var liveAllowedUsersCache = null;
|
|
|
38858
38912
|
function readLiveAllowedUsers() {
|
|
38859
38913
|
if (!SLACK_MCP_CONFIG_PATH) return null;
|
|
38860
38914
|
try {
|
|
38861
|
-
const mtimeMs =
|
|
38915
|
+
const mtimeMs = statSync3(SLACK_MCP_CONFIG_PATH).mtimeMs;
|
|
38862
38916
|
if (liveAllowedUsersCache && liveAllowedUsersCache.mtimeMs === mtimeMs) {
|
|
38863
38917
|
return liveAllowedUsersCache.value;
|
|
38864
38918
|
}
|
|
@@ -38879,7 +38933,7 @@ var livePingAllowedUsersCache = null;
|
|
|
38879
38933
|
function readLivePingAllowedUsers() {
|
|
38880
38934
|
if (!SLACK_MCP_CONFIG_PATH) return null;
|
|
38881
38935
|
try {
|
|
38882
|
-
const mtimeMs =
|
|
38936
|
+
const mtimeMs = statSync3(SLACK_MCP_CONFIG_PATH).mtimeMs;
|
|
38883
38937
|
if (livePingAllowedUsersCache && livePingAllowedUsersCache.mtimeMs === mtimeMs) {
|
|
38884
38938
|
return livePingAllowedUsersCache.value;
|
|
38885
38939
|
}
|
|
@@ -39109,7 +39163,7 @@ function scheduleBusyAck(channel, threadTs, messageTs, isThreadReply, arrivedWhi
|
|
|
39109
39163
|
let paneLogFreshAgeMs = null;
|
|
39110
39164
|
if (SLACK_AGENT_DIR) {
|
|
39111
39165
|
try {
|
|
39112
|
-
const paneMtimeMs =
|
|
39166
|
+
const paneMtimeMs = statSync3(join17(SLACK_AGENT_DIR, "pane.log")).mtimeMs;
|
|
39113
39167
|
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
39114
39168
|
} catch {
|
|
39115
39169
|
}
|
|
@@ -39376,7 +39430,7 @@ function scanSlackRecoveryRetries() {
|
|
|
39376
39430
|
if (!f.includes(".retry-") || f.endsWith(".poison.json")) continue;
|
|
39377
39431
|
let mtimeMs;
|
|
39378
39432
|
try {
|
|
39379
|
-
mtimeMs =
|
|
39433
|
+
mtimeMs = statSync3(join17(SLACK_RECOVERY_OUTBOX_DIR, f)).mtimeMs;
|
|
39380
39434
|
} catch {
|
|
39381
39435
|
continue;
|
|
39382
39436
|
}
|
|
@@ -39433,7 +39487,7 @@ async function processSlackNoticeOutboxFile(filename) {
|
|
|
39433
39487
|
try {
|
|
39434
39488
|
let mtimeMs;
|
|
39435
39489
|
try {
|
|
39436
|
-
mtimeMs =
|
|
39490
|
+
mtimeMs = statSync3(fullPath).mtimeMs;
|
|
39437
39491
|
} catch {
|
|
39438
39492
|
return;
|
|
39439
39493
|
}
|
|
@@ -41882,7 +41936,7 @@ ${result.formatted}` : "No messages in range, or the bot is not a member of this
|
|
|
41882
41936
|
let bytes;
|
|
41883
41937
|
let size;
|
|
41884
41938
|
try {
|
|
41885
|
-
const stat2 =
|
|
41939
|
+
const stat2 = statSync3(resolvedPath);
|
|
41886
41940
|
if (!stat2.isFile()) {
|
|
41887
41941
|
return {
|
|
41888
41942
|
content: [{ type: "text", text: `Upload refused: ${resolvedPath} is not a regular file.` }],
|
|
@@ -42673,7 +42727,7 @@ async function replayPendingSlackMarkers() {
|
|
|
42673
42727
|
let paneFreshAgeMs = null;
|
|
42674
42728
|
if (SLACK_AGENT_DIR) {
|
|
42675
42729
|
try {
|
|
42676
|
-
paneFreshAgeMs = Math.max(0, now -
|
|
42730
|
+
paneFreshAgeMs = Math.max(0, now - statSync3(join17(SLACK_AGENT_DIR, "pane.log")).mtimeMs);
|
|
42677
42731
|
} catch {
|
|
42678
42732
|
}
|
|
42679
42733
|
}
|
|
@@ -42785,6 +42839,7 @@ async function resolveUserEmail(userId) {
|
|
|
42785
42839
|
var currentWs = null;
|
|
42786
42840
|
var isShuttingDown = false;
|
|
42787
42841
|
var acquiredLockPath = null;
|
|
42842
|
+
var stopLockHeartbeat = null;
|
|
42788
42843
|
async function seedMutedChannelsFromApi() {
|
|
42789
42844
|
try {
|
|
42790
42845
|
const cfg = statusRuntimeConfig();
|
|
@@ -43263,7 +43318,7 @@ async function connectSocketMode() {
|
|
|
43263
43318
|
let paneLogFreshAgeMs = null;
|
|
43264
43319
|
if (SLACK_AGENT_DIR) {
|
|
43265
43320
|
try {
|
|
43266
|
-
const paneMtimeMs =
|
|
43321
|
+
const paneMtimeMs = statSync3(join17(SLACK_AGENT_DIR, "pane.log")).mtimeMs;
|
|
43267
43322
|
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
43268
43323
|
} catch {
|
|
43269
43324
|
}
|
|
@@ -43498,6 +43553,10 @@ function shutdown(reason, exitCode = 0) {
|
|
|
43498
43553
|
currentWs?.close();
|
|
43499
43554
|
} catch {
|
|
43500
43555
|
}
|
|
43556
|
+
try {
|
|
43557
|
+
stopLockHeartbeat?.();
|
|
43558
|
+
} catch {
|
|
43559
|
+
}
|
|
43501
43560
|
try {
|
|
43502
43561
|
releaseMcpSpawnLock(acquiredLockPath);
|
|
43503
43562
|
} catch {
|
|
@@ -43527,6 +43586,7 @@ process.on("unhandledRejection", (reason) => {
|
|
|
43527
43586
|
process.exit(0);
|
|
43528
43587
|
} else if (lockResult.kind === "acquired") {
|
|
43529
43588
|
acquiredLockPath = lockResult.path;
|
|
43589
|
+
stopLockHeartbeat = startMcpSpawnLockHeartbeat(acquiredLockPath);
|
|
43530
43590
|
}
|
|
43531
43591
|
}
|
|
43532
43592
|
if (THREAD_STORE_PATH) {
|
|
@@ -30097,7 +30097,7 @@ import {
|
|
|
30097
30097
|
readdirSync as readdirSync4,
|
|
30098
30098
|
realpathSync,
|
|
30099
30099
|
renameSync as renameSync7,
|
|
30100
|
-
statSync as
|
|
30100
|
+
statSync as statSync3,
|
|
30101
30101
|
unlinkSync as unlinkSync7,
|
|
30102
30102
|
watch,
|
|
30103
30103
|
writeFileSync as writeFileSync11,
|
|
@@ -35114,6 +35114,17 @@ var FLAG_REGISTRY = [
|
|
|
35114
35114
|
// call the flag evaluator) can gate the kanban_move `waiting` option. Also the
|
|
35115
35115
|
// highest-precedence operator override, per ADR-0022.
|
|
35116
35116
|
envVar: "AGT_KANBAN_WAITING_ENABLED"
|
|
35117
|
+
},
|
|
35118
|
+
{
|
|
35119
|
+
key: "scheduled-task-nudge-durable",
|
|
35120
|
+
description: 'Deliver the scheduled-task "work this card" nudge over the durable direct-chat notice rail instead of unverified tmux send-keys (ENG-8068, re-landing ENG-7971). When ON, routeScheduledTaskViaKanban enqueues the nudge via POST /host/scheduled-task/notify (kind:notice, push-and-consumed by the in-session MCP with a per-card consume-time revalidation) and closes the card + run on an enqueue failure, retiring the ENG-6351 orphaned-card gap where an unsubmitted keystroke left a scheduled task silently unrun. When OFF (default) the manager keeps the current tmux send-keys delivery, byte-for-byte as today. This is the kill switch: ENG-7971 was reverted once because the durable rail 500d on a session_id bug (fixed in ENG-8061); flip OFF to fall back to send-keys instantly without a code rollback if the durable path misbehaves. Resolved host-side by the manager via hostFlagStore().getBoolean (the manager evaluates the decision itself, so no spawn-env materialization is needed). Ships dark.',
|
|
35121
|
+
flagType: "boolean",
|
|
35122
|
+
// Declared safe value is `false`: the current, reverted-to send-keys delivery. Turning
|
|
35123
|
+
// it ON activates the durable rail per org/host once operators are confident. `false`
|
|
35124
|
+
// is also the fail-safe direction - a flag-DB read error must never silently switch a
|
|
35125
|
+
// fleet onto the rail that broke prod twice. Net-new gate, so registry-only (ADR-0022);
|
|
35126
|
+
// consumed by the manager's own logic, not an in-container MCP, so no env materialization.
|
|
35127
|
+
defaultValue: false
|
|
35117
35128
|
}
|
|
35118
35129
|
];
|
|
35119
35130
|
var REGISTRY_BY_KEY = new Map(FLAG_REGISTRY.map((definition) => [definition.key, definition]));
|
|
@@ -37295,10 +37306,14 @@ import {
|
|
|
37295
37306
|
mkdirSync as mkdirSync8,
|
|
37296
37307
|
readFileSync as readFileSync11,
|
|
37297
37308
|
renameSync as renameSync6,
|
|
37309
|
+
statSync as statSync2,
|
|
37298
37310
|
unlinkSync as unlinkSync6,
|
|
37311
|
+
utimesSync,
|
|
37299
37312
|
writeFileSync as writeFileSync9
|
|
37300
37313
|
} from "fs";
|
|
37301
37314
|
import { join as join11 } from "path";
|
|
37315
|
+
var STALE_LOCK_MS = 9e4;
|
|
37316
|
+
var HEARTBEAT_INTERVAL_MS = 3e4;
|
|
37302
37317
|
function defaultIsPidAlive(pid) {
|
|
37303
37318
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
37304
37319
|
try {
|
|
@@ -37316,6 +37331,9 @@ function acquireMcpSpawnLock(args) {
|
|
|
37316
37331
|
const isPidAlive = options.isPidAlive ?? defaultIsPidAlive;
|
|
37317
37332
|
const selfPid = options.selfPid ?? process.pid;
|
|
37318
37333
|
const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
37334
|
+
const nowMs = options.nowMs ?? (() => Date.now());
|
|
37335
|
+
const lockMtimeMs = options.lockMtimeMs ?? defaultLockMtimeMs;
|
|
37336
|
+
const staleMs = options.staleMs ?? STALE_LOCK_MS;
|
|
37319
37337
|
const path = join11(agentDir, basename2);
|
|
37320
37338
|
const existing = readLockHolder(path);
|
|
37321
37339
|
if (existing) {
|
|
@@ -37323,7 +37341,11 @@ function acquireMcpSpawnLock(args) {
|
|
|
37323
37341
|
return { kind: "acquired", path };
|
|
37324
37342
|
}
|
|
37325
37343
|
if (isPidAlive(existing.pid)) {
|
|
37326
|
-
|
|
37344
|
+
const mtime = lockMtimeMs(path);
|
|
37345
|
+
const fresh = mtime !== null && nowMs() - mtime <= staleMs;
|
|
37346
|
+
if (fresh) {
|
|
37347
|
+
return { kind: "blocked", path, holder: existing };
|
|
37348
|
+
}
|
|
37327
37349
|
}
|
|
37328
37350
|
}
|
|
37329
37351
|
mkdirSync8(agentDir, { recursive: true, mode: 448 });
|
|
@@ -37344,6 +37366,38 @@ function releaseMcpSpawnLock(lockPath, opts = {}) {
|
|
|
37344
37366
|
} catch {
|
|
37345
37367
|
}
|
|
37346
37368
|
}
|
|
37369
|
+
function refreshMcpSpawnLock(lockPath, opts = {}) {
|
|
37370
|
+
if (!lockPath) return false;
|
|
37371
|
+
const selfPid = opts.selfPid ?? process.pid;
|
|
37372
|
+
const existing = readLockHolder(lockPath);
|
|
37373
|
+
if (!existing || existing.pid !== selfPid) return false;
|
|
37374
|
+
try {
|
|
37375
|
+
const t = (opts.nowMs ?? (() => Date.now()))() / 1e3;
|
|
37376
|
+
utimesSync(lockPath, t, t);
|
|
37377
|
+
return true;
|
|
37378
|
+
} catch {
|
|
37379
|
+
return false;
|
|
37380
|
+
}
|
|
37381
|
+
}
|
|
37382
|
+
function startMcpSpawnLockHeartbeat(lockPath, opts = {}) {
|
|
37383
|
+
if (!lockPath) return () => {
|
|
37384
|
+
};
|
|
37385
|
+
const intervalMs = opts.intervalMs ?? HEARTBEAT_INTERVAL_MS;
|
|
37386
|
+
const handle = setInterval(() => {
|
|
37387
|
+
if (!refreshMcpSpawnLock(lockPath, { selfPid: opts.selfPid })) {
|
|
37388
|
+
clearInterval(handle);
|
|
37389
|
+
}
|
|
37390
|
+
}, intervalMs);
|
|
37391
|
+
handle.unref?.();
|
|
37392
|
+
return () => clearInterval(handle);
|
|
37393
|
+
}
|
|
37394
|
+
function defaultLockMtimeMs(path) {
|
|
37395
|
+
try {
|
|
37396
|
+
return statSync2(path).mtimeMs;
|
|
37397
|
+
} catch {
|
|
37398
|
+
return null;
|
|
37399
|
+
}
|
|
37400
|
+
}
|
|
37347
37401
|
function readLockHolder(path) {
|
|
37348
37402
|
if (!existsSync8(path)) return null;
|
|
37349
37403
|
try {
|
|
@@ -38057,7 +38111,7 @@ function scheduleBusyAck(chatId, messageId, arrivedWhileBusy) {
|
|
|
38057
38111
|
let paneLogFreshAgeMs = null;
|
|
38058
38112
|
if (AGENT_DIR) {
|
|
38059
38113
|
try {
|
|
38060
|
-
const paneMtimeMs =
|
|
38114
|
+
const paneMtimeMs = statSync3(join13(AGENT_DIR, "pane.log")).mtimeMs;
|
|
38061
38115
|
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
38062
38116
|
} catch {
|
|
38063
38117
|
}
|
|
@@ -39193,7 +39247,7 @@ function scanRecoveryRetries() {
|
|
|
39193
39247
|
if (!f.includes(".retry-") || f.endsWith(".poison.json")) continue;
|
|
39194
39248
|
let mtimeMs;
|
|
39195
39249
|
try {
|
|
39196
|
-
mtimeMs =
|
|
39250
|
+
mtimeMs = statSync3(join13(RECOVERY_OUTBOX_DIR, f)).mtimeMs;
|
|
39197
39251
|
} catch {
|
|
39198
39252
|
continue;
|
|
39199
39253
|
}
|
|
@@ -39250,7 +39304,7 @@ async function processNoticeOutboxFile(filename) {
|
|
|
39250
39304
|
try {
|
|
39251
39305
|
let mtimeMs;
|
|
39252
39306
|
try {
|
|
39253
|
-
mtimeMs =
|
|
39307
|
+
mtimeMs = statSync3(fullPath).mtimeMs;
|
|
39254
39308
|
} catch {
|
|
39255
39309
|
return;
|
|
39256
39310
|
}
|
|
@@ -39970,7 +40024,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
39970
40024
|
let bytes;
|
|
39971
40025
|
let size;
|
|
39972
40026
|
try {
|
|
39973
|
-
const st =
|
|
40027
|
+
const st = statSync3(realPath);
|
|
39974
40028
|
if (!st.isFile()) {
|
|
39975
40029
|
return { content: [{ type: "text", text: `Upload refused: ${resolvedPath} is not a regular file.` }], isError: true };
|
|
39976
40030
|
}
|
|
@@ -40545,7 +40599,7 @@ async function replayPendingTelegramMarkers() {
|
|
|
40545
40599
|
let paneFreshAgeMs = null;
|
|
40546
40600
|
if (AGENT_DIR) {
|
|
40547
40601
|
try {
|
|
40548
|
-
paneFreshAgeMs = Math.max(0, now -
|
|
40602
|
+
paneFreshAgeMs = Math.max(0, now - statSync3(join13(AGENT_DIR, "pane.log")).mtimeMs);
|
|
40549
40603
|
} catch {
|
|
40550
40604
|
}
|
|
40551
40605
|
}
|
|
@@ -40698,6 +40752,7 @@ var telegramHttp = {
|
|
|
40698
40752
|
var nextOffset = loadPersistedOffset(TELEGRAM_OFFSET_FILE);
|
|
40699
40753
|
var isShuttingDown = false;
|
|
40700
40754
|
var acquiredLockPath = null;
|
|
40755
|
+
var stopLockHeartbeat = null;
|
|
40701
40756
|
async function pollLoop() {
|
|
40702
40757
|
while (!isShuttingDown) {
|
|
40703
40758
|
try {
|
|
@@ -41090,7 +41145,7 @@ async function pollLoop() {
|
|
|
41090
41145
|
let paneLogFreshAgeMs = null;
|
|
41091
41146
|
if (AGENT_DIR) {
|
|
41092
41147
|
try {
|
|
41093
|
-
const paneMtimeMs =
|
|
41148
|
+
const paneMtimeMs = statSync3(join13(AGENT_DIR, "pane.log")).mtimeMs;
|
|
41094
41149
|
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
41095
41150
|
} catch {
|
|
41096
41151
|
}
|
|
@@ -41257,6 +41312,10 @@ function shutdown(reason) {
|
|
|
41257
41312
|
recentDmPersister?.dispose();
|
|
41258
41313
|
} catch {
|
|
41259
41314
|
}
|
|
41315
|
+
try {
|
|
41316
|
+
stopLockHeartbeat?.();
|
|
41317
|
+
} catch {
|
|
41318
|
+
}
|
|
41260
41319
|
try {
|
|
41261
41320
|
releaseMcpSpawnLock(acquiredLockPath);
|
|
41262
41321
|
} catch {
|
|
@@ -41281,6 +41340,7 @@ process.on("SIGHUP", () => shutdown("SIGHUP"));
|
|
|
41281
41340
|
process.exit(0);
|
|
41282
41341
|
} else if (lockResult.kind === "acquired") {
|
|
41283
41342
|
acquiredLockPath = lockResult.path;
|
|
41343
|
+
stopLockHeartbeat = startMcpSpawnLockHeartbeat(acquiredLockPath);
|
|
41284
41344
|
}
|
|
41285
41345
|
}
|
|
41286
41346
|
process.stderr.write(
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
writeDirectChatSessionState,
|
|
37
37
|
writeEgressAllowlist,
|
|
38
38
|
writePersistentClaudeWrapper
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-RD7MIR3G.js";
|
|
40
40
|
import "./chunk-XWVM4KPK.js";
|
|
41
41
|
export {
|
|
42
42
|
EGRESS_BASELINE_DOMAINS,
|
|
@@ -77,4 +77,4 @@ export {
|
|
|
77
77
|
writeEgressAllowlist,
|
|
78
78
|
writePersistentClaudeWrapper
|
|
79
79
|
};
|
|
80
|
-
//# sourceMappingURL=persistent-session-
|
|
80
|
+
//# sourceMappingURL=persistent-session-2AC3P5DJ.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
paneLogPath
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RD7MIR3G.js";
|
|
4
4
|
import "./chunk-XWVM4KPK.js";
|
|
5
5
|
|
|
6
6
|
// src/lib/responsiveness-probe.ts
|
|
@@ -437,4 +437,4 @@ export {
|
|
|
437
437
|
readAndResetSlackReplyBindingClassifications,
|
|
438
438
|
readAndResetSlackReplyTargetClassifications
|
|
439
439
|
};
|
|
440
|
-
//# sourceMappingURL=responsiveness-probe-
|
|
440
|
+
//# sourceMappingURL=responsiveness-probe-LGJNUSPU.js.map
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|