@integrity-labs/agt-cli 0.15.38 → 0.16.0
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 +50 -50
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-XJSQKRFV.js → chunk-LU6L2J32.js} +97 -9
- package/dist/chunk-LU6L2J32.js.map +1 -0
- package/dist/{claude-pair-runtime-GLO2D7WP.js → claude-pair-runtime-GS6AOYHS.js} +2 -2
- package/dist/claude-pair-runtime-GS6AOYHS.js.map +1 -0
- package/dist/lib/manager-worker.js +131 -107
- package/dist/lib/manager-worker.js.map +1 -1
- package/mcp/slack-channel.js +99 -22
- package/package.json +1 -1
- package/dist/chunk-XJSQKRFV.js.map +0 -1
- package/dist/claude-pair-runtime-GLO2D7WP.js.map +0 -1
package/mcp/slack-channel.js
CHANGED
|
@@ -14799,6 +14799,7 @@ async function processSlackRecoveryOutboxFile(filename) {
|
|
|
14799
14799
|
const data = await res.json();
|
|
14800
14800
|
if (data.ok) {
|
|
14801
14801
|
sendSucceeded = true;
|
|
14802
|
+
recordActivity("reply");
|
|
14802
14803
|
process.stderr.write(
|
|
14803
14804
|
`slack-channel(${AGENT_CODE_NAME}): ghost-reply recovery sent (channel=${redactSlackId(payload.channel)} thread=${redactSlackId(payload.thread_ts)})
|
|
14804
14805
|
`
|
|
@@ -15000,6 +15001,7 @@ function buildSlackHelpMessage(codeName) {
|
|
|
15000
15001
|
}
|
|
15001
15002
|
var lastActivityAt = null;
|
|
15002
15003
|
var lastActivityKind = null;
|
|
15004
|
+
var setBotStatusWarnedErrors = /* @__PURE__ */ new Set();
|
|
15003
15005
|
function recordActivity(kind) {
|
|
15004
15006
|
lastActivityAt = Date.now();
|
|
15005
15007
|
lastActivityKind = kind;
|
|
@@ -15017,10 +15019,21 @@ async function setBotStatus(status_emoji, status_text) {
|
|
|
15017
15019
|
});
|
|
15018
15020
|
const data = await res.json();
|
|
15019
15021
|
if (!data.ok) {
|
|
15020
|
-
|
|
15021
|
-
|
|
15022
|
+
const code = data.error ?? "unknown";
|
|
15023
|
+
if (code === "missing_scope") {
|
|
15024
|
+
if (!setBotStatusWarnedErrors.has(code)) {
|
|
15025
|
+
setBotStatusWarnedErrors.add(code);
|
|
15026
|
+
process.stderr.write(
|
|
15027
|
+
`slack-channel: users.profile.set failed (missing_scope) \u2014 bot presence indicator disabled until users.profile:write is granted (re-OAuth required)
|
|
15022
15028
|
`
|
|
15023
|
-
|
|
15029
|
+
);
|
|
15030
|
+
}
|
|
15031
|
+
} else {
|
|
15032
|
+
process.stderr.write(
|
|
15033
|
+
`slack-channel: users.profile.set failed (${code}) \u2014 bot presence indicator disabled
|
|
15034
|
+
`
|
|
15035
|
+
);
|
|
15036
|
+
}
|
|
15024
15037
|
}
|
|
15025
15038
|
} catch (err) {
|
|
15026
15039
|
process.stderr.write(
|
|
@@ -15054,6 +15067,84 @@ function buildAgentStatusReply(codeName) {
|
|
|
15054
15067
|
const state = connected ? "online" : "offline";
|
|
15055
15068
|
return `${dot} \`${codeName}\` is *${state}* \u2014 Socket Mode ${connected ? "connected" : "disconnected"}. Last activity: ${formatLastActivity()}.`;
|
|
15056
15069
|
}
|
|
15070
|
+
async function postEphemeralViaResponseUrl(responseUrl, text, logTag) {
|
|
15071
|
+
try {
|
|
15072
|
+
await fetch(responseUrl, {
|
|
15073
|
+
method: "POST",
|
|
15074
|
+
headers: { "Content-Type": "application/json; charset=utf-8" },
|
|
15075
|
+
body: JSON.stringify({ response_type: "ephemeral", text }),
|
|
15076
|
+
// Match the rest of the Slack API call sites in this file. Without
|
|
15077
|
+
// this, a hung response_url request can stall the live Socket Mode
|
|
15078
|
+
// event loop indefinitely (CodeRabbit feedback on PR #578).
|
|
15079
|
+
signal: AbortSignal.timeout(SLACK_DOWNLOAD_TIMEOUT_MS)
|
|
15080
|
+
});
|
|
15081
|
+
} catch (err) {
|
|
15082
|
+
process.stderr.write(
|
|
15083
|
+
`slack-channel(${logTag}): response_url POST failed: ${err.message}
|
|
15084
|
+
`
|
|
15085
|
+
);
|
|
15086
|
+
}
|
|
15087
|
+
}
|
|
15088
|
+
async function handleSlashCommandEnvelope(payload) {
|
|
15089
|
+
const command = payload.command;
|
|
15090
|
+
const responseUrl = payload.response_url;
|
|
15091
|
+
const codeName = AGENT_CODE_NAME ?? "unknown";
|
|
15092
|
+
if (!command || !responseUrl) return;
|
|
15093
|
+
if (command === "/agent-status") {
|
|
15094
|
+
await postEphemeralViaResponseUrl(responseUrl, buildAgentStatusReply(codeName), codeName);
|
|
15095
|
+
return;
|
|
15096
|
+
}
|
|
15097
|
+
if (command === "/kill" || command === "/unkill") {
|
|
15098
|
+
if (!AGT_HOST || !AGT_API_KEY || !AGT_AGENT_ID) {
|
|
15099
|
+
await postEphemeralViaResponseUrl(
|
|
15100
|
+
responseUrl,
|
|
15101
|
+
":warning: This agent has no host API wiring \u2014 `/kill` / `/unkill` need the host runtime to be reachable.",
|
|
15102
|
+
codeName
|
|
15103
|
+
);
|
|
15104
|
+
return;
|
|
15105
|
+
}
|
|
15106
|
+
if (!payload.thread_ts || !payload.channel_id || !payload.user_id) {
|
|
15107
|
+
await postEphemeralViaResponseUrl(
|
|
15108
|
+
responseUrl,
|
|
15109
|
+
`:warning: \`${command}\` only works inside a thread. Invoke it as a thread reply.`,
|
|
15110
|
+
codeName
|
|
15111
|
+
);
|
|
15112
|
+
return;
|
|
15113
|
+
}
|
|
15114
|
+
try {
|
|
15115
|
+
const res = await fetch(`${AGT_HOST}/host/slack/thread-kill`, {
|
|
15116
|
+
method: "POST",
|
|
15117
|
+
headers: {
|
|
15118
|
+
"Content-Type": "application/json; charset=utf-8",
|
|
15119
|
+
Authorization: `Bearer ${AGT_API_KEY}`
|
|
15120
|
+
},
|
|
15121
|
+
body: JSON.stringify({
|
|
15122
|
+
agent_id: AGT_AGENT_ID,
|
|
15123
|
+
op: command === "/kill" ? "kill" : "unkill",
|
|
15124
|
+
channel_id: payload.channel_id,
|
|
15125
|
+
thread_ts: payload.thread_ts,
|
|
15126
|
+
user_id: payload.user_id,
|
|
15127
|
+
user_name: payload.user_name
|
|
15128
|
+
}),
|
|
15129
|
+
signal: AbortSignal.timeout(SLACK_DOWNLOAD_TIMEOUT_MS)
|
|
15130
|
+
});
|
|
15131
|
+
const data = await res.json();
|
|
15132
|
+
const text = data.message ?? (data.ok ? command === "/kill" ? ":lock: Kill engaged for this thread." : ":unlock: Kill cleared for this thread." : `:x: ${command} failed.`);
|
|
15133
|
+
await postEphemeralViaResponseUrl(responseUrl, text, codeName);
|
|
15134
|
+
} catch (err) {
|
|
15135
|
+
process.stderr.write(
|
|
15136
|
+
`slack-channel(${codeName}): ${command} forward failed: ${err.message}
|
|
15137
|
+
`
|
|
15138
|
+
);
|
|
15139
|
+
await postEphemeralViaResponseUrl(
|
|
15140
|
+
responseUrl,
|
|
15141
|
+
`:x: \`${command}\` forwarding failed \u2014 host runtime unreachable. Try again in a moment.`,
|
|
15142
|
+
codeName
|
|
15143
|
+
);
|
|
15144
|
+
}
|
|
15145
|
+
return;
|
|
15146
|
+
}
|
|
15147
|
+
}
|
|
15057
15148
|
async function handleHelpCommand(opts) {
|
|
15058
15149
|
const codeName = AGENT_CODE_NAME ?? "unknown";
|
|
15059
15150
|
const replyThread = opts.threadTs ?? opts.ts;
|
|
@@ -15490,6 +15581,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
15490
15581
|
};
|
|
15491
15582
|
}
|
|
15492
15583
|
recordReply(channel, throttleKey, throttleNow, throttleCfg);
|
|
15584
|
+
recordActivity("reply");
|
|
15493
15585
|
if (THREAD_AUTO_FOLLOW !== "off") {
|
|
15494
15586
|
const trackTs = thread_ts ?? data.ts ?? void 0;
|
|
15495
15587
|
rememberThread(channel, trackTs, thread_ts ? "mentioned" : "started");
|
|
@@ -15789,7 +15881,9 @@ async function postSlackMessageWithTs(payload) {
|
|
|
15789
15881
|
body: JSON.stringify(payload),
|
|
15790
15882
|
signal: AbortSignal.timeout(SLACK_DOWNLOAD_TIMEOUT_MS)
|
|
15791
15883
|
});
|
|
15792
|
-
|
|
15884
|
+
const data = await res.json();
|
|
15885
|
+
if (data.ok) recordActivity("reply");
|
|
15886
|
+
return data;
|
|
15793
15887
|
} catch (err) {
|
|
15794
15888
|
const isTimeout = err.name === "TimeoutError" || err.name === "AbortError";
|
|
15795
15889
|
return { ok: false, error: isTimeout ? "timeout" : err.message };
|
|
@@ -16256,24 +16350,7 @@ async function connectSocketMode() {
|
|
|
16256
16350
|
ws.send(JSON.stringify({ envelope_id: msg.envelope_id }));
|
|
16257
16351
|
}
|
|
16258
16352
|
if (msg.type === "slash_commands" && msg.payload?.command) {
|
|
16259
|
-
|
|
16260
|
-
const responseUrl = msg.payload.response_url;
|
|
16261
|
-
if (command === "/agent-status" && responseUrl) {
|
|
16262
|
-
const codeName = AGENT_CODE_NAME ?? "unknown";
|
|
16263
|
-
fetch(responseUrl, {
|
|
16264
|
-
method: "POST",
|
|
16265
|
-
headers: { "Content-Type": "application/json; charset=utf-8" },
|
|
16266
|
-
body: JSON.stringify({
|
|
16267
|
-
response_type: "ephemeral",
|
|
16268
|
-
text: buildAgentStatusReply(codeName)
|
|
16269
|
-
})
|
|
16270
|
-
}).catch((err) => {
|
|
16271
|
-
process.stderr.write(
|
|
16272
|
-
`slack-channel(${codeName}): /agent-status response_url POST failed: ${err.message}
|
|
16273
|
-
`
|
|
16274
|
-
);
|
|
16275
|
-
});
|
|
16276
|
-
}
|
|
16353
|
+
void handleSlashCommandEnvelope(msg.payload);
|
|
16277
16354
|
return;
|
|
16278
16355
|
}
|
|
16279
16356
|
if (msg.type === "interactive" && msg.payload?.type === "block_actions") {
|