@integrity-labs/agt-cli 0.22.6 → 0.23.1

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.
@@ -11,7 +11,7 @@ import {
11
11
  provisionOrientHook,
12
12
  provisionStopHook,
13
13
  requireHost
14
- } from "../chunk-Y2XFZBEE.js";
14
+ } from "../chunk-Q4QD3TAC.js";
15
15
  import {
16
16
  findTaskByTemplate,
17
17
  getProjectDir as getProjectDir2,
@@ -27,21 +27,28 @@ import {
27
27
  getProjectDir,
28
28
  getSessionState,
29
29
  injectMessage,
30
+ isAgentIdle,
31
+ isAgentPromptReady,
30
32
  isKanbanLoopArmedForCurrentSession,
33
+ isKanbanLoopDisabled,
31
34
  isSessionHealthy,
35
+ isStaleForToday,
32
36
  parsePsRows,
37
+ peekCurrentSession,
33
38
  prepareForRespawn,
34
39
  readPaneLogTail,
35
40
  reapOrphanChannelMcps,
36
41
  resetRestartCount,
37
42
  resolveClaudeBinary,
38
43
  sanitizeMcpJson,
44
+ sendToAgent,
39
45
  startPersistentSession,
40
46
  stopAllSessionsAndWait,
41
47
  stopPersistentSession,
42
48
  takeZombieDetection
43
- } from "../chunk-XNO35ZAN.js";
49
+ } from "../chunk-TCCBS3PD.js";
44
50
  import {
51
+ KANBAN_CHECK_COMMAND,
45
52
  appendDmFooter,
46
53
  classifyOutput,
47
54
  extractFrontmatter,
@@ -55,7 +62,7 @@ import {
55
62
  resolveChannels,
56
63
  resolveDmTarget,
57
64
  wrapScheduledTaskPrompt
58
- } from "../chunk-E56L56ER.js";
65
+ } from "../chunk-2TOCO5D2.js";
59
66
 
60
67
  // src/lib/manager-worker.ts
61
68
  import { createHash as createHash2 } from "crypto";
@@ -2465,7 +2472,7 @@ var cachedFrameworkVersion = null;
2465
2472
  var lastVersionCheckAt = 0;
2466
2473
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
2467
2474
  var lastResponsivenessProbeAt = 0;
2468
- var agtCliVersion = true ? "0.22.6" : "dev";
2475
+ var agtCliVersion = true ? "0.23.1" : "dev";
2469
2476
  function resolveBrewPath(execFileSync4) {
2470
2477
  try {
2471
2478
  const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -3422,7 +3429,7 @@ async function pollCycle() {
3422
3429
  }
3423
3430
  try {
3424
3431
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
3425
- const { collectDiagnostics } = await import("../persistent-session-WGHWG5XS.js");
3432
+ const { collectDiagnostics } = await import("../persistent-session-XEA4SPAN.js");
3426
3433
  const diagCodeNames = [...persistentSessionAgents];
3427
3434
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
3428
3435
  let tailscaleHostname;
@@ -3473,7 +3480,7 @@ async function pollCycle() {
3473
3480
  const {
3474
3481
  collectResponsivenessProbes,
3475
3482
  getResponsivenessIntervalMs
3476
- } = await import("../responsiveness-probe-SEK5X5VL.js");
3483
+ } = await import("../responsiveness-probe-VWPOCABI.js");
3477
3484
  const probeIntervalMs = getResponsivenessIntervalMs();
3478
3485
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
3479
3486
  const probeCodeNames = [...persistentSessionAgents];
@@ -4674,6 +4681,27 @@ async function processAgent(agent, agentStates) {
4674
4681
  }
4675
4682
  const agentFw = agentFrameworkCache.get(agent.code_name) ?? "openclaw";
4676
4683
  const sessionMode = refreshData.agent.session_mode ?? "oneshot";
4684
+ if (isKanbanHybridEnabled() && agentFw === "claude-code" && sessionMode === "persistent") {
4685
+ let hybridBoard = hasBoardTemplates ? boardItems : void 0;
4686
+ if (!hybridBoard) {
4687
+ try {
4688
+ const boardData = await api.post(
4689
+ "/host/my-kanban",
4690
+ { agent_id: agent.agent_id }
4691
+ );
4692
+ hybridBoard = (boardData.items ?? []).map(sanitizeBoardItem);
4693
+ kanbanBoardCache.set(agent.code_name, hybridBoard);
4694
+ } catch {
4695
+ hybridBoard = kanbanBoardCache.get(agent.code_name) ?? [];
4696
+ }
4697
+ }
4698
+ if (hasHybridActionableItems(hybridBoard)) {
4699
+ const actionableCount = hybridBoard.filter(
4700
+ (i) => HYBRID_ACTIONABLE_STATUSES.has(i.status)
4701
+ ).length;
4702
+ void maybeInjectKanbanCheck(agent.code_name, actionableCount);
4703
+ }
4704
+ }
4677
4705
  if (agentFw === "claude-code" && sessionMode === "persistent") {
4678
4706
  const wasSessionHealthy = isSessionHealthy(agent.code_name);
4679
4707
  let psResult;
@@ -5594,6 +5622,7 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
5594
5622
  };
5595
5623
  }
5596
5624
  let restartTrigger = null;
5625
+ let dayRolloverDeferred = false;
5597
5626
  const currentAuthTuple = `${claudeAuthMode}:${anthropicApiKeyFingerprint ?? "none"}`;
5598
5627
  const recordedAuthTuple = claudeAuthTupleBySession.get(codeName);
5599
5628
  if (recordedAuthTuple && recordedAuthTuple !== currentAuthTuple && isSessionHealthy(codeName)) {
@@ -5602,6 +5631,25 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
5602
5631
  persistentSessionAgents.delete(codeName);
5603
5632
  restartTrigger = "auth-tuple";
5604
5633
  }
5634
+ if (isStaleForToday(codeName, /* @__PURE__ */ new Date(), agentTimezone) && isSessionHealthy(codeName)) {
5635
+ const current = peekCurrentSession(codeName);
5636
+ if (current) {
5637
+ const idle = isAgentIdle(projectDir, current.sessionId);
5638
+ if (idle) {
5639
+ log(
5640
+ `[persistent-session] Day rollover for '${codeName}' (yesterday=${current.date}) \u2014 agent idle, restarting to mint fresh session`
5641
+ );
5642
+ stopPersistentSessionAndForgetMcpBaseline(codeName);
5643
+ persistentSessionAgents.delete(codeName);
5644
+ restartTrigger = "day-rollover";
5645
+ } else {
5646
+ log(
5647
+ `[persistent-session] Day rollover for '${codeName}' deferred \u2014 agent still active on session ${current.sessionId} (will retry next tick)`
5648
+ );
5649
+ dayRolloverDeferred = true;
5650
+ }
5651
+ }
5652
+ }
5605
5653
  if (!isSessionHealthy(codeName)) {
5606
5654
  if (persistentSessionAgents.has(codeName)) {
5607
5655
  const ctx = getLastFailureContext(codeName);
@@ -5769,7 +5817,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash2("sha256").
5769
5817
  break;
5770
5818
  }
5771
5819
  }
5772
- const finalDecision = restartTrigger === "auth-tuple" ? "restart-pending" : "healthy";
5820
+ const finalDecision = restartTrigger === "auth-tuple" ? "restart-pending" : restartTrigger === "day-rollover" ? "day-rollover-restart" : dayRolloverDeferred ? "day-rollover-deferred" : "healthy";
5773
5821
  return {
5774
5822
  decision: finalDecision,
5775
5823
  spawnAttempted: false,
@@ -6192,6 +6240,64 @@ function isKanbanWorkCronDisabled() {
6192
6240
  const v = process.env["AGT_DISABLE_KANBAN_WORK_CRON"];
6193
6241
  return v === "1" || v?.toLowerCase() === "true";
6194
6242
  }
6243
+ function isKanbanHybridEnabled() {
6244
+ const v = process.env["AGT_KANBAN_HYBRID"];
6245
+ return v === "1" || v?.toLowerCase() === "true";
6246
+ }
6247
+ function isKanbanHybridDryRun() {
6248
+ const v = process.env["AGT_KANBAN_HYBRID_DRY_RUN"];
6249
+ return v === "1" || v?.toLowerCase() === "true";
6250
+ }
6251
+ var HYBRID_ACTIONABLE_STATUSES = /* @__PURE__ */ new Set(["todo", "in_progress"]);
6252
+ function hasHybridActionableItems(items) {
6253
+ return items.some((item) => HYBRID_ACTIONABLE_STATUSES.has(item.status));
6254
+ }
6255
+ var lastKanbanInjectAt = /* @__PURE__ */ new Map();
6256
+ var KANBAN_HYBRID_DEBOUNCE_MS = (() => {
6257
+ const raw = process.env["AGT_KANBAN_HYBRID_DEBOUNCE_SECONDS"];
6258
+ const parsed = raw ? parseInt(raw, 10) : NaN;
6259
+ if (Number.isFinite(parsed) && parsed > 0) return Math.max(parsed, 10) * 1e3;
6260
+ return 6e4;
6261
+ })();
6262
+ async function maybeInjectKanbanCheck(codeName, actionableCount) {
6263
+ const lastAt = lastKanbanInjectAt.get(codeName) ?? 0;
6264
+ if (Date.now() - lastAt < KANBAN_HYBRID_DEBOUNCE_MS) {
6265
+ return;
6266
+ }
6267
+ lastKanbanInjectAt.set(codeName, Date.now());
6268
+ const tmuxSession = `agt-${codeName}`;
6269
+ const ready = await isAgentPromptReady(tmuxSession);
6270
+ if (!ready) {
6271
+ log(`[manager-worker] kanban inject skipped \u2014 agent busy ('${codeName}')`);
6272
+ return;
6273
+ }
6274
+ if (isKanbanHybridDryRun()) {
6275
+ log(
6276
+ `[manager-worker] kanban inject DRY-RUN \u2014 would inject for '${codeName}' (${actionableCount} actionable items)`
6277
+ );
6278
+ lastKanbanInjectAt.delete(codeName);
6279
+ return;
6280
+ }
6281
+ const sent = sendToAgent(tmuxSession, KANBAN_CHECK_COMMAND);
6282
+ if (sent) {
6283
+ log(
6284
+ `[manager-worker] Injected kanban check for '${codeName}' (${actionableCount} actionable items)`
6285
+ );
6286
+ } else {
6287
+ log(`[manager-worker] kanban inject failed (tmux send) for '${codeName}'`);
6288
+ }
6289
+ }
6290
+ function warnOnConflictingKanbanModes() {
6291
+ if (!isKanbanHybridEnabled()) return;
6292
+ const cronOff = isKanbanWorkCronDisabled();
6293
+ const loopOff = isKanbanLoopDisabled();
6294
+ if (!cronOff || !loopOff) {
6295
+ const stillOn = !cronOff && !loopOff ? "AGT_DISABLE_KANBAN_WORK_CRON and AGT_DISABLE_KANBAN_LOOP are" : !cronOff ? "AGT_DISABLE_KANBAN_WORK_CRON is" : "AGT_DISABLE_KANBAN_LOOP is";
6296
+ log(
6297
+ `[manager-worker] WARN AGT_KANBAN_HYBRID=1 but ${stillOn} not set \u2014 kanban-work will fire from MULTIPLE sources (doubles token spend). Set both predecessors to 1 for clean hybrid mode.`
6298
+ );
6299
+ }
6300
+ }
6195
6301
  var BOARD_INJECT_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan", "task-update", "hourly-status", "end-of-day-summary", "kanban-work"]);
6196
6302
  var ACTIONABLE_STATUSES = /* @__PURE__ */ new Set(["backlog", "todo", "in_progress"]);
6197
6303
  function hasActionableItems(items) {
@@ -7030,7 +7136,7 @@ async function processClaudePairSessions(agents) {
7030
7136
  killPairSession,
7031
7137
  pairTmuxSession,
7032
7138
  finalizeClaudePairOnboarding
7033
- } = await import("../claude-pair-runtime-4PKORH32.js");
7139
+ } = await import("../claude-pair-runtime-KUWBZW33.js");
7034
7140
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
7035
7141
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
7036
7142
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -7276,7 +7382,8 @@ function generateArtifacts(agent, refreshData, adapter) {
7276
7382
  knowledge: (refreshData.knowledge ?? []).filter((k) => !!k.content),
7277
7383
  knowledgeDelivery: refreshData.agent.knowledge_delivery ?? "both",
7278
7384
  teamMembers: refreshData.team_members ?? void 0,
7279
- people: refreshData.people ?? void 0
7385
+ people: refreshData.people ?? void 0,
7386
+ guardrails: refreshData.guardrails
7280
7387
  };
7281
7388
  const provisionOutput = provision(provisionInput, adapter.id);
7282
7389
  return provisionOutput.artifacts;
@@ -7615,6 +7722,7 @@ function startManager(opts) {
7615
7722
  log(
7616
7723
  `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join4(homedir3(), ".augmented", "manager.log")}`
7617
7724
  );
7725
+ warnOnConflictingKanbanModes();
7618
7726
  deployMcpAssets();
7619
7727
  reapOrphanChannelMcps({ log });
7620
7728
  void ensureHostFrameworkBinaries();
@@ -7785,13 +7893,18 @@ export {
7785
7893
  claudeCodeUpgradeThrottled,
7786
7894
  extractCharterSlackPeers,
7787
7895
  extractCharterTelegramPeers,
7896
+ hasHybridActionableItems,
7788
7897
  hasRevokedResiduals,
7898
+ isKanbanHybridDryRun,
7899
+ isKanbanHybridEnabled,
7789
7900
  isKanbanWorkCronDisabled,
7790
7901
  markAgentForFreshMemorySync,
7902
+ maybeInjectKanbanCheck,
7791
7903
  maybeUpgradeClaudeCode,
7792
7904
  shouldSkipRevokedCleanup,
7793
7905
  stampClaudeCodeUpgradeMarker,
7794
7906
  startManager,
7795
- stopManager
7907
+ stopManager,
7908
+ warnOnConflictingKanbanModes
7796
7909
  };
7797
7910
  //# sourceMappingURL=manager-worker.js.map