@integrity-labs/agt-cli 0.27.74 → 0.27.76

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.
@@ -16,7 +16,7 @@ import {
16
16
  provisionStopHook,
17
17
  requireHost,
18
18
  safeWriteJsonAtomic
19
- } from "../chunk-CADO5HXF.js";
19
+ } from "../chunk-NANSSDFG.js";
20
20
  import {
21
21
  getProjectDir as getProjectDir2,
22
22
  getReadyTasks,
@@ -26,6 +26,7 @@ import {
26
26
  } from "../chunk-HR5T2RQF.js";
27
27
  import {
28
28
  buildAllowedTools,
29
+ checkChannelInputs,
29
30
  formatMissingVar,
30
31
  getLastFailureContext,
31
32
  getProjectDir,
@@ -50,8 +51,9 @@ import {
50
51
  startPersistentSession,
51
52
  stopAllSessionsAndWait,
52
53
  stopPersistentSession,
54
+ takeWatchdogGiveUpCount,
53
55
  takeZombieDetection
54
- } from "../chunk-7YM2F3DG.js";
56
+ } from "../chunk-FAR2FJBQ.js";
55
57
  import {
56
58
  KANBAN_CHECK_COMMAND,
57
59
  appendDmFooter,
@@ -2510,108 +2512,6 @@ function killAgentChannelProcesses(codeName, opts) {
2510
2512
  return pids;
2511
2513
  }
2512
2514
 
2513
- // src/lib/channel-input-watchdog.ts
2514
- var STUCK_THRESHOLD_MS = 5e3;
2515
- var ATTACHED_STUCK_THRESHOLD_MS = 15e3;
2516
- var INPUT_BOX_DIVIDER = /^[─━]{10,}/;
2517
- var PROMPT_PREFIX = "\u276F ";
2518
- function decide(pane, prev, now, config2 = {}) {
2519
- const threshold = config2.stuckThresholdMs ?? STUCK_THRESHOLD_MS;
2520
- const inputText = extractInputBoxText(pane);
2521
- if (!inputText) {
2522
- return { fire: false, next: void 0 };
2523
- }
2524
- if (isActivelyProcessing(pane)) {
2525
- return { fire: false, next: prev };
2526
- }
2527
- const hash = simpleHash(inputText);
2528
- if (!prev || prev.lastInputHash !== hash) {
2529
- return {
2530
- fire: false,
2531
- next: { lastInputHash: hash, firstSeenAt: now, resolved: false }
2532
- };
2533
- }
2534
- if (prev.resolved) return { fire: false, next: prev };
2535
- if (now - prev.firstSeenAt < threshold) return { fire: false, next: prev };
2536
- return {
2537
- fire: true,
2538
- next: { ...prev, resolved: true }
2539
- };
2540
- }
2541
- function extractInputBoxText(pane) {
2542
- const lines = pane.split("\n");
2543
- for (let i = 1; i < lines.length; i++) {
2544
- const line = lines[i] ?? "";
2545
- if (!line.startsWith(PROMPT_PREFIX)) continue;
2546
- let j = i - 1;
2547
- while (j >= 0 && (lines[j] ?? "").trim() === "") j--;
2548
- if (j < 0) continue;
2549
- if (!INPUT_BOX_DIVIDER.test((lines[j] ?? "").trim())) continue;
2550
- const text = line.slice(PROMPT_PREFIX.length).trim();
2551
- return text.length > 0 ? text : null;
2552
- }
2553
- return null;
2554
- }
2555
- function isActivelyProcessing(pane) {
2556
- const lines = pane.split("\n");
2557
- for (let i = lines.length - 1; i >= 0; i--) {
2558
- const line = (lines[i] ?? "").trim();
2559
- if (!line.startsWith("\u273B")) continue;
2560
- if (/\bfor\s+\d+s\s*$/.test(line)) return false;
2561
- if (/\b\w+ing[…\.]{0,3}\s*$/i.test(line)) return true;
2562
- return false;
2563
- }
2564
- return false;
2565
- }
2566
- function simpleHash(s) {
2567
- let h = 0;
2568
- for (let i = 0; i < s.length; i++) {
2569
- h = (h << 5) - h + s.charCodeAt(i) | 0;
2570
- }
2571
- return h.toString(16);
2572
- }
2573
- function checkChannelInputs(codeNames, io, config2 = {}, states = sharedStates) {
2574
- const live = new Set(codeNames);
2575
- for (const codeName of codeNames) {
2576
- try {
2577
- checkOne(codeName, io, config2, states);
2578
- } catch (err) {
2579
- io.log(`[channel-input-watchdog] '${codeName}': ${err.message}`);
2580
- }
2581
- }
2582
- for (const key of [...states.keys()]) {
2583
- if (!live.has(key)) states.delete(key);
2584
- }
2585
- }
2586
- function checkOne(codeName, io, config2, states) {
2587
- const pane = io.capturePane(codeName);
2588
- if (!pane) {
2589
- states.delete(codeName);
2590
- return;
2591
- }
2592
- const attached = io.isClientAttached(codeName);
2593
- const effectiveConfig = attached ? {
2594
- ...config2,
2595
- stuckThresholdMs: config2.attachedStuckThresholdMs ?? ATTACHED_STUCK_THRESHOLD_MS
2596
- } : config2;
2597
- const prev = states.get(codeName);
2598
- const { fire, next } = decide(pane, prev, io.now(), effectiveConfig);
2599
- if (next === void 0) {
2600
- states.delete(codeName);
2601
- } else {
2602
- states.set(codeName, next);
2603
- }
2604
- if (fire) {
2605
- const text = extractInputBoxText(pane) ?? "";
2606
- const hash = next?.lastInputHash ?? simpleHash(text);
2607
- io.log(
2608
- `[channel-input-watchdog] '${codeName}': stuck channel input \u2014 firing Enter (input_hash=${hash}, len=${text.length})`
2609
- );
2610
- io.sendEnter(codeName);
2611
- }
2612
- }
2613
- var sharedStates = /* @__PURE__ */ new Map();
2614
-
2615
2515
  // src/lib/delivery-hint.ts
2616
2516
  var DEFAULT_PROBABILITY = 0.1;
2617
2517
  function envSuffixFor(codeName) {
@@ -3748,7 +3648,7 @@ var cachedMaintenanceWindow = null;
3748
3648
  var lastVersionCheckAt = 0;
3749
3649
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
3750
3650
  var lastResponsivenessProbeAt = 0;
3751
- var agtCliVersion = true ? "0.27.74" : "dev";
3651
+ var agtCliVersion = true ? "0.27.76" : "dev";
3752
3652
  function resolveBrewPath(execFileSync4) {
3753
3653
  try {
3754
3654
  const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -4862,7 +4762,7 @@ async function pollCycle() {
4862
4762
  }
4863
4763
  try {
4864
4764
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
4865
- const { collectDiagnostics } = await import("../persistent-session-S7OJTKKE.js");
4765
+ const { collectDiagnostics } = await import("../persistent-session-4HYXVGKO.js");
4866
4766
  const diagCodeNames = [...agentState.persistentSessionAgents];
4867
4767
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
4868
4768
  let tailscaleHostname;
@@ -4935,12 +4835,15 @@ async function pollCycle() {
4935
4835
  const {
4936
4836
  collectResponsivenessProbes,
4937
4837
  getResponsivenessIntervalMs
4938
- } = await import("../responsiveness-probe-LGNXOX43.js");
4838
+ } = await import("../responsiveness-probe-NUGYDDMS.js");
4939
4839
  const probeIntervalMs = getResponsivenessIntervalMs();
4940
4840
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
4941
4841
  const probeCodeNames = [...agentState.persistentSessionAgents];
4942
4842
  if (probeCodeNames.length > 0) {
4943
- const probes = collectResponsivenessProbes(probeCodeNames);
4843
+ const probes = collectResponsivenessProbes(probeCodeNames).map((p) => ({
4844
+ ...p,
4845
+ input_stuck_give_ups: takeWatchdogGiveUpCount(p.code_name)
4846
+ }));
4944
4847
  if (probes.length > 0) {
4945
4848
  void api.post("/host/responsiveness-probe", { host_id: hostId, probes }).catch((err) => {
4946
4849
  log(`[responsiveness-probe] post failed: ${err.message}`);
@@ -5138,6 +5041,26 @@ async function pollCycle() {
5138
5041
  } catch {
5139
5042
  }
5140
5043
  },
5044
+ // ENG-6017: dialog-dismissal keys — one send-keys call per key so a
5045
+ // multi-key sequence can't be wrapped into a single bracketed paste
5046
+ // (see defaultArmSender in persistent-session.ts). The inter-key
5047
+ // delay is a blocking sleep; dialog sequences are at most two keys
5048
+ // with a 300ms gap, well within poll-cycle tolerances.
5049
+ sendKeys: (codeName, keys, interKeyDelayMs) => {
5050
+ try {
5051
+ for (let i = 0; i < keys.length; i++) {
5052
+ if (i > 0 && interKeyDelayMs > 0) {
5053
+ const view = new Int32Array(new SharedArrayBuffer(4));
5054
+ Atomics.wait(view, 0, 0, interKeyDelayMs);
5055
+ }
5056
+ syncExecFile("tmux", ["send-keys", "-t", `agt-${codeName}`, keys[i]], {
5057
+ stdio: "ignore",
5058
+ timeout: 2e3
5059
+ });
5060
+ }
5061
+ } catch {
5062
+ }
5063
+ },
5141
5064
  log,
5142
5065
  now: () => Date.now()
5143
5066
  });
@@ -9093,7 +9016,7 @@ async function processClaudePairSessions(agents) {
9093
9016
  killPairSession,
9094
9017
  pairTmuxSession,
9095
9018
  finalizeClaudePairOnboarding
9096
- } = await import("../claude-pair-runtime-2XWSYFSY.js");
9019
+ } = await import("../claude-pair-runtime-EZ73GJW7.js");
9097
9020
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
9098
9021
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
9099
9022
  const killed = await killPairSession(pairTmuxSession(pairId));