@integrity-labs/agt-cli 0.24.8 → 0.24.9
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-53TCAGCM.js → chunk-354Z63L7.js} +38 -26
- package/dist/{chunk-53TCAGCM.js.map → chunk-354Z63L7.js.map} +1 -1
- package/dist/{chunk-XW27YIEU.js → chunk-67PAZ3I4.js} +2 -2
- package/dist/{chunk-TS7W4YNI.js → chunk-HR5T2RQF.js} +8 -2
- package/dist/{chunk-TS7W4YNI.js.map → chunk-HR5T2RQF.js.map} +1 -1
- package/dist/{chunk-3A2PMQM4.js → chunk-S262PDVS.js} +11 -7
- package/dist/chunk-S262PDVS.js.map +1 -0
- package/dist/{claude-pair-runtime-4F53C7RB.js → claude-pair-runtime-6IB35CES.js} +2 -2
- package/dist/{claude-scheduler-XHJS2MZV.js → claude-scheduler-EM24LTGV.js} +2 -2
- package/dist/lib/manager-worker.js +224 -19
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-XJYOPFIP.js → persistent-session-OYO4DTPL.js} +5 -3
- package/dist/{responsiveness-probe-EWZNGMTX.js → responsiveness-probe-SSFKGL7Q.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-3A2PMQM4.js.map +0 -1
- /package/dist/{chunk-XW27YIEU.js.map → chunk-67PAZ3I4.js.map} +0 -0
- /package/dist/{claude-pair-runtime-4F53C7RB.js.map → claude-pair-runtime-6IB35CES.js.map} +0 -0
- /package/dist/{claude-scheduler-XHJS2MZV.js.map → claude-scheduler-EM24LTGV.js.map} +0 -0
- /package/dist/{persistent-session-XJYOPFIP.js.map → persistent-session-OYO4DTPL.js.map} +0 -0
- /package/dist/{responsiveness-probe-EWZNGMTX.js.map → responsiveness-probe-SSFKGL7Q.js.map} +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ApiError,
|
|
2
3
|
SUPERVISOR_RESTART_EXIT_CODE,
|
|
3
4
|
api,
|
|
4
5
|
estimateActiveTasksTokens,
|
|
@@ -12,7 +13,7 @@ import {
|
|
|
12
13
|
provisionOrientHook,
|
|
13
14
|
provisionStopHook,
|
|
14
15
|
requireHost
|
|
15
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-67PAZ3I4.js";
|
|
16
17
|
import {
|
|
17
18
|
findTaskByTemplate,
|
|
18
19
|
getProjectDir as getProjectDir2,
|
|
@@ -20,7 +21,7 @@ import {
|
|
|
20
21
|
loadSchedulerState,
|
|
21
22
|
markTaskFired,
|
|
22
23
|
syncTasksToScheduler
|
|
23
|
-
} from "../chunk-
|
|
24
|
+
} from "../chunk-HR5T2RQF.js";
|
|
24
25
|
import {
|
|
25
26
|
buildAllowedTools,
|
|
26
27
|
ensureKanbanLoopArmed,
|
|
@@ -28,6 +29,7 @@ import {
|
|
|
28
29
|
getProjectDir,
|
|
29
30
|
getSessionState,
|
|
30
31
|
injectMessage,
|
|
32
|
+
injectMessageWithStatus,
|
|
31
33
|
isAgentIdle,
|
|
32
34
|
isAgentPromptReady,
|
|
33
35
|
isKanbanLoopArmedForCurrentSession,
|
|
@@ -48,11 +50,12 @@ import {
|
|
|
48
50
|
stopAllSessionsAndWait,
|
|
49
51
|
stopPersistentSession,
|
|
50
52
|
takeZombieDetection
|
|
51
|
-
} from "../chunk-
|
|
53
|
+
} from "../chunk-S262PDVS.js";
|
|
52
54
|
import {
|
|
53
55
|
KANBAN_CHECK_COMMAND,
|
|
54
56
|
appendDmFooter,
|
|
55
57
|
attributeTranscriptUsageByRun,
|
|
58
|
+
classifyActor,
|
|
56
59
|
classifyOutput,
|
|
57
60
|
extractFrontmatter,
|
|
58
61
|
formatActorId,
|
|
@@ -68,7 +71,7 @@ import {
|
|
|
68
71
|
resolveChannels,
|
|
69
72
|
resolveDmTarget,
|
|
70
73
|
wrapScheduledTaskPrompt
|
|
71
|
-
} from "../chunk-
|
|
74
|
+
} from "../chunk-354Z63L7.js";
|
|
72
75
|
|
|
73
76
|
// src/lib/manager-worker.ts
|
|
74
77
|
import { createHash as createHash3 } from "crypto";
|
|
@@ -2695,6 +2698,7 @@ function stopPersistentSessionAndForgetMcpBaseline(codeName, breakerReason) {
|
|
|
2695
2698
|
runningMcpHashes.delete(codeName);
|
|
2696
2699
|
runningMcpServerKeys.delete(codeName);
|
|
2697
2700
|
closeInjectedRunIfOpen(codeName, "cancelled", `session stopped (${breakerReason ?? "deprovision"})`);
|
|
2701
|
+
closeScheduledRunsForCode(codeName, "cancelled", `session stopped (${breakerReason ?? "deprovision"})`);
|
|
2698
2702
|
if (breakerReason) {
|
|
2699
2703
|
recordRestartForBreaker(codeName, breakerReason);
|
|
2700
2704
|
}
|
|
@@ -2838,7 +2842,7 @@ var cachedFrameworkVersion = null;
|
|
|
2838
2842
|
var lastVersionCheckAt = 0;
|
|
2839
2843
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
2840
2844
|
var lastResponsivenessProbeAt = 0;
|
|
2841
|
-
var agtCliVersion = true ? "0.24.
|
|
2845
|
+
var agtCliVersion = true ? "0.24.9" : "dev";
|
|
2842
2846
|
function resolveBrewPath(execFileSync4) {
|
|
2843
2847
|
try {
|
|
2844
2848
|
const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -3797,7 +3801,7 @@ async function pollCycle() {
|
|
|
3797
3801
|
}
|
|
3798
3802
|
try {
|
|
3799
3803
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
3800
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
3804
|
+
const { collectDiagnostics } = await import("../persistent-session-OYO4DTPL.js");
|
|
3801
3805
|
const diagCodeNames = [...persistentSessionAgents];
|
|
3802
3806
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
|
|
3803
3807
|
let tailscaleHostname;
|
|
@@ -3848,7 +3852,7 @@ async function pollCycle() {
|
|
|
3848
3852
|
const {
|
|
3849
3853
|
collectResponsivenessProbes,
|
|
3850
3854
|
getResponsivenessIntervalMs
|
|
3851
|
-
} = await import("../responsiveness-probe-
|
|
3855
|
+
} = await import("../responsiveness-probe-SSFKGL7Q.js");
|
|
3852
3856
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
3853
3857
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
3854
3858
|
const probeCodeNames = [...persistentSessionAgents];
|
|
@@ -5106,7 +5110,9 @@ async function processAgent(agent, agentStates) {
|
|
|
5106
5110
|
}
|
|
5107
5111
|
const agentFw = agentFrameworkCache.get(agent.code_name) ?? "openclaw";
|
|
5108
5112
|
const sessionMode = refreshData.agent.session_mode ?? "oneshot";
|
|
5109
|
-
|
|
5113
|
+
const wantsHybridInject = isKanbanHybridEnabled();
|
|
5114
|
+
const wantsScheduledReconcile = isScheduledViaKanbanEnabled();
|
|
5115
|
+
if ((wantsHybridInject || wantsScheduledReconcile) && agentFw === "claude-code" && sessionMode === "persistent") {
|
|
5110
5116
|
let hybridBoard = hasBoardTemplates ? boardItems : void 0;
|
|
5111
5117
|
if (!hybridBoard) {
|
|
5112
5118
|
try {
|
|
@@ -5120,13 +5126,14 @@ async function processAgent(agent, agentStates) {
|
|
|
5120
5126
|
hybridBoard = kanbanBoardCache.get(agent.code_name) ?? [];
|
|
5121
5127
|
}
|
|
5122
5128
|
}
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5129
|
+
void reconcileScheduledRuns(agent.code_name, agent.agent_id, hybridBoard);
|
|
5130
|
+
if (wantsHybridInject) {
|
|
5131
|
+
if (hasHybridActionableItems(hybridBoard)) {
|
|
5132
|
+
const actionableCount = hybridBoard.filter(isHybridActionable).length;
|
|
5133
|
+
void maybeInjectKanbanCheck(agent.code_name, agent.agent_id, actionableCount);
|
|
5134
|
+
} else {
|
|
5135
|
+
closeInjectedRunIfOpen(agent.code_name, "completed", "kanban board drained");
|
|
5136
|
+
}
|
|
5130
5137
|
}
|
|
5131
5138
|
}
|
|
5132
5139
|
if (agentFw === "claude-code" && sessionMode === "persistent") {
|
|
@@ -5757,6 +5764,157 @@ async function fetchPriorScheduledRuns(agentId, taskId) {
|
|
|
5757
5764
|
return [];
|
|
5758
5765
|
}
|
|
5759
5766
|
}
|
|
5767
|
+
function isScheduledViaKanbanEnabled() {
|
|
5768
|
+
const v = process.env["AGT_SCHEDULED_VIA_KANBAN"];
|
|
5769
|
+
return v === "1" || v?.toLowerCase() === "true";
|
|
5770
|
+
}
|
|
5771
|
+
var scheduledRunsByCode = /* @__PURE__ */ new Map();
|
|
5772
|
+
var claimedScheduledCards = /* @__PURE__ */ new Set();
|
|
5773
|
+
var completedScheduledCards = /* @__PURE__ */ new Set();
|
|
5774
|
+
function claimScheduledCardDelivery(cardId) {
|
|
5775
|
+
if (claimedScheduledCards.has(cardId)) return false;
|
|
5776
|
+
claimedScheduledCards.add(cardId);
|
|
5777
|
+
return true;
|
|
5778
|
+
}
|
|
5779
|
+
function releaseScheduledCardDelivery(cardId) {
|
|
5780
|
+
claimedScheduledCards.delete(cardId);
|
|
5781
|
+
}
|
|
5782
|
+
function markScheduledCardDeliveryComplete(cardId) {
|
|
5783
|
+
completedScheduledCards.add(cardId);
|
|
5784
|
+
}
|
|
5785
|
+
function __resetScheduledDeliveryDedupeForTest() {
|
|
5786
|
+
claimedScheduledCards.clear();
|
|
5787
|
+
completedScheduledCards.clear();
|
|
5788
|
+
}
|
|
5789
|
+
function trackScheduledRun(codeName, cardId, runId) {
|
|
5790
|
+
let m = scheduledRunsByCode.get(codeName);
|
|
5791
|
+
if (!m) {
|
|
5792
|
+
m = /* @__PURE__ */ new Map();
|
|
5793
|
+
scheduledRunsByCode.set(codeName, m);
|
|
5794
|
+
}
|
|
5795
|
+
m.set(cardId, runId);
|
|
5796
|
+
}
|
|
5797
|
+
function isScheduledCardTracked(cardId) {
|
|
5798
|
+
for (const m of scheduledRunsByCode.values()) {
|
|
5799
|
+
if (m.has(cardId)) return true;
|
|
5800
|
+
}
|
|
5801
|
+
return false;
|
|
5802
|
+
}
|
|
5803
|
+
function closeScheduledRunsForCode(codeName, outcome, reason) {
|
|
5804
|
+
const m = scheduledRunsByCode.get(codeName);
|
|
5805
|
+
if (!m || m.size === 0) return;
|
|
5806
|
+
scheduledRunsByCode.delete(codeName);
|
|
5807
|
+
for (const runId of m.values()) {
|
|
5808
|
+
void finishRun(runId, outcome, { outcomeMessage: reason });
|
|
5809
|
+
}
|
|
5810
|
+
}
|
|
5811
|
+
async function deliverScheduledCardResult(codeName, agentId, cardId) {
|
|
5812
|
+
if (!claimScheduledCardDelivery(cardId)) {
|
|
5813
|
+
return completedScheduledCards.has(cardId) ? "terminal" : "in_flight";
|
|
5814
|
+
}
|
|
5815
|
+
let card;
|
|
5816
|
+
try {
|
|
5817
|
+
const resp = await api.post("/host/kanban-item", {
|
|
5818
|
+
agent_id: agentId,
|
|
5819
|
+
item_id: cardId
|
|
5820
|
+
});
|
|
5821
|
+
card = resp.item;
|
|
5822
|
+
} catch (err) {
|
|
5823
|
+
if (err instanceof ApiError && err.status >= 400 && err.status < 500) {
|
|
5824
|
+
log(`[scheduled-kanban] delivery: card ${cardId} on '${codeName}' fetch returned ${err.status} (${err.message}) \u2014 treating as terminal, not retrying`);
|
|
5825
|
+
markScheduledCardDeliveryComplete(cardId);
|
|
5826
|
+
return "terminal";
|
|
5827
|
+
}
|
|
5828
|
+
releaseScheduledCardDelivery(cardId);
|
|
5829
|
+
log(`[scheduled-kanban] delivery fetch failed for card ${cardId} on '${codeName}': ${err.message} \u2014 will retry`);
|
|
5830
|
+
return "retry";
|
|
5831
|
+
}
|
|
5832
|
+
if (!card || card.status !== "done" || card.source_type !== "scheduled_task" || !card.source_ref) {
|
|
5833
|
+
markScheduledCardDeliveryComplete(cardId);
|
|
5834
|
+
return "terminal";
|
|
5835
|
+
}
|
|
5836
|
+
const state5 = claudeSchedulerStates.get(codeName) ?? loadSchedulerState(codeName);
|
|
5837
|
+
const task = state5.tasks[card.source_ref];
|
|
5838
|
+
if (!task) {
|
|
5839
|
+
log(`[scheduled-kanban] delivery: no scheduler task for source_ref=${card.source_ref} on '${codeName}' \u2014 skipping`);
|
|
5840
|
+
markScheduledCardDeliveryComplete(cardId);
|
|
5841
|
+
return "terminal";
|
|
5842
|
+
}
|
|
5843
|
+
if (!isPlainScheduledTemplate(task.templateId)) {
|
|
5844
|
+
log(`[scheduled-kanban] delivery: card ${cardId} template '${task.templateId}' on '${codeName}' is not a plain scheduled template \u2014 skipping manager delivery`);
|
|
5845
|
+
markScheduledCardDeliveryComplete(cardId);
|
|
5846
|
+
return "terminal";
|
|
5847
|
+
}
|
|
5848
|
+
await processClaudeTaskResult(codeName, agentId, task.templateId, card.result ?? "", {
|
|
5849
|
+
mode: task.deliveryMode,
|
|
5850
|
+
channel: task.deliveryChannel,
|
|
5851
|
+
to: task.deliveryTo,
|
|
5852
|
+
taskId: task.taskId
|
|
5853
|
+
});
|
|
5854
|
+
markScheduledCardDeliveryComplete(cardId);
|
|
5855
|
+
log(`[scheduled-kanban] Delivered result from card ${cardId} (task '${task.name}') for '${codeName}'`);
|
|
5856
|
+
return "delivered";
|
|
5857
|
+
}
|
|
5858
|
+
async function reconcileScheduledRuns(codeName, agentId, board) {
|
|
5859
|
+
const m = scheduledRunsByCode.get(codeName);
|
|
5860
|
+
if (!m || m.size === 0) return;
|
|
5861
|
+
const byId = new Map(board.map((i) => [i.id, i]));
|
|
5862
|
+
for (const [cardId, runId] of [...m.entries()]) {
|
|
5863
|
+
const card = byId.get(cardId);
|
|
5864
|
+
if (!card) continue;
|
|
5865
|
+
if (card.status === "done") {
|
|
5866
|
+
const result = await deliverScheduledCardResult(codeName, agentId, cardId);
|
|
5867
|
+
if (result === "retry" || result === "in_flight") continue;
|
|
5868
|
+
m.delete(cardId);
|
|
5869
|
+
void finishRun(runId, "completed", { outcomeMessage: "scheduled-task card done" });
|
|
5870
|
+
} else if (card.status === "failed") {
|
|
5871
|
+
m.delete(cardId);
|
|
5872
|
+
void finishRun(runId, "failed", { outcomeMessage: "scheduled-task card failed" });
|
|
5873
|
+
}
|
|
5874
|
+
}
|
|
5875
|
+
if (m.size === 0) scheduledRunsByCode.delete(codeName);
|
|
5876
|
+
}
|
|
5877
|
+
async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt) {
|
|
5878
|
+
const { run_id, kanban_item_id } = await startRun({
|
|
5879
|
+
agent_id: agentId,
|
|
5880
|
+
source_type: "scheduled_task",
|
|
5881
|
+
source_ref: task.taskId,
|
|
5882
|
+
metadata: { template_id: task.templateId, name: task.name, via: "kanban-inject" },
|
|
5883
|
+
materialize_kanban: {
|
|
5884
|
+
title: task.name,
|
|
5885
|
+
description: prompt,
|
|
5886
|
+
priority: 2,
|
|
5887
|
+
initial_status: "todo"
|
|
5888
|
+
}
|
|
5889
|
+
});
|
|
5890
|
+
if (!run_id || !kanban_item_id) {
|
|
5891
|
+
log(`[scheduled-kanban] materialise incomplete for task '${task.name}' on '${codeName}' (run_id=${run_id ? "ok" : "null"}, card=${kanban_item_id ? "ok" : "null"}) \u2014 falling back to claude -p`);
|
|
5892
|
+
if (run_id) void finishRun(run_id, "failed", { outcomeMessage: "kanban materialise incomplete", completeKanbanItemId: kanban_item_id });
|
|
5893
|
+
return false;
|
|
5894
|
+
}
|
|
5895
|
+
const nudge = `You have a new scheduled task on your kanban board: id=${kanban_item_id} title=${JSON.stringify(task.name)}. Call kanban_move("${kanban_item_id}", "in_progress"), do the work described on the card, then write the finished result onto the card and mark it done. Do NOT send, post, or message the result to anyone yourself \u2014 recording it on the card is enough; delivery to the recipient is handled for you.
|
|
5896
|
+
` + formatRunMarker(run_id);
|
|
5897
|
+
let injectStatus;
|
|
5898
|
+
try {
|
|
5899
|
+
injectStatus = await injectMessageWithStatus(codeName, "task", nudge, { task_name: "scheduled-task" }, log);
|
|
5900
|
+
} catch (err) {
|
|
5901
|
+
log(`[scheduled-kanban] nudge injection threw for task '${task.name}' on '${codeName}': ${err.message} \u2014 closing card + falling back to claude -p`);
|
|
5902
|
+
void finishRun(run_id, "failed", { outcomeMessage: "scheduled-task nudge delivery threw", completeKanbanItemId: kanban_item_id });
|
|
5903
|
+
return false;
|
|
5904
|
+
}
|
|
5905
|
+
const { delivered, fallbackUsed } = injectStatus;
|
|
5906
|
+
if (!delivered && !fallbackUsed) {
|
|
5907
|
+
log(`[scheduled-kanban] nudge delivery failed for task '${task.name}' on '${codeName}' \u2014 closing card + falling back to claude -p`);
|
|
5908
|
+
void finishRun(run_id, "failed", { outcomeMessage: "scheduled-task nudge delivery failed", completeKanbanItemId: kanban_item_id });
|
|
5909
|
+
return false;
|
|
5910
|
+
}
|
|
5911
|
+
if (!delivered && fallbackUsed) {
|
|
5912
|
+
log(`[scheduled-kanban] nudge sent via send-keys (unverified) for task '${task.name}' on '${codeName}' \u2014 proceeding without oneshot fallback`);
|
|
5913
|
+
}
|
|
5914
|
+
trackScheduledRun(codeName, kanban_item_id, run_id);
|
|
5915
|
+
log(`[scheduled-kanban] Routed task '${task.name}' for '${codeName}' via todo card ${kanban_item_id} run_id=${run_id}`);
|
|
5916
|
+
return true;
|
|
5917
|
+
}
|
|
5760
5918
|
async function executeAndProcessClaudeTask(codeName, agentId, task, prompt) {
|
|
5761
5919
|
const projectDir = getProjectDir2(codeName);
|
|
5762
5920
|
const mcpConfigPath = join6(projectDir, ".mcp.json");
|
|
@@ -6264,6 +6422,31 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash3("sha256").
|
|
|
6264
6422
|
}
|
|
6265
6423
|
inFlightClaudeTasks.add(task.taskId);
|
|
6266
6424
|
claudeTaskConcurrency.set(codeName, (claudeTaskConcurrency.get(codeName) ?? 0) + 1);
|
|
6425
|
+
if (isScheduledViaKanbanEnabled() && isPlainScheduledTemplate(task.templateId)) {
|
|
6426
|
+
let routed = false;
|
|
6427
|
+
try {
|
|
6428
|
+
routed = await routeScheduledTaskViaKanban(codeName, agent.agent_id, task, prompt);
|
|
6429
|
+
} catch (err) {
|
|
6430
|
+
log(`[scheduled-kanban] route threw for '${task.name}' on '${codeName}': ${err.message}`);
|
|
6431
|
+
routed = false;
|
|
6432
|
+
}
|
|
6433
|
+
if (routed) {
|
|
6434
|
+
try {
|
|
6435
|
+
const updated = markTaskFired(codeName, task.taskId, "ok");
|
|
6436
|
+
claudeSchedulerStates.set(codeName, updated);
|
|
6437
|
+
} catch (err) {
|
|
6438
|
+
log(`[scheduled-kanban] markTaskFired failed for '${task.name}' on '${codeName}': ${err.message}`);
|
|
6439
|
+
}
|
|
6440
|
+
if (task.scheduleKind === "at") {
|
|
6441
|
+
api.post("/host/schedules/disable", { agent_id: agent.agent_id, task_id: task.taskId }).catch(
|
|
6442
|
+
(err) => log(`[scheduled-kanban] Failed to disable one-off task '${task.name}': ${err.message}`)
|
|
6443
|
+
);
|
|
6444
|
+
}
|
|
6445
|
+
inFlightClaudeTasks.delete(task.taskId);
|
|
6446
|
+
claudeTaskConcurrency.set(codeName, Math.max(0, (claudeTaskConcurrency.get(codeName) ?? 1) - 1));
|
|
6447
|
+
break;
|
|
6448
|
+
}
|
|
6449
|
+
}
|
|
6267
6450
|
log(`[persistent-session] Firing task '${task.name}' for '${codeName}' via claude -p`);
|
|
6268
6451
|
executeAndProcessClaudeTask(codeName, agent.agent_id, task, prompt).catch(() => {
|
|
6269
6452
|
}).finally(() => {
|
|
@@ -6447,6 +6630,7 @@ function ensureRealtimeKanbanStarted(agentStates) {
|
|
|
6447
6630
|
token: exchange.token,
|
|
6448
6631
|
agentIds: activeAgentIds,
|
|
6449
6632
|
onTodayItem: (item) => {
|
|
6633
|
+
if (item.source_type === "scheduled_task") return;
|
|
6450
6634
|
const agent = agentStates.find((a) => a.agentId === item.agent_id);
|
|
6451
6635
|
if (!agent) return;
|
|
6452
6636
|
const agentFw = agentFrameworkCache.get(agent.codeName) ?? "openclaw";
|
|
@@ -6474,6 +6658,9 @@ function ensureRealtimeKanbanStarted(agentStates) {
|
|
|
6474
6658
|
log(
|
|
6475
6659
|
`[realtime] Kanban completion forwarded for '${codeName}': item=${event.item_id} status=${event.status} actor=${event.last_actor_id ?? "unknown"}`
|
|
6476
6660
|
);
|
|
6661
|
+
if (event.status === "done" && (isScheduledViaKanbanEnabled() || isKanbanHybridEnabled()) && classifyActor(event.last_actor_id, event.agent_id) === "user" && isScheduledCardTracked(event.item_id)) {
|
|
6662
|
+
void deliverScheduledCardResult(codeName, event.agent_id, event.item_id);
|
|
6663
|
+
}
|
|
6477
6664
|
},
|
|
6478
6665
|
log
|
|
6479
6666
|
});
|
|
@@ -6598,7 +6785,7 @@ ${escapeXml(msg.content)}
|
|
|
6598
6785
|
try {
|
|
6599
6786
|
let reply;
|
|
6600
6787
|
if (fw === "claude-code") {
|
|
6601
|
-
const { getProjectDir: ccProjectDir } = await import("../claude-scheduler-
|
|
6788
|
+
const { getProjectDir: ccProjectDir } = await import("../claude-scheduler-EM24LTGV.js");
|
|
6602
6789
|
const projDir = ccProjectDir(agent.codeName);
|
|
6603
6790
|
const mcpConfigPath = join6(projDir, ".mcp.json");
|
|
6604
6791
|
const serverNames = [];
|
|
@@ -6692,6 +6879,9 @@ var STANDUP_TEMPLATES = /* @__PURE__ */ new Set(["daily-standup", "end-of-day-su
|
|
|
6692
6879
|
var TASK_UPDATE_TEMPLATES = /* @__PURE__ */ new Set(["hourly-status", "task-update"]);
|
|
6693
6880
|
var PLAN_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan"]);
|
|
6694
6881
|
var KANBAN_WORK_TEMPLATES = /* @__PURE__ */ new Set(["kanban-work"]);
|
|
6882
|
+
function isPlainScheduledTemplate(templateId) {
|
|
6883
|
+
return !STANDUP_TEMPLATES.has(templateId) && !TASK_UPDATE_TEMPLATES.has(templateId) && !PLAN_TEMPLATES.has(templateId) && !KANBAN_WORK_TEMPLATES.has(templateId);
|
|
6884
|
+
}
|
|
6695
6885
|
function isKanbanWorkCronDisabled() {
|
|
6696
6886
|
const v = process.env["AGT_DISABLE_KANBAN_WORK_CRON"];
|
|
6697
6887
|
return v === "1" || v?.toLowerCase() === "true";
|
|
@@ -6705,8 +6895,11 @@ function isKanbanHybridDryRun() {
|
|
|
6705
6895
|
return v === "1" || v?.toLowerCase() === "true";
|
|
6706
6896
|
}
|
|
6707
6897
|
var HYBRID_ACTIONABLE_STATUSES = /* @__PURE__ */ new Set(["todo", "in_progress"]);
|
|
6898
|
+
function isHybridActionable(item) {
|
|
6899
|
+
return HYBRID_ACTIONABLE_STATUSES.has(item.status) && item.source_type !== "scheduled_task";
|
|
6900
|
+
}
|
|
6708
6901
|
function hasHybridActionableItems(items) {
|
|
6709
|
-
return items.some(
|
|
6902
|
+
return items.some(isHybridActionable);
|
|
6710
6903
|
}
|
|
6711
6904
|
var lastKanbanInjectAt = /* @__PURE__ */ new Map();
|
|
6712
6905
|
var openInjectedRunByCode = /* @__PURE__ */ new Map();
|
|
@@ -6782,7 +6975,7 @@ function warnOnConflictingKanbanModes() {
|
|
|
6782
6975
|
}
|
|
6783
6976
|
}
|
|
6784
6977
|
var BOARD_INJECT_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan", "task-update", "hourly-status", "end-of-day-summary", "kanban-work"]);
|
|
6785
|
-
var ACTIONABLE_STATUSES = /* @__PURE__ */ new Set(["
|
|
6978
|
+
var ACTIONABLE_STATUSES = /* @__PURE__ */ new Set(["todo", "in_progress"]);
|
|
6786
6979
|
function hasActionableItems(items) {
|
|
6787
6980
|
return items.some((item) => ACTIONABLE_STATUSES.has(item.status));
|
|
6788
6981
|
}
|
|
@@ -7619,7 +7812,7 @@ async function processClaudePairSessions(agents) {
|
|
|
7619
7812
|
killPairSession,
|
|
7620
7813
|
pairTmuxSession,
|
|
7621
7814
|
finalizeClaudePairOnboarding
|
|
7622
|
-
} = await import("../claude-pair-runtime-
|
|
7815
|
+
} = await import("../claude-pair-runtime-6IB35CES.js");
|
|
7623
7816
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
7624
7817
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
7625
7818
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -8188,6 +8381,9 @@ async function stopPolling(opts = {}) {
|
|
|
8188
8381
|
stopCaffeinate();
|
|
8189
8382
|
stopRealtimeChat();
|
|
8190
8383
|
stopGatewayPool();
|
|
8384
|
+
for (const codeName of [...scheduledRunsByCode.keys()]) {
|
|
8385
|
+
closeScheduledRunsForCode(codeName, "cancelled", "manager shutdown");
|
|
8386
|
+
}
|
|
8191
8387
|
log("Killing tmux sessions...");
|
|
8192
8388
|
await killAllAgtTmuxSessions();
|
|
8193
8389
|
log("Stopping persistent sessions...");
|
|
@@ -8385,19 +8581,28 @@ process.on("disconnect", () => {
|
|
|
8385
8581
|
});
|
|
8386
8582
|
export {
|
|
8387
8583
|
ChildProcessError,
|
|
8584
|
+
__resetScheduledDeliveryDedupeForTest,
|
|
8388
8585
|
applyRestartAcks,
|
|
8389
8586
|
claudeCodeUpgradeMarkerPath,
|
|
8390
8587
|
claudeCodeUpgradeThrottled,
|
|
8588
|
+
deliverScheduledCardResult,
|
|
8391
8589
|
extractCharterSlackPeers,
|
|
8392
8590
|
extractCharterTelegramPeers,
|
|
8591
|
+
hasActionableItems,
|
|
8393
8592
|
hasHybridActionableItems,
|
|
8394
8593
|
hasRevokedResiduals,
|
|
8594
|
+
isHybridActionable,
|
|
8395
8595
|
isKanbanHybridDryRun,
|
|
8396
8596
|
isKanbanHybridEnabled,
|
|
8397
8597
|
isKanbanWorkCronDisabled,
|
|
8598
|
+
isPlainScheduledTemplate,
|
|
8599
|
+
isScheduledCardTracked,
|
|
8600
|
+
isScheduledViaKanbanEnabled,
|
|
8398
8601
|
markAgentForFreshMemorySync,
|
|
8399
8602
|
maybeInjectKanbanCheck,
|
|
8400
8603
|
maybeUpgradeClaudeCode,
|
|
8604
|
+
reconcileScheduledRuns,
|
|
8605
|
+
routeScheduledTaskViaKanban,
|
|
8401
8606
|
shouldSkipRevokedCleanup,
|
|
8402
8607
|
stampClaudeCodeUpgradeMarker,
|
|
8403
8608
|
startManager,
|