@integrity-labs/agt-cli 0.27.13 → 0.27.14
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 +31 -12
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-GN4XPQWJ.js → chunk-5ZUNHYKV.js} +2 -2
- package/dist/{chunk-Q4MWFZ5Y.js → chunk-HKZFMGYE.js} +9 -6
- package/dist/{chunk-Q4MWFZ5Y.js.map → chunk-HKZFMGYE.js.map} +1 -1
- package/dist/{chunk-YSBGIXJG.js → chunk-HT6EETEL.js} +1 -1
- package/dist/{claude-pair-runtime-ZBQKBBMT.js → claude-pair-runtime-ISBA6RDU.js} +2 -2
- package/dist/lib/manager-worker.js +7 -7
- package/dist/mcp/slack-channel.js +99 -42
- package/dist/{persistent-session-ICYFLUAM.js → persistent-session-N6SYAERB.js} +3 -3
- package/dist/{responsiveness-probe-WZNQ2762.js → responsiveness-probe-GPRQBBZG.js} +3 -3
- package/package.json +1 -1
- /package/dist/{chunk-GN4XPQWJ.js.map → chunk-5ZUNHYKV.js.map} +0 -0
- /package/dist/{chunk-YSBGIXJG.js.map → chunk-HT6EETEL.js.map} +0 -0
- /package/dist/{claude-pair-runtime-ZBQKBBMT.js.map → claude-pair-runtime-ISBA6RDU.js.map} +0 -0
- /package/dist/{persistent-session-ICYFLUAM.js.map → persistent-session-N6SYAERB.js.map} +0 -0
- /package/dist/{responsiveness-probe-WZNQ2762.js.map → responsiveness-probe-GPRQBBZG.js.map} +0 -0
|
@@ -100,7 +100,7 @@ async function spawnPairSession(session) {
|
|
|
100
100
|
return { ok: true };
|
|
101
101
|
} catch {
|
|
102
102
|
}
|
|
103
|
-
const { resolveClaudeBinary } = await import("./persistent-session-
|
|
103
|
+
const { resolveClaudeBinary } = await import("./persistent-session-N6SYAERB.js");
|
|
104
104
|
const claudeBin = resolveClaudeBinary();
|
|
105
105
|
const pairEnv = {
|
|
106
106
|
...process.env,
|
|
@@ -373,4 +373,4 @@ export {
|
|
|
373
373
|
startClaudePair,
|
|
374
374
|
submitClaudePairCode
|
|
375
375
|
};
|
|
376
|
-
//# sourceMappingURL=claude-pair-runtime-
|
|
376
|
+
//# sourceMappingURL=claude-pair-runtime-ISBA6RDU.js.map
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
provisionOrientHook,
|
|
16
16
|
provisionStopHook,
|
|
17
17
|
requireHost
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-HKZFMGYE.js";
|
|
19
19
|
import {
|
|
20
20
|
getProjectDir as getProjectDir2,
|
|
21
21
|
getReadyTasks,
|
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
stopAllSessionsAndWait,
|
|
47
47
|
stopPersistentSession,
|
|
48
48
|
takeZombieDetection
|
|
49
|
-
} from "../chunk-
|
|
49
|
+
} from "../chunk-5ZUNHYKV.js";
|
|
50
50
|
import {
|
|
51
51
|
KANBAN_CHECK_COMMAND,
|
|
52
52
|
appendDmFooter,
|
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
resolveConnectivityProbe,
|
|
70
70
|
resolveDmTarget,
|
|
71
71
|
wrapScheduledTaskPrompt
|
|
72
|
-
} from "../chunk-
|
|
72
|
+
} from "../chunk-HT6EETEL.js";
|
|
73
73
|
import {
|
|
74
74
|
parsePsRows,
|
|
75
75
|
reapOrphanChannelMcps
|
|
@@ -3166,7 +3166,7 @@ var cachedFrameworkVersion = null;
|
|
|
3166
3166
|
var lastVersionCheckAt = 0;
|
|
3167
3167
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
3168
3168
|
var lastResponsivenessProbeAt = 0;
|
|
3169
|
-
var agtCliVersion = true ? "0.27.
|
|
3169
|
+
var agtCliVersion = true ? "0.27.14" : "dev";
|
|
3170
3170
|
function resolveBrewPath(execFileSync4) {
|
|
3171
3171
|
try {
|
|
3172
3172
|
const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -4180,7 +4180,7 @@ async function pollCycle() {
|
|
|
4180
4180
|
}
|
|
4181
4181
|
try {
|
|
4182
4182
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
4183
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
4183
|
+
const { collectDiagnostics } = await import("../persistent-session-N6SYAERB.js");
|
|
4184
4184
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
4185
4185
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
|
|
4186
4186
|
let tailscaleHostname;
|
|
@@ -4248,7 +4248,7 @@ async function pollCycle() {
|
|
|
4248
4248
|
const {
|
|
4249
4249
|
collectResponsivenessProbes,
|
|
4250
4250
|
getResponsivenessIntervalMs
|
|
4251
|
-
} = await import("../responsiveness-probe-
|
|
4251
|
+
} = await import("../responsiveness-probe-GPRQBBZG.js");
|
|
4252
4252
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
4253
4253
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
4254
4254
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -8196,7 +8196,7 @@ async function processClaudePairSessions(agents) {
|
|
|
8196
8196
|
killPairSession,
|
|
8197
8197
|
pairTmuxSession,
|
|
8198
8198
|
finalizeClaudePairOnboarding
|
|
8199
|
-
} = await import("../claude-pair-runtime-
|
|
8199
|
+
} = await import("../claude-pair-runtime-ISBA6RDU.js");
|
|
8200
8200
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
8201
8201
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
8202
8202
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -14813,6 +14813,64 @@ function isMode(value) {
|
|
|
14813
14813
|
return value === "thinking" || value === "working" || value === "waiting";
|
|
14814
14814
|
}
|
|
14815
14815
|
|
|
14816
|
+
// src/slack-thread-context.ts
|
|
14817
|
+
var SLACK_AUTOLOAD_THREAD_LIMIT = 30;
|
|
14818
|
+
var SLACK_AUTOLOAD_THREAD_MAX_CHARS = 4e3;
|
|
14819
|
+
function formatThreadMessages(messages, nameById) {
|
|
14820
|
+
return messages.map((m) => `[${m.ts}] ${nameById.get(m.user) ?? m.user} (<@${m.user}>): ${m.text}`).join("\n");
|
|
14821
|
+
}
|
|
14822
|
+
function capThreadContext(formatted, maxChars) {
|
|
14823
|
+
if (formatted.length <= maxChars) return formatted;
|
|
14824
|
+
const marker = "[\u2026earlier thread messages omitted \u2014 slack.read_thread for full history\u2026]\n";
|
|
14825
|
+
if (maxChars <= marker.length) return marker.slice(0, maxChars);
|
|
14826
|
+
const tailBudget = maxChars - marker.length;
|
|
14827
|
+
const tail = formatted.slice(formatted.length - tailBudget);
|
|
14828
|
+
const firstNewline = tail.indexOf("\n");
|
|
14829
|
+
const clean = firstNewline >= 0 ? tail.slice(firstNewline + 1) : tail;
|
|
14830
|
+
return `${marker}${clean}`;
|
|
14831
|
+
}
|
|
14832
|
+
async function fetchThreadTranscript(channel, threadTs, limit, deps) {
|
|
14833
|
+
const { botToken, resolveUserName: resolveUserName2, fetchImpl = fetch } = deps;
|
|
14834
|
+
const cappedLimit = Math.min(Math.max(limit, 1), 200);
|
|
14835
|
+
const allMessages = [];
|
|
14836
|
+
let cursor;
|
|
14837
|
+
do {
|
|
14838
|
+
const remaining = cappedLimit - allMessages.length;
|
|
14839
|
+
if (remaining <= 0) break;
|
|
14840
|
+
const params = new URLSearchParams({
|
|
14841
|
+
channel,
|
|
14842
|
+
ts: threadTs,
|
|
14843
|
+
limit: String(Math.min(remaining, 100)),
|
|
14844
|
+
...cursor ? { cursor } : {}
|
|
14845
|
+
});
|
|
14846
|
+
let data;
|
|
14847
|
+
try {
|
|
14848
|
+
const res = await fetchImpl(`https://slack.com/api/conversations.replies?${params}`, {
|
|
14849
|
+
headers: { Authorization: `Bearer ${botToken}` }
|
|
14850
|
+
});
|
|
14851
|
+
if (!res.ok) return { ok: false, error: `http_${res.status}` };
|
|
14852
|
+
data = await res.json();
|
|
14853
|
+
} catch (err) {
|
|
14854
|
+
return { ok: false, error: err instanceof Error ? err.message : "fetch_failed" };
|
|
14855
|
+
}
|
|
14856
|
+
if (!data.ok) return { ok: false, error: data.error ?? "unknown" };
|
|
14857
|
+
for (const msg of data.messages ?? []) {
|
|
14858
|
+
allMessages.push({
|
|
14859
|
+
user: msg.user ?? msg.bot_id ?? "unknown",
|
|
14860
|
+
text: msg.text ?? "",
|
|
14861
|
+
ts: msg.ts ?? ""
|
|
14862
|
+
});
|
|
14863
|
+
}
|
|
14864
|
+
cursor = data.response_metadata?.next_cursor || void 0;
|
|
14865
|
+
} while (cursor && allMessages.length < cappedLimit);
|
|
14866
|
+
const uniqueUserIds = [...new Set(allMessages.map((m) => m.user))];
|
|
14867
|
+
const resolved = await Promise.all(
|
|
14868
|
+
uniqueUserIds.map(async (id) => [id, await resolveUserName2(id)])
|
|
14869
|
+
);
|
|
14870
|
+
const nameById = new Map(resolved);
|
|
14871
|
+
return { ok: true, count: allMessages.length, formatted: formatThreadMessages(allMessages, nameById) };
|
|
14872
|
+
}
|
|
14873
|
+
|
|
14816
14874
|
// src/impersonation.ts
|
|
14817
14875
|
var ENV_VAR = "AGT_ACT_AS_AGENT_ID";
|
|
14818
14876
|
var OVERRIDE_ENV_VAR = "ENABLE_IMPERSONATION_CHANNELS";
|
|
@@ -16657,7 +16715,6 @@ void resolveBotUserIdOrThrow().then((id) => {
|
|
|
16657
16715
|
);
|
|
16658
16716
|
if (authFailed) slackBotUserIdClient?.reportAuthHealth(false);
|
|
16659
16717
|
});
|
|
16660
|
-
var selfIdentityInstruction = `Mentions of your own Slack bot user are directed at you, even inside auto_followed threads.`;
|
|
16661
16718
|
var mcp = new Server(
|
|
16662
16719
|
{ name: "slack", version: "0.1.0" },
|
|
16663
16720
|
{
|
|
@@ -16672,12 +16729,11 @@ var mcp = new Server(
|
|
|
16672
16729
|
// Highest-priority lines first — Claude Code truncates this string at
|
|
16673
16730
|
// 2048 chars, so anything appended late silently disappears.
|
|
16674
16731
|
"CRITICAL: every response to a Slack <channel> tag MUST go through slack.reply. Text in your session WITHOUT a slack.reply call never reaches the user \u2014 the message dies inside the agent process.",
|
|
16675
|
-
|
|
16732
|
+
`Inbound: <channel ... thread_ts="..." [thread_context="..."]>. Pass channel + thread_ts to slack.reply on threads. thread_context = thread pre-loaded; ground replies ONLY in it, never another channel's.`,
|
|
16676
16733
|
"Long task (3+ tool calls or >5s)? slack_progress_start (channel + thread_ts), slack_progress_update between steps, slack_progress_complete/_fail to close. One anchor edits in place; avoids thread spam. Not for one-shots.",
|
|
16677
|
-
selfIdentityInstruction,
|
|
16678
16734
|
"Inbound attachments: <channel> `files` is a JSON-serialised array \u2014 JSON.parse it. If an entry has `path`, the image is already downloaded \u2014 Read it directly, do NOT call slack.download_attachment. Use that tool only for entries with `file_id` but NO `path` (PDF, docx, csv): pass file_id + channel verbatim, then Read the returned path. Single-image messages also get a top-level `image_path`. Don't surface internal file-handling errors that don't affect the answer.",
|
|
16679
16735
|
"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.",
|
|
16680
|
-
'Mentioned in a channel \u2192 respond in that thread. DM \u2192 respond directly. auto_followed="true" \u2192 only reply if
|
|
16736
|
+
'Mentioned in a channel \u2192 respond in that thread. DM \u2192 respond directly. auto_followed="true" \u2192 only reply if useful, OR if your own bot user is @-mentioned (counts even in auto_followed).',
|
|
16681
16737
|
"Reaction taxonomy (use slack.react sparingly \u2014 prefer a reply): \u{1F440} = ack (already auto-added on inbound, do not duplicate); \u2705 = success. NEVER react to signal failure \u2014 users can't tell why something failed from an emoji. On failure, slack.reply with one sentence explaining what went wrong (no stack traces, no secrets).",
|
|
16682
16738
|
`When a thread message is NOT addressed to you (different @-mention, side conversation, auto_followed catch-up): SILENTLY SKIP \u2014 no reaction, no reply, no "this wasn't for me" message.`,
|
|
16683
16739
|
"To deliver a file: save under your project dir, call slack.upload_file with path + channel + thread_ts."
|
|
@@ -16743,7 +16799,7 @@ mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
16743
16799
|
},
|
|
16744
16800
|
{
|
|
16745
16801
|
name: "slack.read_thread",
|
|
16746
|
-
description: "Read the full message history of a Slack thread.
|
|
16802
|
+
description: "Read the full message history of a Slack thread. Inbound thread replies already carry the surrounding thread inline as the <channel> tag's thread_context attribute \u2014 ground your reply in that first, and only call this tool when you need MORE history than thread_context shows (it is capped to recent messages) or to catch up on an auto-followed thread.",
|
|
16747
16803
|
inputSchema: {
|
|
16748
16804
|
type: "object",
|
|
16749
16805
|
properties: {
|
|
@@ -17117,46 +17173,22 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
17117
17173
|
const limit = Math.min(Math.max(rawLimit ?? 50, 1), 200);
|
|
17118
17174
|
noteThreadActivity(channel, thread_ts);
|
|
17119
17175
|
try {
|
|
17120
|
-
const
|
|
17121
|
-
|
|
17122
|
-
|
|
17123
|
-
|
|
17124
|
-
|
|
17125
|
-
|
|
17126
|
-
|
|
17127
|
-
|
|
17128
|
-
|
|
17129
|
-
|
|
17130
|
-
});
|
|
17131
|
-
const res = await fetch(`https://slack.com/api/conversations.replies?${params}`, {
|
|
17132
|
-
headers: { Authorization: `Bearer ${BOT_TOKEN}` }
|
|
17133
|
-
});
|
|
17134
|
-
const data = await res.json();
|
|
17135
|
-
if (!data.ok) {
|
|
17136
|
-
return {
|
|
17137
|
-
content: [{ type: "text", text: `Slack error: ${data.error}` }],
|
|
17138
|
-
isError: true
|
|
17139
|
-
};
|
|
17140
|
-
}
|
|
17141
|
-
for (const msg of data.messages ?? []) {
|
|
17142
|
-
allMessages.push({
|
|
17143
|
-
user: msg.user ?? msg.bot_id ?? "unknown",
|
|
17144
|
-
text: msg.text ?? "",
|
|
17145
|
-
ts: msg.ts ?? ""
|
|
17146
|
-
});
|
|
17147
|
-
}
|
|
17148
|
-
cursor = data.response_metadata?.next_cursor || void 0;
|
|
17149
|
-
} while (cursor && allMessages.length < limit);
|
|
17150
|
-
const uniqueUserIds = [...new Set(allMessages.map((m) => m.user))];
|
|
17151
|
-
const resolved = await Promise.all(uniqueUserIds.map(async (id) => [id, await resolveUserName(id)]));
|
|
17152
|
-
const nameById = new Map(resolved);
|
|
17153
|
-
const formatted = allMessages.map((m) => `[${m.ts}] ${nameById.get(m.user) ?? m.user} (<@${m.user}>): ${m.text}`).join("\n");
|
|
17176
|
+
const result = await fetchThreadTranscript(channel, thread_ts, limit, {
|
|
17177
|
+
botToken: BOT_TOKEN,
|
|
17178
|
+
resolveUserName
|
|
17179
|
+
});
|
|
17180
|
+
if (!result.ok) {
|
|
17181
|
+
return {
|
|
17182
|
+
content: [{ type: "text", text: `Slack error: ${result.error}` }],
|
|
17183
|
+
isError: true
|
|
17184
|
+
};
|
|
17185
|
+
}
|
|
17154
17186
|
return {
|
|
17155
17187
|
content: [{
|
|
17156
17188
|
type: "text",
|
|
17157
|
-
text:
|
|
17189
|
+
text: result.count > 0 ? `Thread (${result.count} messages):
|
|
17158
17190
|
|
|
17159
|
-
${formatted}` : "Thread is empty or not found."
|
|
17191
|
+
${result.formatted}` : "Thread is empty or not found."
|
|
17160
17192
|
}]
|
|
17161
17193
|
};
|
|
17162
17194
|
} catch (err) {
|
|
@@ -18246,6 +18278,29 @@ async function connectSocketMode() {
|
|
|
18246
18278
|
(f) => f.kind === "image" && typeof f.path === "string"
|
|
18247
18279
|
);
|
|
18248
18280
|
const imagePath = downloadedImages.length === 1 ? downloadedImages[0].path : void 0;
|
|
18281
|
+
let threadContext;
|
|
18282
|
+
if (isThreadReply && channel && threadTs) {
|
|
18283
|
+
try {
|
|
18284
|
+
const transcript = await fetchThreadTranscript(
|
|
18285
|
+
channel,
|
|
18286
|
+
threadTs,
|
|
18287
|
+
SLACK_AUTOLOAD_THREAD_LIMIT,
|
|
18288
|
+
{ botToken: BOT_TOKEN, resolveUserName }
|
|
18289
|
+
);
|
|
18290
|
+
if (transcript.ok && transcript.count >= 2) {
|
|
18291
|
+
threadContext = capThreadContext(
|
|
18292
|
+
transcript.formatted,
|
|
18293
|
+
SLACK_AUTOLOAD_THREAD_MAX_CHARS
|
|
18294
|
+
);
|
|
18295
|
+
}
|
|
18296
|
+
} catch (err) {
|
|
18297
|
+
const msg2 = err instanceof Error ? err.message : String(err);
|
|
18298
|
+
process.stderr.write(
|
|
18299
|
+
`slack-channel(${AGENT_CODE_NAME}): thread_context fetch failed (channel=${redactSlackId(channel)} thread=${redactSlackId(threadTs)}): ${msg2}
|
|
18300
|
+
`
|
|
18301
|
+
);
|
|
18302
|
+
}
|
|
18303
|
+
}
|
|
18249
18304
|
await mcp.notification({
|
|
18250
18305
|
method: "notifications/claude/channel",
|
|
18251
18306
|
params: {
|
|
@@ -18260,7 +18315,9 @@ async function connectSocketMode() {
|
|
|
18260
18315
|
// Only set these when we actually have attachments to avoid
|
|
18261
18316
|
// bloating every notification with empty metadata.
|
|
18262
18317
|
...fileMeta.length > 0 ? { files: JSON.stringify(fileMeta) } : {},
|
|
18263
|
-
...imagePath ? { image_path: imagePath } : {}
|
|
18318
|
+
...imagePath ? { image_path: imagePath } : {},
|
|
18319
|
+
// ENG-5830: the pre-loaded surrounding thread (thread replies only).
|
|
18320
|
+
...threadContext ? { thread_context: threadContext } : {}
|
|
18264
18321
|
}
|
|
18265
18322
|
}
|
|
18266
18323
|
});
|
|
@@ -21,8 +21,8 @@ import {
|
|
|
21
21
|
stopPersistentSession,
|
|
22
22
|
takeZombieDetection,
|
|
23
23
|
writePersistentClaudeWrapper
|
|
24
|
-
} from "./chunk-
|
|
25
|
-
import "./chunk-
|
|
24
|
+
} from "./chunk-5ZUNHYKV.js";
|
|
25
|
+
import "./chunk-HT6EETEL.js";
|
|
26
26
|
import "./chunk-XWVM4KPK.js";
|
|
27
27
|
export {
|
|
28
28
|
SEND_KEYS_ENTER_DELAY_MS,
|
|
@@ -48,4 +48,4 @@ export {
|
|
|
48
48
|
takeZombieDetection,
|
|
49
49
|
writePersistentClaudeWrapper
|
|
50
50
|
};
|
|
51
|
-
//# sourceMappingURL=persistent-session-
|
|
51
|
+
//# sourceMappingURL=persistent-session-N6SYAERB.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
paneLogPath
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-5ZUNHYKV.js";
|
|
4
|
+
import "./chunk-HT6EETEL.js";
|
|
5
5
|
import "./chunk-XWVM4KPK.js";
|
|
6
6
|
|
|
7
7
|
// src/lib/responsiveness-probe.ts
|
|
@@ -30,4 +30,4 @@ export {
|
|
|
30
30
|
collectResponsivenessProbes,
|
|
31
31
|
getResponsivenessIntervalMs
|
|
32
32
|
};
|
|
33
|
-
//# sourceMappingURL=responsiveness-probe-
|
|
33
|
+
//# sourceMappingURL=responsiveness-probe-GPRQBBZG.js.map
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|