@integrity-labs/agt-cli 0.28.138 → 0.28.140

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.
@@ -100,7 +100,7 @@ async function spawnPairSession(session) {
100
100
  return { ok: true };
101
101
  } catch {
102
102
  }
103
- const { resolveClaudeBinary } = await import("./persistent-session-SVZCOP7I.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-BRGQGGZY.js");
104
104
  const claudeBin = resolveClaudeBinary();
105
105
  const pairEnv = {
106
106
  ...process.env,
@@ -373,4 +373,4 @@ export {
373
373
  startClaudePair,
374
374
  submitClaudePairCode
375
375
  };
376
- //# sourceMappingURL=claude-pair-runtime-7TJXAPIK.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-CSTESL6B.js.map
@@ -28,7 +28,7 @@ import {
28
28
  requireHost,
29
29
  safeWriteJsonAtomic,
30
30
  setConfigHash
31
- } from "../chunk-QJCTWNIJ.js";
31
+ } from "../chunk-3R2XOKXQ.js";
32
32
  import {
33
33
  getProjectDir as getProjectDir2,
34
34
  getReadyTasks,
@@ -72,7 +72,7 @@ import {
72
72
  takeZombieDetection,
73
73
  transcriptActivityAgeSeconds,
74
74
  writeEgressAllowlist
75
- } from "../chunk-NGES4EZD.js";
75
+ } from "../chunk-6GNDRA3F.js";
76
76
  import {
77
77
  FLAGS_SCHEMA_VERSION,
78
78
  FLAG_REGISTRY,
@@ -110,14 +110,14 @@ import {
110
110
  resolveDmTarget,
111
111
  sumTranscriptUsageInWindow,
112
112
  wrapScheduledTaskPrompt
113
- } from "../chunk-ROOFBKRE.js";
113
+ } from "../chunk-WI6HYZ7K.js";
114
114
  import {
115
115
  parsePsRows,
116
116
  reapOrphanChannelMcps
117
117
  } from "../chunk-XWVM4KPK.js";
118
118
 
119
119
  // src/lib/manager-worker.ts
120
- import { createHash as createHash9 } from "crypto";
120
+ import { createHash as createHash10 } from "crypto";
121
121
  import { readFileSync as readFileSync15, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, existsSync as existsSync9, rmSync as rmSync4, readdirSync as readdirSync5, statSync as statSync4, unlinkSync, copyFileSync } from "fs";
122
122
  import { execFileSync as syncExecFile } from "child_process";
123
123
  import { join as join16, dirname as dirname5 } from "path";
@@ -4396,6 +4396,28 @@ function formatBoardForPrompt(items, template) {
4396
4396
  return lines.join("\n");
4397
4397
  }
4398
4398
 
4399
+ // src/lib/manager/kanban/notify.ts
4400
+ import { createHash as createHash6 } from "crypto";
4401
+ async function enqueueKanbanNotice(opts) {
4402
+ try {
4403
+ const res = await api.post(
4404
+ "/host/kanban/notify",
4405
+ {
4406
+ agent_id: opts.agentId,
4407
+ content: opts.content,
4408
+ run_id: opts.runId ?? void 0,
4409
+ actionable_count: opts.actionableCount
4410
+ }
4411
+ );
4412
+ return res.ok === true;
4413
+ } catch (err) {
4414
+ const errText = err instanceof Error ? err.message : String(err);
4415
+ const errId = createHash6("sha256").update(errText).digest("hex").slice(0, 12);
4416
+ log(`[kanban] notice enqueue failed for agent_id=${opts.agentId} error_id=${errId}`);
4417
+ return false;
4418
+ }
4419
+ }
4420
+
4399
4421
  // src/lib/manager/channels/state.ts
4400
4422
  var agentChannelTokens = /* @__PURE__ */ new Map();
4401
4423
  var alertSlackWebhook = null;
@@ -4761,7 +4783,7 @@ function isScheduledViaKanbanEnabled() {
4761
4783
  }
4762
4784
 
4763
4785
  // src/lib/manager/scheduler/runs.ts
4764
- import { createHash as createHash6 } from "crypto";
4786
+ import { createHash as createHash7 } from "crypto";
4765
4787
  async function startRun(opts) {
4766
4788
  try {
4767
4789
  const res = await api.post(
@@ -4771,7 +4793,7 @@ async function startRun(opts) {
4771
4793
  return { run_id: res.run_id ?? null, kanban_item_id: res.kanban_item_id ?? null };
4772
4794
  } catch (err) {
4773
4795
  const errText = err instanceof Error ? err.message : String(err);
4774
- const errId = createHash6("sha256").update(errText).digest("hex").slice(0, 12);
4796
+ const errId = createHash7("sha256").update(errText).digest("hex").slice(0, 12);
4775
4797
  log(`[runs] start failed for agent_id=${opts.agent_id} source_type=${opts.source_type} error_id=${errId}`);
4776
4798
  return { run_id: null, kanban_item_id: null };
4777
4799
  }
@@ -4788,7 +4810,7 @@ async function finishRun(runId, outcome, options = {}) {
4788
4810
  });
4789
4811
  } catch (err) {
4790
4812
  const errText = err instanceof Error ? err.message : String(err);
4791
- const errId = createHash6("sha256").update(errText).digest("hex").slice(0, 12);
4813
+ const errId = createHash7("sha256").update(errText).digest("hex").slice(0, 12);
4792
4814
  log(`[runs] finish failed for run_id=${runId} outcome=${outcome} error_id=${errId}`);
4793
4815
  }
4794
4816
  }
@@ -4805,7 +4827,7 @@ async function fetchPriorScheduledRuns(agentId, taskId) {
4805
4827
  return rows.filter((r) => typeof r.output_text === "string" && r.output_text.length > 0).map((r) => ({ startedAt: r.started_at, output: r.output_text }));
4806
4828
  } catch (err) {
4807
4829
  const errText = err instanceof Error ? err.message : String(err);
4808
- const errId = createHash6("sha256").update(errText).digest("hex").slice(0, 12);
4830
+ const errId = createHash7("sha256").update(errText).digest("hex").slice(0, 12);
4809
4831
  log(`[runs] prior-runs lookup failed for task_id=${taskId} error_id=${errId}`);
4810
4832
  return [];
4811
4833
  }
@@ -4854,7 +4876,7 @@ function closeScheduledRunsForCode(codeName, outcome, reason) {
4854
4876
  }
4855
4877
 
4856
4878
  // src/lib/manager/scheduler/kanban-route.ts
4857
- import { createHash as createHash7 } from "crypto";
4879
+ import { createHash as createHash8 } from "crypto";
4858
4880
 
4859
4881
  // src/lib/delivery-schedule-link.ts
4860
4882
  function envSuffixFor2(codeName) {
@@ -5269,10 +5291,10 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
5269
5291
  const classification = classifyOutput(rawOutput);
5270
5292
  if (classification.action === "suppress") {
5271
5293
  const trimmed = (rawOutput ?? "").trim();
5272
- const outputHash = trimmed.length === 0 ? "empty" : createHash7("sha256").update(trimmed).digest("hex").slice(0, 12);
5294
+ const outputHash = trimmed.length === 0 ? "empty" : createHash8("sha256").update(trimmed).digest("hex").slice(0, 12);
5273
5295
  log(`[claude-scheduler] Suppressing delivery for '${codeName}' (template=${templateId}, task=${delivery?.taskId ?? "n/a"}) \u2014 output_len=${trimmed.length} output_hash=${outputHash}`);
5274
5296
  if (classification.suppressedNotes) {
5275
- const notesHash = createHash7("sha256").update(classification.suppressedNotes).digest("hex").slice(0, 12);
5297
+ const notesHash = createHash8("sha256").update(classification.suppressedNotes).digest("hex").slice(0, 12);
5276
5298
  log(`[claude-scheduler] Suppressed notes for '${codeName}' (task=${delivery?.taskId ?? "n/a"}) \u2014 notes_len=${classification.suppressedNotes.length} notes_hash=${notesHash}`);
5277
5299
  }
5278
5300
  if (delivery?.mode === "announce" && delivery.to) {
@@ -5338,7 +5360,7 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
5338
5360
  }
5339
5361
 
5340
5362
  // src/lib/manager/scheduler/execution.ts
5341
- import { createHash as createHash8 } from "crypto";
5363
+ import { createHash as createHash9 } from "crypto";
5342
5364
  import { readFileSync as readFileSync13, existsSync as existsSync7 } from "fs";
5343
5365
  import { homedir as homedir7 } from "os";
5344
5366
  import { join as join14 } from "path";
@@ -5363,10 +5385,10 @@ function unregisterClaudeSpawn(pid) {
5363
5385
  }
5364
5386
  async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData) {
5365
5387
  const codeName = agent.code_name;
5366
- const stableTasksHash = createHash8("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
5367
- const boardHash = boardItems.length > 0 ? createHash8("sha256").update(JSON.stringify(boardItems.map((b) => ({ id: b.id, title: b.title, status: b.status, priority: b.priority, deliverable: b.deliverable })))).digest("hex").slice(0, 16) : "empty";
5388
+ const stableTasksHash = createHash9("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
5389
+ const boardHash = boardItems.length > 0 ? createHash9("sha256").update(JSON.stringify(boardItems.map((b) => ({ id: b.id, title: b.title, status: b.status, priority: b.priority, deliverable: b.deliverable })))).digest("hex").slice(0, 16) : "empty";
5368
5390
  const resolvedModels = resolveModelChain(refreshData);
5369
- const modelsHash = createHash8("sha256").update(JSON.stringify(resolvedModels)).digest("hex").slice(0, 16);
5391
+ const modelsHash = createHash9("sha256").update(JSON.stringify(resolvedModels)).digest("hex").slice(0, 16);
5370
5392
  const combinedHash = `${stableTasksHash}:${boardHash}:${modelsHash}`;
5371
5393
  const prevHash = agentState.knownTasksHashes.get(agent.agent_id);
5372
5394
  if (combinedHash !== prevHash) {
@@ -6816,7 +6838,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
6816
6838
  function projectMcpHash(_codeName, projectDir) {
6817
6839
  try {
6818
6840
  const raw = readFileSync15(join16(projectDir, ".mcp.json"), "utf-8");
6819
- return createHash9("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
6841
+ return createHash10("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
6820
6842
  } catch {
6821
6843
  return null;
6822
6844
  }
@@ -7070,7 +7092,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
7070
7092
  var lastVersionCheckAt = 0;
7071
7093
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
7072
7094
  var lastResponsivenessProbeAt = 0;
7073
- var agtCliVersion = true ? "0.28.138" : "dev";
7095
+ var agtCliVersion = true ? "0.28.140" : "dev";
7074
7096
  function resolveBrewPath(execFileSync4) {
7075
7097
  try {
7076
7098
  const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -8203,7 +8225,7 @@ async function pollCycle() {
8203
8225
  }
8204
8226
  try {
8205
8227
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
8206
- const { collectDiagnostics } = await import("../persistent-session-SVZCOP7I.js");
8228
+ const { collectDiagnostics } = await import("../persistent-session-BRGQGGZY.js");
8207
8229
  const diagCodeNames = [...agentState.persistentSessionAgents];
8208
8230
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
8209
8231
  let tailscaleHostname;
@@ -8233,7 +8255,7 @@ async function pollCycle() {
8233
8255
  claudeAuth = await detectClaudeAuth();
8234
8256
  } catch (err) {
8235
8257
  const errText = err instanceof Error ? err.message : String(err);
8236
- const errId = createHash9("sha256").update(errText).digest("hex").slice(0, 12);
8258
+ const errId = createHash10("sha256").update(errText).digest("hex").slice(0, 12);
8237
8259
  log(`Claude auth detection failed (error_id=${errId})`);
8238
8260
  }
8239
8261
  const hostHasClaudeCode = state6.agents.some(
@@ -8351,7 +8373,7 @@ async function pollCycle() {
8351
8373
  const {
8352
8374
  collectResponsivenessProbes,
8353
8375
  getResponsivenessIntervalMs
8354
- } = await import("../responsiveness-probe-AS7ASMDE.js");
8376
+ } = await import("../responsiveness-probe-RZYQMCM3.js");
8355
8377
  const probeIntervalMs = getResponsivenessIntervalMs();
8356
8378
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
8357
8379
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -8383,7 +8405,7 @@ async function pollCycle() {
8383
8405
  collectResponsivenessProbes,
8384
8406
  livePendingInboundOldestAgeSeconds,
8385
8407
  parkPendingInbound
8386
- } = await import("../responsiveness-probe-AS7ASMDE.js");
8408
+ } = await import("../responsiveness-probe-RZYQMCM3.js");
8387
8409
  const { getProjectDir: wedgeProjectDir } = await import("../claude-scheduler-FATCLHDM.js");
8388
8410
  const wedgeNow = /* @__PURE__ */ new Date();
8389
8411
  const liveAgents = agentState.persistentSessionAgents;
@@ -9506,7 +9528,7 @@ async function processAgent(agent, agentStates) {
9506
9528
  if (channelConfigConverged) {
9507
9529
  const hasSenderPolicyChannel = currentChannelIds.has("slack") || currentChannelIds.has("msteams");
9508
9530
  const senderPolicyForRestartHash = refreshData.sender_policy ?? null;
9509
- const senderPolicyHash = createHash9("sha256").update(canonicalJson({ senderPolicy: senderPolicyForRestartHash })).digest("hex");
9531
+ const senderPolicyHash = createHash10("sha256").update(canonicalJson({ senderPolicy: senderPolicyForRestartHash })).digest("hex");
9510
9532
  const prevSenderPolicyHash = agentState.knownSenderPolicyHashes.get(agent.agent_id);
9511
9533
  const senderPolicyDecision = hasSenderPolicyChannel ? decideSenderPolicyRestart({
9512
9534
  previousHash: prevSenderPolicyHash,
@@ -9548,7 +9570,7 @@ async function processAgent(agent, agentStates) {
9548
9570
  const behaviourSubset = extractMsTeamsBehaviourSubset(
9549
9571
  msteamsEntry?.config
9550
9572
  );
9551
- const behaviourHash = createHash9("sha256").update(canonicalJson(behaviourSubset)).digest("hex");
9573
+ const behaviourHash = createHash10("sha256").update(canonicalJson(behaviourSubset)).digest("hex");
9552
9574
  const prevBehaviourHash = agentState.knownMsTeamsBehaviourHashes.get(agent.agent_id);
9553
9575
  const behaviourDecision = decideSenderPolicyRestart({
9554
9576
  previousHash: prevBehaviourHash,
@@ -9595,7 +9617,7 @@ async function processAgent(agent, agentStates) {
9595
9617
  const slackBehaviourSubset = extractSlackBehaviourSubset(
9596
9618
  slackEntry?.config
9597
9619
  );
9598
- const slackBehaviourHash = createHash9("sha256").update(canonicalJson(slackBehaviourSubset)).digest("hex");
9620
+ const slackBehaviourHash = createHash10("sha256").update(canonicalJson(slackBehaviourSubset)).digest("hex");
9599
9621
  const prevSlackBehaviourHash = agentState.knownSlackBehaviourHashes.get(agent.agent_id);
9600
9622
  const slackBehaviourDecision = decideSenderPolicyRestart({
9601
9623
  previousHash: prevSlackBehaviourHash,
@@ -9853,10 +9875,10 @@ async function processAgent(agent, agentStates) {
9853
9875
  desiredEntries.push({ serverId, url, headers: mcpHeaders, name: tk.toolkit_name });
9854
9876
  }
9855
9877
  const hashBasis = desiredEntries.slice().sort((a, b) => a.serverId.localeCompare(b.serverId)).map((e) => {
9856
- const headersHash = createHash9("sha256").update(canonicalJson(e.headers ?? {})).digest("hex").slice(0, 16);
9878
+ const headersHash = createHash10("sha256").update(canonicalJson(e.headers ?? {})).digest("hex").slice(0, 16);
9857
9879
  return `${e.serverId}|${e.url}|${headersHash}`;
9858
9880
  }).join("\n");
9859
- const mcpHash = createHash9("sha256").update(hashBasis).digest("hex").slice(0, 16);
9881
+ const mcpHash = createHash10("sha256").update(hashBasis).digest("hex").slice(0, 16);
9860
9882
  const prevMcpHash = agentState.knownManagedMcpHashes.get(agent.agent_id);
9861
9883
  const structureHash = managedMcpStructureHash(desiredEntries);
9862
9884
  const prevStructureHash = agentState.knownManagedMcpStructure.get(agent.agent_id);
@@ -9871,7 +9893,7 @@ async function processAgent(agent, agentStates) {
9871
9893
  if (mcpHash !== prevMcpHash) {
9872
9894
  for (const e of desiredEntries) {
9873
9895
  frameworkAdapter.writeMcpServer(agent.code_name, e.serverId, { url: e.url, headers: e.headers });
9874
- const urlHash = createHash9("sha256").update(e.url).digest("hex").slice(0, 12);
9896
+ const urlHash = createHash10("sha256").update(e.url).digest("hex").slice(0, 12);
9875
9897
  log(`[managed-toolkit] ${agent.code_name}: wrote '${e.name}' (serverId=${e.serverId}, url_hash=${urlHash})`);
9876
9898
  }
9877
9899
  if (frameworkAdapter.removeMcpServer && frameworkAdapter.getMcpPath) {
@@ -10005,7 +10027,7 @@ async function processAgent(agent, agentStates) {
10005
10027
  if (frameworkAdapter.installSkillFiles) {
10006
10028
  const currentIntegrationSkillIds = /* @__PURE__ */ new Set();
10007
10029
  const installedIntegrationSkills = [];
10008
- const { createHash: createHash10 } = await import("crypto");
10030
+ const { createHash: createHash11 } = await import("crypto");
10009
10031
  const refreshAny = refreshData;
10010
10032
  const contexts = refreshAny.integration_contexts ?? refreshAny.plugin_contexts ?? [];
10011
10033
  const contextBySlug = /* @__PURE__ */ new Map();
@@ -10034,7 +10056,7 @@ async function processAgent(agent, agentStates) {
10034
10056
  )
10035
10057
  }));
10036
10058
  const bundle = buildIntegrationBundle(renderedScopes);
10037
- const contentHash = createHash10("sha256").update(bundleFingerprint(bundle.files)).digest("hex").slice(0, 12);
10059
+ const contentHash = createHash11("sha256").update(bundleFingerprint(bundle.files)).digest("hex").slice(0, 12);
10038
10060
  const hashKey = `plugin-skill:${agent.agent_id}:${integrationSkillId}`;
10039
10061
  if (agentState.knownSkillHashes.get(hashKey) === contentHash) continue;
10040
10062
  frameworkAdapter.installSkillFiles(agent.code_name, integrationSkillId, bundle.files);
@@ -10093,7 +10115,7 @@ async function processAgent(agent, agentStates) {
10093
10115
  const plan = planGlobalSkillSync(
10094
10116
  refreshAny.global_skills ?? [],
10095
10117
  agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
10096
- (content) => createHash10("sha256").update(content).digest("hex").slice(0, 12),
10118
+ (content) => createHash11("sha256").update(content).digest("hex").slice(0, 12),
10097
10119
  (skillId) => agentState.knownSkillHashes.get(`global-skill:${agent.agent_id}:${skillId}`)
10098
10120
  );
10099
10121
  for (const { skillId, content, hash } of plan.installs) {
@@ -10137,7 +10159,7 @@ async function processAgent(agent, agentStates) {
10137
10159
  const slug = hook.integration_slug ?? hook.plugin_slug;
10138
10160
  if (!slug) continue;
10139
10161
  try {
10140
- const scriptHash = createHash10("sha256").update(hook.script).digest("hex").slice(0, 12);
10162
+ const scriptHash = createHash11("sha256").update(hook.script).digest("hex").slice(0, 12);
10141
10163
  const hookKey = `${agent.agent_id}:${frameworkAdapter.id}:plugin-hook:${slug}:on_install`;
10142
10164
  if (agentState.knownSkillHashes.get(hookKey) === scriptHash) continue;
10143
10165
  const result = await frameworkAdapter.executePluginHook({
@@ -10152,9 +10174,9 @@ async function processAgent(agent, agentStates) {
10152
10174
  } else if (result.timedOut) {
10153
10175
  log(`Integration hook on_install '${slug}' TIMED OUT for '${agent.code_name}' after ${result.durationMs}ms`);
10154
10176
  } else {
10155
- const stderrHash = createHash10("sha256").update(result.stderr).digest("hex").slice(0, 12);
10177
+ const stderrHash = createHash11("sha256").update(result.stderr).digest("hex").slice(0, 12);
10156
10178
  const missingCmd = result.exitCode === 127 ? extractCommandNotFound(result.stderr) : null;
10157
- const missingCmdHash = missingCmd ? createHash10("sha256").update(missingCmd).digest("hex").slice(0, 8) : null;
10179
+ const missingCmdHash = missingCmd ? createHash11("sha256").update(missingCmd).digest("hex").slice(0, 8) : null;
10158
10180
  log(
10159
10181
  `Integration hook on_install '${slug}' exited ${result.exitCode} for '${agent.code_name}' ` + (missingCmdHash ? `[missing_command_hash=${missingCmdHash}] ` : "") + `[stderr_hash=${stderrHash} stderr_len=${result.stderr.length}]`
10160
10182
  );
@@ -10433,10 +10455,10 @@ async function processAgent(agent, agentStates) {
10433
10455
  } else if (agentFw === "claude-code" && tasks.length > 0) {
10434
10456
  await syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData);
10435
10457
  } else if (frameworkAdapter.syncScheduledTasks && gatewayRunning && gatewayPort) {
10436
- const stableTasksHash = createHash9("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
10437
- const boardHash = boardItems.length > 0 ? createHash9("sha256").update(JSON.stringify(boardItems.map((b) => ({ id: b.id, title: b.title, status: b.status, priority: b.priority, deliverable: b.deliverable })))).digest("hex").slice(0, 16) : "empty";
10458
+ const stableTasksHash = createHash10("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
10459
+ const boardHash = boardItems.length > 0 ? createHash10("sha256").update(JSON.stringify(boardItems.map((b) => ({ id: b.id, title: b.title, status: b.status, priority: b.priority, deliverable: b.deliverable })))).digest("hex").slice(0, 16) : "empty";
10438
10460
  const resolvedModels = resolveModelChain(refreshData);
10439
- const modelsHash = createHash9("sha256").update(JSON.stringify(resolvedModels)).digest("hex").slice(0, 16);
10461
+ const modelsHash = createHash10("sha256").update(JSON.stringify(resolvedModels)).digest("hex").slice(0, 16);
10440
10462
  const combinedHash = `${stableTasksHash}:${boardHash}:${modelsHash}`;
10441
10463
  const prevTasksHash = agentState.knownTasksHashes.get(agent.agent_id);
10442
10464
  if (combinedHash !== prevTasksHash) {
@@ -10984,7 +11006,7 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
10984
11006
  const ctx = getLastFailureContext(codeName);
10985
11007
  const recovery = prepareForRespawn(codeName);
10986
11008
  const tailSummary = !ctx.tail ? "" : KNOWN_SAFE_TAIL_SIGNATURES.has(ctx.signature) ? `; last pane output (${PANE_TAIL_PREVIEW_LINES} of ~20 lines):
10987
- ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash9("sha256").update(ctx.tail).digest("hex").slice(0, 12)} (raw at ~/.augmented/${codeName}/pane.log)`;
11009
+ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash10("sha256").update(ctx.tail).digest("hex").slice(0, 12)} (raw at ~/.augmented/${codeName}/pane.log)`;
10988
11010
  const sigSummary = ctx.signature !== "unknown" ? `; signature=${ctx.signature}` : "";
10989
11011
  const recoverySummary = recovery ? `; recovery=${recovery}` : "";
10990
11012
  log(
@@ -10998,7 +11020,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash9("sha256").
10998
11020
  );
10999
11021
  getHostId().then((hostId) => {
11000
11022
  if (!hostId) return;
11001
- const paneTailHash = zombie.paneTail ? `sha256:${createHash9("sha256").update(zombie.paneTail).digest("hex").slice(0, 12)}` : null;
11023
+ const paneTailHash = zombie.paneTail ? `sha256:${createHash10("sha256").update(zombie.paneTail).digest("hex").slice(0, 12)}` : null;
11002
11024
  return api.post("/host/events", {
11003
11025
  host_id: hostId,
11004
11026
  agent_code_name: codeName,
@@ -11114,7 +11136,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash9("sha256").
11114
11136
  if (!claudeAuthTupleBySession.has(codeName)) {
11115
11137
  claudeAuthTupleBySession.set(codeName, currentAuthTuple);
11116
11138
  }
11117
- const stableTasksHash = createHash9("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
11139
+ const stableTasksHash = createHash10("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
11118
11140
  const prevHash = agentState.knownTasksHashes.get(agent.agent_id);
11119
11141
  if (stableTasksHash !== prevHash) {
11120
11142
  const taskInputs = tasks.map((t) => buildSchedulerTaskInput(t));
@@ -11640,7 +11662,7 @@ ${escapeXml(msg.content)}
11640
11662
  log(`[direct-chat] Reply sent for '${agent.codeName}'`);
11641
11663
  } catch (err) {
11642
11664
  const errMsg = err instanceof Error ? err.message : String(err);
11643
- const errorId = createHash9("sha256").update(errMsg).digest("hex").slice(0, 12);
11665
+ const errorId = createHash10("sha256").update(errMsg).digest("hex").slice(0, 12);
11644
11666
  log(`[direct-chat] Failed to process message for '${agent.codeName}': error_id=${errorId} error=${errMsg.slice(0, 500)}`);
11645
11667
  try {
11646
11668
  await api.post("/host/direct-chat/reply", {
@@ -11668,12 +11690,51 @@ var KANBAN_HYBRID_DEBOUNCE_MS = (() => {
11668
11690
  if (Number.isFinite(parsed) && parsed > 0) return Math.max(parsed, 10) * 1e3;
11669
11691
  return 6e4;
11670
11692
  })();
11693
+ async function injectKanbanCheckViaDirectChat(codeName, agentId, actionableCount) {
11694
+ if (isKanbanHybridDryRun()) {
11695
+ log(
11696
+ `[manager-worker] kanban inject DRY-RUN (direct-chat) \u2014 would enqueue for '${codeName}' (${actionableCount} actionable items)`
11697
+ );
11698
+ lastKanbanInjectAt.delete(codeName);
11699
+ return true;
11700
+ }
11701
+ closeInjectedRunIfOpen(codeName, "completed", "kanban inject superseded by next inject");
11702
+ const { run_id } = await startRun({
11703
+ agent_id: agentId,
11704
+ source_type: "kanban",
11705
+ metadata: { injected: "kanban-check", actionable_count: actionableCount, delivery: "direct-chat" }
11706
+ });
11707
+ const content = run_id ? `${KANBAN_CHECK_COMMAND}
11708
+ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
11709
+ const ok = await enqueueKanbanNotice({ agentId, content, runId: run_id, actionableCount });
11710
+ if (!ok) {
11711
+ if (run_id) void finishRun(run_id, "failed", { outcomeMessage: "kanban notice enqueue failed" });
11712
+ return false;
11713
+ }
11714
+ if (run_id) openInjectedRunByCode.set(codeName, run_id);
11715
+ try {
11716
+ const doorbell = directChatDoorbellPath(agentId, homedir9());
11717
+ mkdirSync6(dirname5(doorbell), { recursive: true });
11718
+ writeFileSync6(doorbell, String(Date.now()));
11719
+ } catch (err) {
11720
+ log(`[kanban] doorbell ring failed for '${codeName}': ${err.message} (notice still queued)`);
11721
+ }
11722
+ log(
11723
+ `[manager-worker] Enqueued kanban check via direct-chat for '${codeName}' (${actionableCount} actionable items)${run_id ? ` run_id=${run_id}` : ""}`
11724
+ );
11725
+ return true;
11726
+ }
11671
11727
  async function maybeInjectKanbanCheck(codeName, agentId, actionableCount) {
11672
11728
  const lastAt = lastKanbanInjectAt.get(codeName) ?? 0;
11673
11729
  if (Date.now() - lastAt < KANBAN_HYBRID_DEBOUNCE_MS) {
11674
11730
  return;
11675
11731
  }
11676
11732
  lastKanbanInjectAt.set(codeName, Date.now());
11733
+ if (hostFlagStore().getBoolean("kanban-doorbell")) {
11734
+ const ok = await injectKanbanCheckViaDirectChat(codeName, agentId, actionableCount);
11735
+ if (ok) return;
11736
+ log(`[manager-worker] kanban direct-chat enqueue failed for '${codeName}' \u2014 falling back to send-keys`);
11737
+ }
11677
11738
  const tmuxSession = `agt-${codeName}`;
11678
11739
  const ready = await isAgentPromptReady(tmuxSession);
11679
11740
  if (!ready) {
@@ -11932,7 +11993,7 @@ async function processClaudePairSessions(agents) {
11932
11993
  killPairSession,
11933
11994
  pairTmuxSession,
11934
11995
  finalizeClaudePairOnboarding
11935
- } = await import("../claude-pair-runtime-7TJXAPIK.js");
11996
+ } = await import("../claude-pair-runtime-CSTESL6B.js");
11936
11997
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
11937
11998
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
11938
11999
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -12196,7 +12257,7 @@ async function syncMemories(agent, configDir, log2) {
12196
12257
  if (!file.endsWith(".md")) continue;
12197
12258
  try {
12198
12259
  const raw = readFileSync15(join16(memoryDir, file), "utf-8");
12199
- const fileHash = createHash9("sha256").update(raw).digest("hex").slice(0, 16);
12260
+ const fileHash = createHash10("sha256").update(raw).digest("hex").slice(0, 16);
12200
12261
  currentHashes.set(file, fileHash);
12201
12262
  if (prevHashes.get(file) === fileHash) continue;
12202
12263
  const parsed = parseMemoryFile(raw, file.replace(/\.md$/, ""));
@@ -12234,14 +12295,14 @@ async function syncMemories(agent, configDir, log2) {
12234
12295
  }
12235
12296
  async function downloadMemories(agent, memoryDir, log2, { force }) {
12236
12297
  const localFiles = existsSync9(memoryDir) ? readdirSync5(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
12237
- const localListHash = createHash9("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
12298
+ const localListHash = createHash10("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
12238
12299
  const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
12239
12300
  const prevDownload = lastDownloadHash.get(agent.agent_id);
12240
12301
  try {
12241
12302
  const dbMemories = await api.post("/host/memories", {
12242
12303
  agent_id: agent.agent_id
12243
12304
  });
12244
- const responseHash = createHash9("sha256").update(JSON.stringify(dbMemories.memories ?? [])).digest("hex").slice(0, 16);
12305
+ const responseHash = createHash10("sha256").update(JSON.stringify(dbMemories.memories ?? [])).digest("hex").slice(0, 16);
12245
12306
  if (!force && prevDownload && prevLocalHash === localListHash && lastDownloadHash.get(agent.agent_id) === responseHash) {
12246
12307
  return true;
12247
12308
  }
@@ -12280,7 +12341,7 @@ ${mem.content}
12280
12341
  }
12281
12342
  if (written > 0 || overwritten > 0) {
12282
12343
  const updatedFiles = readdirSync5(memoryDir).filter((f) => f.endsWith(".md")).sort();
12283
- lastLocalFileHash.set(agent.agent_id, createHash9("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
12344
+ lastLocalFileHash.set(agent.agent_id, createHash10("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
12284
12345
  log2(`Memory download for '${agent.code_name}': wrote ${written} new, overwrote ${overwritten} stale`);
12285
12346
  }
12286
12347
  }
@@ -12723,7 +12784,7 @@ function deployMcpAssets() {
12723
12784
  const fileHash = (p) => {
12724
12785
  try {
12725
12786
  if (!existsSync9(p)) return null;
12726
- return createHash9("sha256").update(readFileSync15(p)).digest("hex");
12787
+ return createHash10("sha256").update(readFileSync15(p)).digest("hex");
12727
12788
  } catch {
12728
12789
  return null;
12729
12790
  }