@integrity-labs/agt-cli 0.25.2 → 0.26.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.
- package/dist/bin/agt.js +4 -4
- package/dist/{chunk-VWOXS4YP.js → chunk-7NDNTSHD.js} +4 -8
- package/dist/chunk-7NDNTSHD.js.map +1 -0
- package/dist/{chunk-M2RBM3M5.js → chunk-QJJAGFJJ.js} +5 -66
- package/dist/chunk-QJJAGFJJ.js.map +1 -0
- package/dist/{chunk-U4DAVDAZ.js → chunk-UTPOHAX7.js} +2 -2
- package/dist/{claude-pair-runtime-Q5CZLM2R.js → claude-pair-runtime-A35NZYDN.js} +2 -2
- package/dist/lib/manager-worker.js +50 -111
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-MUJA45LT.js → persistent-session-E5EZ32CI.js} +3 -9
- package/dist/{responsiveness-probe-2TBRHC5T.js → responsiveness-probe-MLUVAXJH.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-M2RBM3M5.js.map +0 -1
- package/dist/chunk-VWOXS4YP.js.map +0 -1
- /package/dist/{chunk-U4DAVDAZ.js.map → chunk-UTPOHAX7.js.map} +0 -0
- /package/dist/{claude-pair-runtime-Q5CZLM2R.js.map → claude-pair-runtime-A35NZYDN.js.map} +0 -0
- /package/dist/{persistent-session-MUJA45LT.js.map → persistent-session-E5EZ32CI.js.map} +0 -0
- /package/dist/{responsiveness-probe-2TBRHC5T.js.map → responsiveness-probe-MLUVAXJH.js.map} +0 -0
|
@@ -13,9 +13,8 @@ import {
|
|
|
13
13
|
provisionOrientHook,
|
|
14
14
|
provisionStopHook,
|
|
15
15
|
requireHost
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-UTPOHAX7.js";
|
|
17
17
|
import {
|
|
18
|
-
findTaskByTemplate,
|
|
19
18
|
getProjectDir as getProjectDir2,
|
|
20
19
|
getReadyTasks,
|
|
21
20
|
loadSchedulerState,
|
|
@@ -24,7 +23,6 @@ import {
|
|
|
24
23
|
} from "../chunk-HR5T2RQF.js";
|
|
25
24
|
import {
|
|
26
25
|
buildAllowedTools,
|
|
27
|
-
ensureKanbanLoopArmed,
|
|
28
26
|
getLastFailureContext,
|
|
29
27
|
getProjectDir,
|
|
30
28
|
getSessionState,
|
|
@@ -32,8 +30,6 @@ import {
|
|
|
32
30
|
injectMessageWithStatus,
|
|
33
31
|
isAgentIdle,
|
|
34
32
|
isAgentPromptReady,
|
|
35
|
-
isKanbanLoopArmedForCurrentSession,
|
|
36
|
-
isKanbanLoopDisabled,
|
|
37
33
|
isSessionHealthy,
|
|
38
34
|
isStaleForToday,
|
|
39
35
|
parsePsRows,
|
|
@@ -50,7 +46,7 @@ import {
|
|
|
50
46
|
stopAllSessionsAndWait,
|
|
51
47
|
stopPersistentSession,
|
|
52
48
|
takeZombieDetection
|
|
53
|
-
} from "../chunk-
|
|
49
|
+
} from "../chunk-QJJAGFJJ.js";
|
|
54
50
|
import {
|
|
55
51
|
KANBAN_CHECK_COMMAND,
|
|
56
52
|
appendDmFooter,
|
|
@@ -73,7 +69,7 @@ import {
|
|
|
73
69
|
resolveConnectivityProbe,
|
|
74
70
|
resolveDmTarget,
|
|
75
71
|
wrapScheduledTaskPrompt
|
|
76
|
-
} from "../chunk-
|
|
72
|
+
} from "../chunk-7NDNTSHD.js";
|
|
77
73
|
|
|
78
74
|
// src/lib/manager-worker.ts
|
|
79
75
|
import { createHash as createHash3 } from "crypto";
|
|
@@ -2966,7 +2962,14 @@ async function runAgentConnectivityProbes(agent, integrations, projectDir) {
|
|
|
2966
2962
|
auth_type: i.auth_type,
|
|
2967
2963
|
source_type: i.source_type ?? null,
|
|
2968
2964
|
credentials: i.credentials,
|
|
2969
|
-
last_connectivity_check_at: i.last_connectivity_check_at ?? null
|
|
2965
|
+
last_connectivity_check_at: i.last_connectivity_check_at ?? null,
|
|
2966
|
+
// ENG-5665: for managed (Composio) + mcp_server toolkits the connectivity
|
|
2967
|
+
// probe is an MCP `tools/list` against the agent's wired server. Derive the
|
|
2968
|
+
// .mcp.json server key the same way the managed-toolkit writer does
|
|
2969
|
+
// (definition_id === toolkit_id, sanitised: non-alnum → '_', lowercased —
|
|
2970
|
+
// e.g. 'composio_outlook'). The executor looks this up in .mcp.json; an
|
|
2971
|
+
// unresolvable key degrades to transient_error, never a false 'down'.
|
|
2972
|
+
mcp_server_key: i.source_type === "managed" || i.source_type === "mcp_server" ? i.definition_id.replace(/[^a-z0-9]/gi, "_").toLowerCase() : void 0
|
|
2970
2973
|
})),
|
|
2971
2974
|
{ probeDeps, intervalMs: intervalSec * 1e3 }
|
|
2972
2975
|
);
|
|
@@ -3130,7 +3133,7 @@ var cachedFrameworkVersion = null;
|
|
|
3130
3133
|
var lastVersionCheckAt = 0;
|
|
3131
3134
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
3132
3135
|
var lastResponsivenessProbeAt = 0;
|
|
3133
|
-
var agtCliVersion = true ? "0.
|
|
3136
|
+
var agtCliVersion = true ? "0.26.1" : "dev";
|
|
3134
3137
|
function resolveBrewPath(execFileSync4) {
|
|
3135
3138
|
try {
|
|
3136
3139
|
const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -4089,7 +4092,7 @@ async function pollCycle() {
|
|
|
4089
4092
|
}
|
|
4090
4093
|
try {
|
|
4091
4094
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
4092
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
4095
|
+
const { collectDiagnostics } = await import("../persistent-session-E5EZ32CI.js");
|
|
4093
4096
|
const diagCodeNames = [...persistentSessionAgents];
|
|
4094
4097
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
|
|
4095
4098
|
let tailscaleHostname;
|
|
@@ -4147,7 +4150,7 @@ async function pollCycle() {
|
|
|
4147
4150
|
const {
|
|
4148
4151
|
collectResponsivenessProbes,
|
|
4149
4152
|
getResponsivenessIntervalMs
|
|
4150
|
-
} = await import("../responsiveness-probe-
|
|
4153
|
+
} = await import("../responsiveness-probe-MLUVAXJH.js");
|
|
4151
4154
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
4152
4155
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
4153
4156
|
const probeCodeNames = [...persistentSessionAgents];
|
|
@@ -5221,12 +5224,15 @@ async function processAgent(agent, agentStates) {
|
|
|
5221
5224
|
}
|
|
5222
5225
|
let tasks = refreshData.scheduled_tasks ?? [];
|
|
5223
5226
|
const existingTemplateIds = new Set(tasks.map((t) => t.template_id));
|
|
5227
|
+
const kanbanWorkRetired = (agentFrameworkCache.get(agent.code_name) ?? "openclaw") === "claude-code" && agentSessionMode === "persistent";
|
|
5224
5228
|
try {
|
|
5225
5229
|
const defaultsData = await api.post("/host/resolve-default-schedules", { agent_id: agent.agent_id });
|
|
5226
|
-
const
|
|
5230
|
+
const allSchedules = (defaultsData.schedules ?? []).filter(
|
|
5231
|
+
(s) => !(kanbanWorkRetired && s.template_id === "kanban-work")
|
|
5232
|
+
);
|
|
5233
|
+
const missing = allSchedules.filter(
|
|
5227
5234
|
(s) => !existingTemplateIds.has(s.template_id)
|
|
5228
5235
|
);
|
|
5229
|
-
const allSchedules = defaultsData.schedules ?? [];
|
|
5230
5236
|
if (allSchedules.length > 0) {
|
|
5231
5237
|
await api.post("/host/ensure-default-schedules", {
|
|
5232
5238
|
agent_id: agent.agent_id,
|
|
@@ -5243,6 +5249,9 @@ async function processAgent(agent, agentStates) {
|
|
|
5243
5249
|
} catch (err) {
|
|
5244
5250
|
log(`Default schedule provisioning failed for '${agent.code_name}': ${err.message}`);
|
|
5245
5251
|
}
|
|
5252
|
+
if (kanbanWorkRetired) {
|
|
5253
|
+
tasks = tasks.filter((t) => t.template_id !== "kanban-work");
|
|
5254
|
+
}
|
|
5246
5255
|
if (agent.status === "active") {
|
|
5247
5256
|
if (frameworkAdapter.installPlugin) {
|
|
5248
5257
|
try {
|
|
@@ -5486,10 +5495,6 @@ async function processAgent(agent, agentStates) {
|
|
|
5486
5495
|
sessionHealthy: psResult.sessionHealthyAfter,
|
|
5487
5496
|
spawnAttempted: psResult.spawnAttempted
|
|
5488
5497
|
});
|
|
5489
|
-
if (psResult.sessionHealthyAfter) {
|
|
5490
|
-
ensureKanbanLoopArmed(agent.code_name, log).catch(() => {
|
|
5491
|
-
});
|
|
5492
|
-
}
|
|
5493
5498
|
if (stuck.shouldWarn) {
|
|
5494
5499
|
log(
|
|
5495
5500
|
`[persistent-session-stuck] WARN: agent=${agent.code_name} unhealthy with no spawn attempt for ${stuck.consecutiveTicks} consecutive ticks (last_decision=${psResult.decision}) \u2014 manager-worker may need restart, or upstream guard is mis-firing (see ENG-5116)`
|
|
@@ -5688,8 +5693,6 @@ async function processAgent(agent, agentStates) {
|
|
|
5688
5693
|
} else {
|
|
5689
5694
|
log(`[persistent-session] Work trigger skipped for '${agent.code_name}' \u2014 session not yet healthy`);
|
|
5690
5695
|
}
|
|
5691
|
-
} else {
|
|
5692
|
-
fireClaudeWorkTrigger(agent.code_name, agent.agent_id, boardItems);
|
|
5693
5696
|
}
|
|
5694
5697
|
}
|
|
5695
5698
|
}
|
|
@@ -5719,12 +5722,7 @@ async function processAgent(agent, agentStates) {
|
|
|
5719
5722
|
for (const item of newlyDone) {
|
|
5720
5723
|
log(`Newly done: '${item.title}' notify_channel=${item.notify_channel ?? "none"} notify_to=${item.notify_to ?? "none"}`);
|
|
5721
5724
|
if (item.notify_channel && item.notify_to) {
|
|
5722
|
-
const
|
|
5723
|
-
const resultLine = item.result ? `
|
|
5724
|
-
${isFailed ? "Reason" : "Result"}: ${item.result}` : "";
|
|
5725
|
-
const emoji = isFailed ? "\u274C" : "\u2705";
|
|
5726
|
-
const message = `${emoji} ${isFailed ? "Task Failed" : "Task Complete"} \u2014 ${displayName}
|
|
5727
|
-
${item.title}${resultLine}`;
|
|
5725
|
+
const message = await buildDoneCardNotification(agentId, agent.code_name, displayName, item);
|
|
5728
5726
|
sendTaskNotification(agent.code_name, item.notify_channel, item.notify_to, message).catch((err) => {
|
|
5729
5727
|
log(`sendTaskNotification failed for '${agent.code_name}': ${err.message}`);
|
|
5730
5728
|
});
|
|
@@ -6006,8 +6004,7 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
|
|
|
6006
6004
|
if (ready.length === 0) return;
|
|
6007
6005
|
for (const task of ready) {
|
|
6008
6006
|
if ((claudeTaskConcurrency.get(codeName) ?? 0) >= MAX_CLAUDE_CONCURRENCY) break;
|
|
6009
|
-
if (KANBAN_WORK_TEMPLATES.has(task.templateId)
|
|
6010
|
-
log(`[claude-scheduler] Skipping '${task.name}' for '${codeName}' \u2014 board is empty`);
|
|
6007
|
+
if (KANBAN_WORK_TEMPLATES.has(task.templateId)) {
|
|
6011
6008
|
const updated = markTaskFired(codeName, task.taskId, "ok");
|
|
6012
6009
|
claudeSchedulerStates.set(codeName, updated);
|
|
6013
6010
|
continue;
|
|
@@ -6018,20 +6015,6 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
|
|
|
6018
6015
|
const boardPrefix = formatBoardForPrompt(boardItems, template);
|
|
6019
6016
|
prompt = boardPrefix + prompt;
|
|
6020
6017
|
}
|
|
6021
|
-
if (KANBAN_WORK_TEMPLATES.has(task.templateId)) {
|
|
6022
|
-
const todayItem = boardItems.find((b) => b.status === "todo");
|
|
6023
|
-
if (todayItem) {
|
|
6024
|
-
try {
|
|
6025
|
-
await api.post("/host/kanban", {
|
|
6026
|
-
agent_id: agent.agent_id,
|
|
6027
|
-
update: [{ id: todayItem.id, title: todayItem.title, status: "in_progress" }]
|
|
6028
|
-
});
|
|
6029
|
-
log(`[claude-scheduler] Moved '${todayItem.title}' to in_progress for '${codeName}'`);
|
|
6030
|
-
} catch (err) {
|
|
6031
|
-
log(`[claude-scheduler] Failed to move item to in_progress: ${err.message}`);
|
|
6032
|
-
}
|
|
6033
|
-
}
|
|
6034
|
-
}
|
|
6035
6018
|
inFlightClaudeTasks.add(task.taskId);
|
|
6036
6019
|
claudeTaskConcurrency.set(codeName, (claudeTaskConcurrency.get(codeName) ?? 0) + 1);
|
|
6037
6020
|
log(`[claude-scheduler] Firing '${task.name}' for '${codeName}'`);
|
|
@@ -6433,30 +6416,6 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
6433
6416
|
log(`[claude-scheduler] Failed to post result for '${codeName}': ${err.message}`);
|
|
6434
6417
|
}
|
|
6435
6418
|
}
|
|
6436
|
-
function fireClaudeWorkTrigger(codeName, agentId, boardItems) {
|
|
6437
|
-
const state5 = claudeSchedulerStates.get(codeName) ?? loadSchedulerState(codeName);
|
|
6438
|
-
const kanbanTask = findTaskByTemplate(state5, "kanban-work");
|
|
6439
|
-
if (!kanbanTask) {
|
|
6440
|
-
log(`[claude-scheduler] Work trigger: no kanban-work task found for '${codeName}'`);
|
|
6441
|
-
return;
|
|
6442
|
-
}
|
|
6443
|
-
if (inFlightClaudeTasks.has(kanbanTask.taskId)) {
|
|
6444
|
-
log(`[claude-scheduler] Work trigger: kanban-work already in-flight for '${codeName}'`);
|
|
6445
|
-
return;
|
|
6446
|
-
}
|
|
6447
|
-
let prompt = kanbanTask.prompt;
|
|
6448
|
-
if (boardItems.length > 0) {
|
|
6449
|
-
const boardPrefix = formatBoardForPrompt(boardItems, "follow-up");
|
|
6450
|
-
prompt = boardPrefix + prompt;
|
|
6451
|
-
}
|
|
6452
|
-
inFlightClaudeTasks.add(kanbanTask.taskId);
|
|
6453
|
-
claudeTaskConcurrency.set(codeName, (claudeTaskConcurrency.get(codeName) ?? 0) + 1);
|
|
6454
|
-
log(`[claude-scheduler] Work trigger: firing kanban-work for '${codeName}'`);
|
|
6455
|
-
executeAndProcessClaudeTask(codeName, agentId, kanbanTask, prompt).finally(() => {
|
|
6456
|
-
inFlightClaudeTasks.delete(kanbanTask.taskId);
|
|
6457
|
-
claudeTaskConcurrency.set(codeName, Math.max(0, (claudeTaskConcurrency.get(codeName) ?? 1) - 1));
|
|
6458
|
-
});
|
|
6459
|
-
}
|
|
6460
6419
|
var persistentSessionAgents = /* @__PURE__ */ new Set();
|
|
6461
6420
|
var lastMcpFailedBannerCount = /* @__PURE__ */ new Map();
|
|
6462
6421
|
var persistentSessionStuckTracker = new PersistentSessionStuckTracker();
|
|
@@ -6711,13 +6670,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash3("sha256").
|
|
|
6711
6670
|
log(`[persistent-session] ${ready.length} ready task(s) for '${codeName}': ${ready.map((t) => `${t.name}(next=${t.nextFireAt ? new Date(t.nextFireAt).toISOString() : "null"})`).join(", ")}`);
|
|
6712
6671
|
}
|
|
6713
6672
|
for (const task of ready) {
|
|
6714
|
-
if (KANBAN_WORK_TEMPLATES.has(task.templateId)
|
|
6715
|
-
const updated = markTaskFired(codeName, task.taskId, "ok");
|
|
6716
|
-
claudeSchedulerStates.set(codeName, updated);
|
|
6717
|
-
continue;
|
|
6718
|
-
}
|
|
6719
|
-
if (KANBAN_WORK_TEMPLATES.has(task.templateId) && !hasActionableItems(boardItems)) {
|
|
6720
|
-
log(`[persistent-session] Skipping '${task.name}' for '${codeName}' \u2014 board is empty`);
|
|
6673
|
+
if (KANBAN_WORK_TEMPLATES.has(task.templateId)) {
|
|
6721
6674
|
const updated = markTaskFired(codeName, task.taskId, "ok");
|
|
6722
6675
|
claudeSchedulerStates.set(codeName, updated);
|
|
6723
6676
|
continue;
|
|
@@ -6728,19 +6681,6 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash3("sha256").
|
|
|
6728
6681
|
const boardPrefix = formatBoardForPrompt(boardItems, template);
|
|
6729
6682
|
prompt = boardPrefix + prompt;
|
|
6730
6683
|
}
|
|
6731
|
-
if (KANBAN_WORK_TEMPLATES.has(task.templateId)) {
|
|
6732
|
-
const todayItem = boardItems.find((b) => b.status === "todo");
|
|
6733
|
-
if (todayItem) {
|
|
6734
|
-
try {
|
|
6735
|
-
await api.post("/host/kanban", {
|
|
6736
|
-
agent_id: agent.agent_id,
|
|
6737
|
-
update: [{ id: todayItem.id, title: todayItem.title, status: "in_progress" }]
|
|
6738
|
-
});
|
|
6739
|
-
log(`[persistent-session] Moved '${todayItem.title}' to in_progress for '${codeName}'`);
|
|
6740
|
-
} catch {
|
|
6741
|
-
}
|
|
6742
|
-
}
|
|
6743
|
-
}
|
|
6744
6684
|
if (inFlightClaudeTasks.has(task.taskId)) {
|
|
6745
6685
|
continue;
|
|
6746
6686
|
}
|
|
@@ -6974,15 +6914,13 @@ function ensureRealtimeKanbanStarted(agentStates) {
|
|
|
6974
6914
|
if (!agent) return;
|
|
6975
6915
|
const agentFw = agentFrameworkCache.get(agent.codeName) ?? "openclaw";
|
|
6976
6916
|
if (agentFw === "claude-code") {
|
|
6977
|
-
const boardItems = kanbanBoardCache.get(agent.codeName) ?? [];
|
|
6978
6917
|
if (isSessionHealthy(agent.codeName)) {
|
|
6979
6918
|
injectMessage(agent.codeName, "task", `New task added to your board: id=${item.id} title=${JSON.stringify(item.title)} priority=${item.priority}. Call kanban_move("${item.id}", "in_progress") and start working.`, {
|
|
6980
6919
|
task_name: "kanban-work-trigger"
|
|
6981
6920
|
}, log);
|
|
6982
6921
|
log(`[realtime] Injected kanban-work trigger for '${agent.codeName}': "${item.title}"`);
|
|
6983
6922
|
} else {
|
|
6984
|
-
|
|
6985
|
-
log(`[realtime] Fired kanban-work for '${agent.codeName}': "${item.title}"`);
|
|
6923
|
+
log(`[realtime] Work trigger skipped for '${agent.codeName}' \u2014 session not yet healthy; hybrid will pick up "${item.title}"`);
|
|
6986
6924
|
}
|
|
6987
6925
|
}
|
|
6988
6926
|
},
|
|
@@ -7221,13 +7159,8 @@ var KANBAN_WORK_TEMPLATES = /* @__PURE__ */ new Set(["kanban-work"]);
|
|
|
7221
7159
|
function isPlainScheduledTemplate(templateId) {
|
|
7222
7160
|
return !STANDUP_TEMPLATES.has(templateId) && !TASK_UPDATE_TEMPLATES.has(templateId) && !PLAN_TEMPLATES.has(templateId) && !KANBAN_WORK_TEMPLATES.has(templateId);
|
|
7223
7161
|
}
|
|
7224
|
-
function isKanbanWorkCronDisabled() {
|
|
7225
|
-
const v = process.env["AGT_DISABLE_KANBAN_WORK_CRON"];
|
|
7226
|
-
return v === "1" || v?.toLowerCase() === "true";
|
|
7227
|
-
}
|
|
7228
7162
|
function isKanbanHybridEnabled() {
|
|
7229
|
-
|
|
7230
|
-
return v === "1" || v?.toLowerCase() === "true";
|
|
7163
|
+
return true;
|
|
7231
7164
|
}
|
|
7232
7165
|
function isKanbanHybridDryRun() {
|
|
7233
7166
|
const v = process.env["AGT_KANBAN_HYBRID_DRY_RUN"];
|
|
@@ -7302,18 +7235,7 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
|
|
|
7302
7235
|
log(`[manager-worker] kanban inject failed for '${codeName}'`);
|
|
7303
7236
|
}
|
|
7304
7237
|
}
|
|
7305
|
-
|
|
7306
|
-
if (!isKanbanHybridEnabled()) return;
|
|
7307
|
-
const cronOff = isKanbanWorkCronDisabled();
|
|
7308
|
-
const loopOff = isKanbanLoopDisabled();
|
|
7309
|
-
if (!cronOff || !loopOff) {
|
|
7310
|
-
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";
|
|
7311
|
-
log(
|
|
7312
|
-
`[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.`
|
|
7313
|
-
);
|
|
7314
|
-
}
|
|
7315
|
-
}
|
|
7316
|
-
var BOARD_INJECT_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan", "task-update", "hourly-status", "end-of-day-summary", "kanban-work"]);
|
|
7238
|
+
var BOARD_INJECT_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan", "task-update", "hourly-status", "end-of-day-summary"]);
|
|
7317
7239
|
var ACTIONABLE_STATUSES = /* @__PURE__ */ new Set(["todo", "in_progress"]);
|
|
7318
7240
|
function hasActionableItems(items) {
|
|
7319
7241
|
return items.some((item) => ACTIONABLE_STATUSES.has(item.status));
|
|
@@ -7322,6 +7244,7 @@ var lastHarvestAt = /* @__PURE__ */ new Map();
|
|
|
7322
7244
|
var HARVEST_INTERVAL_MS = 3 * 60 * 1e3;
|
|
7323
7245
|
var kanbanBoardCache = /* @__PURE__ */ new Map();
|
|
7324
7246
|
var notifyBoardCache = /* @__PURE__ */ new Map();
|
|
7247
|
+
var NOTIFY_RESULT_MAX_CHARS = 3500;
|
|
7325
7248
|
async function harvestCronResults(codeName, tasks, gatewayPort) {
|
|
7326
7249
|
const token = readGatewayToken(codeName);
|
|
7327
7250
|
const gwArgs = ["--url", `ws://127.0.0.1:${gatewayPort}`, ...token ? ["--token", token] : []];
|
|
@@ -8151,7 +8074,7 @@ async function processClaudePairSessions(agents) {
|
|
|
8151
8074
|
killPairSession,
|
|
8152
8075
|
pairTmuxSession,
|
|
8153
8076
|
finalizeClaudePairOnboarding
|
|
8154
|
-
} = await import("../claude-pair-runtime-
|
|
8077
|
+
} = await import("../claude-pair-runtime-A35NZYDN.js");
|
|
8155
8078
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
8156
8079
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
8157
8080
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -8270,6 +8193,24 @@ async function maybePostScheduledTaskRatingPrompt(agentId, taskId, channelId, me
|
|
|
8270
8193
|
log(`[rating-prompt] Failed to post rating prompt for ${agentId}/${taskId}: ${err.message}`);
|
|
8271
8194
|
}
|
|
8272
8195
|
}
|
|
8196
|
+
async function buildDoneCardNotification(agentId, codeName, displayName, item) {
|
|
8197
|
+
const isFailed = item.status === "failed";
|
|
8198
|
+
let resultBody = item.result ?? "";
|
|
8199
|
+
try {
|
|
8200
|
+
const full = await api.post("/host/kanban-item", {
|
|
8201
|
+
agent_id: agentId,
|
|
8202
|
+
item_id: item.id
|
|
8203
|
+
});
|
|
8204
|
+
if (full.item?.result) resultBody = full.item.result;
|
|
8205
|
+
} catch (err) {
|
|
8206
|
+
log(`[notify] full-result fetch failed for card ${item.id} on '${codeName}': ${err.message} \u2014 using truncated board result`);
|
|
8207
|
+
}
|
|
8208
|
+
const resultLine = resultBody ? `
|
|
8209
|
+
${isFailed ? "Reason" : "Result"}: ${resultBody.slice(0, NOTIFY_RESULT_MAX_CHARS)}` : "";
|
|
8210
|
+
const emoji = isFailed ? "\u274C" : "\u2705";
|
|
8211
|
+
return `${emoji} ${isFailed ? "Task Failed" : "Task Complete"} \u2014 ${displayName}
|
|
8212
|
+
${item.title}${resultLine}`;
|
|
8213
|
+
}
|
|
8273
8214
|
async function sendTaskNotification(agentCodeName, channel, to, text) {
|
|
8274
8215
|
const tokens = agentChannelTokens.get(agentCodeName);
|
|
8275
8216
|
if (channel === "slack") {
|
|
@@ -8754,7 +8695,6 @@ function startManager(opts) {
|
|
|
8754
8695
|
log(
|
|
8755
8696
|
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join6(homedir4(), ".augmented", "manager.log")}`
|
|
8756
8697
|
);
|
|
8757
|
-
warnOnConflictingKanbanModes();
|
|
8758
8698
|
deployMcpAssets();
|
|
8759
8699
|
reapOrphanChannelMcps({ log });
|
|
8760
8700
|
void ensureHostFrameworkBinaries();
|
|
@@ -8922,6 +8862,7 @@ export {
|
|
|
8922
8862
|
ChildProcessError,
|
|
8923
8863
|
__resetScheduledDeliveryDedupeForTest,
|
|
8924
8864
|
applyRestartAcks,
|
|
8865
|
+
buildDoneCardNotification,
|
|
8925
8866
|
claudeCodeUpgradeMarkerPath,
|
|
8926
8867
|
claudeCodeUpgradeThrottled,
|
|
8927
8868
|
deliverScheduledCardResult,
|
|
@@ -8933,7 +8874,6 @@ export {
|
|
|
8933
8874
|
isHybridActionable,
|
|
8934
8875
|
isKanbanHybridDryRun,
|
|
8935
8876
|
isKanbanHybridEnabled,
|
|
8936
|
-
isKanbanWorkCronDisabled,
|
|
8937
8877
|
isPlainScheduledTemplate,
|
|
8938
8878
|
isScheduledCardTracked,
|
|
8939
8879
|
isScheduledViaKanbanEnabled,
|
|
@@ -8945,7 +8885,6 @@ export {
|
|
|
8945
8885
|
shouldSkipRevokedCleanup,
|
|
8946
8886
|
stampClaudeCodeUpgradeMarker,
|
|
8947
8887
|
startManager,
|
|
8948
|
-
stopManager
|
|
8949
|
-
warnOnConflictingKanbanModes
|
|
8888
|
+
stopManager
|
|
8950
8889
|
};
|
|
8951
8890
|
//# sourceMappingURL=manager-worker.js.map
|