@integrity-labs/agt-cli 0.15.2 → 0.15.4
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 +3 -3
- package/dist/{chunk-IQI7XAQ6.js → chunk-WDF7NJ2F.js} +42 -11
- package/dist/chunk-WDF7NJ2F.js.map +1 -0
- package/dist/lib/manager-worker.js +58 -2
- package/dist/lib/manager-worker.js.map +1 -1
- package/mcp/index.js +0 -0
- package/mcp/slack-channel.js +29 -17
- package/mcp/telegram-channel.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-IQI7XAQ6.js.map +0 -1
package/mcp/index.js
CHANGED
|
File without changes
|
package/mcp/slack-channel.js
CHANGED
|
@@ -14229,6 +14229,30 @@ if (!BOT_TOKEN || !APP_TOKEN) {
|
|
|
14229
14229
|
);
|
|
14230
14230
|
process.exit(1);
|
|
14231
14231
|
}
|
|
14232
|
+
async function getBotUserId() {
|
|
14233
|
+
try {
|
|
14234
|
+
const res = await fetch("https://slack.com/api/auth.test", {
|
|
14235
|
+
headers: { Authorization: `Bearer ${BOT_TOKEN}` }
|
|
14236
|
+
});
|
|
14237
|
+
const data = await res.json();
|
|
14238
|
+
return data.ok ? data.user_id ?? null : null;
|
|
14239
|
+
} catch {
|
|
14240
|
+
return null;
|
|
14241
|
+
}
|
|
14242
|
+
}
|
|
14243
|
+
async function resolveBotUserIdOrThrow() {
|
|
14244
|
+
for (let attempt = 1; attempt <= 5; attempt++) {
|
|
14245
|
+
const id = await getBotUserId();
|
|
14246
|
+
if (id) return id;
|
|
14247
|
+
await new Promise((r) => setTimeout(r, attempt * 1e3));
|
|
14248
|
+
}
|
|
14249
|
+
throw new Error("slack-channel: failed to resolve bot user_id via auth.test after 5 attempts");
|
|
14250
|
+
}
|
|
14251
|
+
var botUserId = await resolveBotUserIdOrThrow();
|
|
14252
|
+
var botUserIdForLog = `${botUserId.slice(0, 2)}***${botUserId.slice(-2)}`;
|
|
14253
|
+
process.stderr.write(`slack-channel: Bot user ID resolved (${botUserIdForLog})
|
|
14254
|
+
`);
|
|
14255
|
+
var selfIdentityInstruction = `Your own Slack user_id is ${botUserId}. Treat <@${botUserId}> mentions as directed at you, even inside auto_followed threads.`;
|
|
14232
14256
|
var mcp = new Server(
|
|
14233
14257
|
{ name: "slack", version: "0.1.0" },
|
|
14234
14258
|
{
|
|
@@ -14241,11 +14265,14 @@ var mcp = new Server(
|
|
|
14241
14265
|
// and the agent silently loses attachment-handling guidance.
|
|
14242
14266
|
instructions: [
|
|
14243
14267
|
'Messages from Slack arrive as <channel source="slack" user="<slack-id>" user_name="<display-name>" channel="..." thread_ts="...">.',
|
|
14268
|
+
selfIdentityInstruction,
|
|
14244
14269
|
"Inbound attachments: the <channel> tag's `files` attribute is a JSON-serialised array \u2014 JSON.parse it before iterating. If a file entry has a `path`, the image is ALREADY DOWNLOADED locally \u2014 Read that path directly, do NOT call slack.download_attachment. That tool is only for entries with `file_id` but NO `path` (PDF, docx, csv, etc.): pass file_id + channel verbatim (never paraphrase), then Read the returned path. Single-image messages also get a top-level `image_path` convenience attribute; multi-image messages omit it. Never tell the user about internal file-handling failures that don't affect the answer.",
|
|
14245
14270
|
"Reply via slack.reply passing channel and thread_ts from the tag. Always include thread_ts on threaded replies so the response lands in the same thread.",
|
|
14246
14271
|
"Address users by user_name, never by raw user ID. In multi-participant threads the CURRENT speaker is the one on the latest <channel> tag \u2014 don't conflate with earlier participants.",
|
|
14247
14272
|
"Mentioned in a channel \u2192 respond in that thread. DM \u2192 respond directly.",
|
|
14248
14273
|
'auto_followed="true" messages are from threads you previously joined: reply only if you have something useful to add. Skip if the conversation moved on, the message is directed at someone else, or your input would not add value.',
|
|
14274
|
+
'Reaction taxonomy (use slack.react sparingly \u2014 most messages need a reply, not a reaction): \u{1F440} = ack/working on it (already auto-added on inbound, do not duplicate); \u2705 = action completed successfully; \u274C = you TRIED to execute the requested action and it FAILED with an error. Do NOT use \u274C to mean "skipped", "disagree", "n/a", "not addressed to me", or "no response needed".',
|
|
14275
|
+
`When a message in a thread is not addressed to you (different @-mention, conversation between others, auto_followed catch-up): SILENTLY SKIP \u2014 no reaction, no reply, do nothing. Adding \u274C in this case is wrong; it gives the user a misleading "execution failed" signal when in fact you correctly identified the message wasn't yours to handle.`,
|
|
14249
14276
|
"To deliver a file, save it under your project dir and call slack.upload_file with path, channel, thread_ts."
|
|
14250
14277
|
].join(" ")
|
|
14251
14278
|
}
|
|
@@ -14273,13 +14300,13 @@ mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
14273
14300
|
},
|
|
14274
14301
|
{
|
|
14275
14302
|
name: "slack.react",
|
|
14276
|
-
description:
|
|
14303
|
+
description: 'Add an emoji reaction to a Slack message. Use sparingly \u2014 prefer a text reply. Reaction taxonomy: \u2705 = action completed successfully; \u274C (`x`) = you TRIED to execute the requested action and it FAILED with an error. Do NOT use \u274C for "skipped", "disagree", "not addressed to me", "n/a", or "noted" \u2014 those need either a text reply or no response at all. \u{1F440} (eyes) is already auto-applied on inbound; do not duplicate.',
|
|
14277
14304
|
inputSchema: {
|
|
14278
14305
|
type: "object",
|
|
14279
14306
|
properties: {
|
|
14280
14307
|
channel: { type: "string", description: "Slack channel ID" },
|
|
14281
14308
|
timestamp: { type: "string", description: "Message timestamp to react to" },
|
|
14282
|
-
emoji: { type: "string", description: 'Emoji name without colons (e.g. "
|
|
14309
|
+
emoji: { type: "string", description: 'Emoji name without colons (e.g. "white_check_mark", "x"). Only use "x" when an execution attempt actually failed.' }
|
|
14283
14310
|
},
|
|
14284
14311
|
required: ["channel", "timestamp", "emoji"]
|
|
14285
14312
|
}
|
|
@@ -14768,18 +14795,6 @@ async function buildInboundFileMeta(rawFiles, codeName, channel) {
|
|
|
14768
14795
|
return out;
|
|
14769
14796
|
}
|
|
14770
14797
|
await mcp.connect(new StdioServerTransport());
|
|
14771
|
-
var botUserId = null;
|
|
14772
|
-
async function getBotUserId() {
|
|
14773
|
-
try {
|
|
14774
|
-
const res = await fetch("https://slack.com/api/auth.test", {
|
|
14775
|
-
headers: { Authorization: `Bearer ${BOT_TOKEN}` }
|
|
14776
|
-
});
|
|
14777
|
-
const data = await res.json();
|
|
14778
|
-
return data.ok ? data.user_id ?? null : null;
|
|
14779
|
-
} catch {
|
|
14780
|
-
return null;
|
|
14781
|
-
}
|
|
14782
|
-
}
|
|
14783
14798
|
var userNameCache = /* @__PURE__ */ new Map();
|
|
14784
14799
|
async function resolveUserName(userId) {
|
|
14785
14800
|
if (!userId || userId === "unknown") return userId ?? "unknown";
|
|
@@ -14983,7 +14998,4 @@ if (THREAD_STORE_PATH) {
|
|
|
14983
14998
|
"slack-channel: AGT_AGENT_CODE_NAME not set \u2014 running without thread-follow persistence\n"
|
|
14984
14999
|
);
|
|
14985
15000
|
}
|
|
14986
|
-
botUserId = await getBotUserId();
|
|
14987
|
-
process.stderr.write(`slack-channel: Bot user ID: ${botUserId}
|
|
14988
|
-
`);
|
|
14989
15001
|
connectSocketModeSafely();
|
package/mcp/telegram-channel.js
CHANGED
|
@@ -14227,7 +14227,7 @@ var mcp = new Server(
|
|
|
14227
14227
|
'For work >30s follow CLAUDE.md kanban flow: kanban.add, reply with "On it \u2014 tracking here: <kanban URL>", move to in_progress, do the work, reply with the result. Simple lookups skip kanban but still reply.',
|
|
14228
14228
|
"Address users by user_name; user is the numeric Telegram ID. Reply-to a specific message with reply_to_message_id, otherwise omit.",
|
|
14229
14229
|
"Resolve ambiguous times against your own Timezone from CLAUDE.md \u2014 do not ask the user.",
|
|
14230
|
-
|
|
14230
|
+
`Reaction taxonomy (use telegram.react sparingly \u2014 prefer a text reply via telegram.reply): \u{1F440} = ack/working on it (already auto-added on inbound, do not duplicate); \u{1F44D} or \u{1F389} = action completed successfully; \u{1F494} = you TRIED to execute the requested action and it FAILED with an error (Telegram's free-tier stand-in for Slack's \u274C; the literal \u274C is not on the bot-allowed emoji list). Do NOT use \u{1F494} for "skipped", "disagree", "n/a", or "no response needed" \u2014 those need either a text reply or no reaction. Free-tier emoji set: \u{1F44D} \u{1F44E} \u2764 \u{1F525} \u{1F389} \u{1F914} \u{1F92F} \u{1F64F} \u{1F44C} \u{1F440} \u{1F4AF} \u270D \u{1FAE1} \u{1F192} \u{1F973} \u{1F494} (premium-only fail silently).`
|
|
14231
14231
|
].join(" ")
|
|
14232
14232
|
}
|
|
14233
14233
|
);
|
|
@@ -14287,7 +14287,7 @@ mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
14287
14287
|
},
|
|
14288
14288
|
{
|
|
14289
14289
|
name: "telegram.react",
|
|
14290
|
-
description:
|
|
14290
|
+
description: `Add an emoji reaction to a Telegram message. Use sparingly \u2014 prefer a text reply via telegram.reply. Reaction taxonomy: \u{1F44D} or \u{1F389} = action completed successfully; \u{1F494} = you TRIED to execute the requested action and it FAILED with an error (free-tier stand-in for Slack's \u274C). Do NOT use \u{1F494} for "skipped", "disagree", or "noted" \u2014 those need a text reply or no reaction at all. \u{1F440} is already auto-applied on inbound; do not duplicate. Only free-tier emoji reactions are available to bots (Premium-only emoji fail silently). Pass an empty string or omit emoji to clear the bot's reaction on that message.`,
|
|
14291
14291
|
inputSchema: {
|
|
14292
14292
|
type: "object",
|
|
14293
14293
|
properties: {
|