@integrity-labs/agt-cli 0.26.2-eng5706.1 → 0.27.0-test.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 +874 -192
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-LBYU24PW.js → chunk-CPZIFISH.js} +22 -8
- package/dist/{chunk-LBYU24PW.js.map → chunk-CPZIFISH.js.map} +1 -1
- package/dist/{chunk-U3HCB23E.js → chunk-CTWY2X4S.js} +41 -8
- package/dist/chunk-CTWY2X4S.js.map +1 -0
- package/dist/{chunk-QSDDP7JN.js → chunk-WDCSMDQ4.js} +52 -8
- package/dist/chunk-WDCSMDQ4.js.map +1 -0
- package/dist/{claude-pair-runtime-2NNAUBP3.js → claude-pair-runtime-YRPKT45R.js} +2 -2
- package/dist/lib/manager-worker.js +7 -7
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +168 -0
- package/dist/mcp/slack-channel.js +158 -19
- package/dist/mcp/telegram-channel.js +212 -40
- package/dist/{persistent-session-K4X76LLB.js → persistent-session-QJT7JE5P.js} +3 -3
- package/dist/{responsiveness-probe-QBV43SJ7.js → responsiveness-probe-ZERSZOZ2.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-QSDDP7JN.js.map +0 -1
- package/dist/chunk-U3HCB23E.js.map +0 -1
- /package/dist/{claude-pair-runtime-2NNAUBP3.js.map → claude-pair-runtime-YRPKT45R.js.map} +0 -0
- /package/dist/{persistent-session-K4X76LLB.js.map → persistent-session-QJT7JE5P.js.map} +0 -0
- /package/dist/{responsiveness-probe-QBV43SJ7.js.map → responsiveness-probe-ZERSZOZ2.js.map} +0 -0
|
@@ -13982,6 +13982,75 @@ function createDirectChatProgressFlush(opts) {
|
|
|
13982
13982
|
};
|
|
13983
13983
|
}
|
|
13984
13984
|
|
|
13985
|
+
// src/inbound-context-client.ts
|
|
13986
|
+
var REQUEST_TIMEOUT_MS = 1e4;
|
|
13987
|
+
function createInboundContextClient(args) {
|
|
13988
|
+
if (!args.agtHost || !args.agtApiKey || !args.agentId) return null;
|
|
13989
|
+
const fetchImpl = args.fetchImpl ?? fetch;
|
|
13990
|
+
const log = args.log ?? (() => {
|
|
13991
|
+
});
|
|
13992
|
+
const base = args.agtHost.replace(/\/+$/, "");
|
|
13993
|
+
const agentId = args.agentId;
|
|
13994
|
+
const apiKey = args.agtApiKey;
|
|
13995
|
+
let cachedToken = null;
|
|
13996
|
+
let cachedTokenExpiresAt = 0;
|
|
13997
|
+
async function getToken() {
|
|
13998
|
+
if (cachedToken && Date.now() < cachedTokenExpiresAt) return cachedToken;
|
|
13999
|
+
const resp = await fetchImpl(`${base}/host/exchange`, {
|
|
14000
|
+
method: "POST",
|
|
14001
|
+
headers: { "Content-Type": "application/json" },
|
|
14002
|
+
body: JSON.stringify({ host_key: apiKey }),
|
|
14003
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
14004
|
+
});
|
|
14005
|
+
if (!resp.ok) {
|
|
14006
|
+
const body = await resp.text().catch(() => "");
|
|
14007
|
+
throw new Error(`/host/exchange failed (${resp.status}): ${body.slice(0, 200)}`);
|
|
14008
|
+
}
|
|
14009
|
+
const data = await resp.json();
|
|
14010
|
+
cachedToken = data.token;
|
|
14011
|
+
cachedTokenExpiresAt = data.expires_at ? new Date(data.expires_at).getTime() - 12e4 : Date.now() + 55 * 6e4;
|
|
14012
|
+
return cachedToken;
|
|
14013
|
+
}
|
|
14014
|
+
async function postOnce(body) {
|
|
14015
|
+
const token = await getToken();
|
|
14016
|
+
return fetchImpl(`${base}/host/inbound-context`, {
|
|
14017
|
+
method: "POST",
|
|
14018
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
14019
|
+
body: JSON.stringify(body),
|
|
14020
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
14021
|
+
});
|
|
14022
|
+
}
|
|
14023
|
+
async function emit(args2) {
|
|
14024
|
+
const body = {
|
|
14025
|
+
agent_id: agentId,
|
|
14026
|
+
source_integration: args2.sourceIntegration,
|
|
14027
|
+
source_external_id: args2.sourceExternalId,
|
|
14028
|
+
...args2.sourceUrl ? { source_url: args2.sourceUrl } : {}
|
|
14029
|
+
};
|
|
14030
|
+
try {
|
|
14031
|
+
let resp = await postOnce(body);
|
|
14032
|
+
if (resp.status === 401) {
|
|
14033
|
+
cachedToken = null;
|
|
14034
|
+
cachedTokenExpiresAt = 0;
|
|
14035
|
+
resp = await postOnce(body);
|
|
14036
|
+
}
|
|
14037
|
+
if (!resp.ok) {
|
|
14038
|
+
const text = await resp.text().catch(() => "");
|
|
14039
|
+
log(
|
|
14040
|
+
`inbound-context: POST failed (${resp.status}) integration=${args2.sourceIntegration}: ${text.slice(0, 200)}`
|
|
14041
|
+
);
|
|
14042
|
+
}
|
|
14043
|
+
} catch (err) {
|
|
14044
|
+
log(`inbound-context: emit threw integration=${args2.sourceIntegration}: ${err.message}`);
|
|
14045
|
+
}
|
|
14046
|
+
}
|
|
14047
|
+
return {
|
|
14048
|
+
recordInbound(args2) {
|
|
14049
|
+
void emit(args2);
|
|
14050
|
+
}
|
|
14051
|
+
};
|
|
14052
|
+
}
|
|
14053
|
+
|
|
13985
14054
|
// src/progress-tools.ts
|
|
13986
14055
|
import { randomUUID } from "crypto";
|
|
13987
14056
|
|
|
@@ -14299,10 +14368,89 @@ function isMode(value) {
|
|
|
14299
14368
|
return value === "thinking" || value === "working" || value === "waiting";
|
|
14300
14369
|
}
|
|
14301
14370
|
|
|
14371
|
+
// src/mcp-spawn-lock.ts
|
|
14372
|
+
import {
|
|
14373
|
+
existsSync,
|
|
14374
|
+
mkdirSync,
|
|
14375
|
+
readFileSync,
|
|
14376
|
+
renameSync,
|
|
14377
|
+
unlinkSync,
|
|
14378
|
+
writeFileSync
|
|
14379
|
+
} from "fs";
|
|
14380
|
+
import { join } from "path";
|
|
14381
|
+
function defaultIsPidAlive(pid) {
|
|
14382
|
+
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
14383
|
+
try {
|
|
14384
|
+
process.kill(pid, 0);
|
|
14385
|
+
return true;
|
|
14386
|
+
} catch (err) {
|
|
14387
|
+
const code = err.code;
|
|
14388
|
+
if (code === "ESRCH") return false;
|
|
14389
|
+
return true;
|
|
14390
|
+
}
|
|
14391
|
+
}
|
|
14392
|
+
function acquireMcpSpawnLock(args) {
|
|
14393
|
+
const { agentDir, basename, options = {} } = args;
|
|
14394
|
+
if (!agentDir) return { kind: "no-agent-dir" };
|
|
14395
|
+
const isPidAlive = options.isPidAlive ?? defaultIsPidAlive;
|
|
14396
|
+
const selfPid = options.selfPid ?? process.pid;
|
|
14397
|
+
const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
14398
|
+
const path = join(agentDir, basename);
|
|
14399
|
+
const existing = readLockHolder(path);
|
|
14400
|
+
if (existing) {
|
|
14401
|
+
if (existing.pid === selfPid) {
|
|
14402
|
+
return { kind: "acquired", path };
|
|
14403
|
+
}
|
|
14404
|
+
if (isPidAlive(existing.pid)) {
|
|
14405
|
+
return { kind: "blocked", path, holder: existing };
|
|
14406
|
+
}
|
|
14407
|
+
}
|
|
14408
|
+
mkdirSync(agentDir, { recursive: true, mode: 448 });
|
|
14409
|
+
const tmpPath = `${path}.${selfPid}.tmp`;
|
|
14410
|
+
const payload = { pid: selfPid, started_at: now() };
|
|
14411
|
+
writeFileSync(tmpPath, JSON.stringify(payload), { mode: 384 });
|
|
14412
|
+
renameSync(tmpPath, path);
|
|
14413
|
+
return { kind: "acquired", path };
|
|
14414
|
+
}
|
|
14415
|
+
function releaseMcpSpawnLock(lockPath, opts = {}) {
|
|
14416
|
+
if (!lockPath) return;
|
|
14417
|
+
const selfPid = opts.selfPid ?? process.pid;
|
|
14418
|
+
const existing = readLockHolder(lockPath);
|
|
14419
|
+
if (!existing) return;
|
|
14420
|
+
if (existing.pid !== selfPid) return;
|
|
14421
|
+
try {
|
|
14422
|
+
unlinkSync(lockPath);
|
|
14423
|
+
} catch {
|
|
14424
|
+
}
|
|
14425
|
+
}
|
|
14426
|
+
function readLockHolder(path) {
|
|
14427
|
+
if (!existsSync(path)) return null;
|
|
14428
|
+
try {
|
|
14429
|
+
const raw = readFileSync(path, "utf8");
|
|
14430
|
+
const parsed = JSON.parse(raw);
|
|
14431
|
+
const pid = typeof parsed.pid === "number" ? parsed.pid : Number(parsed.pid);
|
|
14432
|
+
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
14433
|
+
const startedAt = typeof parsed.started_at === "string" ? parsed.started_at : "";
|
|
14434
|
+
return { pid, started_at: startedAt };
|
|
14435
|
+
} catch {
|
|
14436
|
+
return null;
|
|
14437
|
+
}
|
|
14438
|
+
}
|
|
14439
|
+
|
|
14302
14440
|
// src/direct-chat-channel.ts
|
|
14441
|
+
import { homedir } from "os";
|
|
14442
|
+
import { join as join2 } from "path";
|
|
14303
14443
|
var AGT_HOST = process.env.AGT_HOST;
|
|
14304
14444
|
var AGT_API_KEY = process.env.AGT_API_KEY;
|
|
14305
14445
|
var AGT_AGENT_ID = process.env.AGT_AGENT_ID;
|
|
14446
|
+
var DIRECT_CHAT_AGENT_DIR = AGT_AGENT_ID ? join2(homedir(), ".augmented", AGT_AGENT_ID) : null;
|
|
14447
|
+
var inboundContextClient = createInboundContextClient({
|
|
14448
|
+
agtHost: AGT_HOST ?? null,
|
|
14449
|
+
agtApiKey: AGT_API_KEY ?? null,
|
|
14450
|
+
agentId: AGT_AGENT_ID ?? null,
|
|
14451
|
+
log: (line) => process.stderr.write(`direct-chat-channel: ${line}
|
|
14452
|
+
`)
|
|
14453
|
+
});
|
|
14306
14454
|
if (!AGT_HOST || !AGT_API_KEY || !AGT_AGENT_ID) {
|
|
14307
14455
|
process.stderr.write(
|
|
14308
14456
|
"direct-chat-channel: Missing AGT_HOST, AGT_API_KEY, or AGT_AGENT_ID. Cannot start.\n"
|
|
@@ -14488,6 +14636,22 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
14488
14636
|
throw new Error(`Unknown tool: ${name}`);
|
|
14489
14637
|
});
|
|
14490
14638
|
await mcp.connect(new StdioServerTransport());
|
|
14639
|
+
var acquiredLockPath = null;
|
|
14640
|
+
{
|
|
14641
|
+
const lockResult = acquireMcpSpawnLock({
|
|
14642
|
+
agentDir: DIRECT_CHAT_AGENT_DIR,
|
|
14643
|
+
basename: "direct-chat-channel.lock"
|
|
14644
|
+
});
|
|
14645
|
+
if (lockResult.kind === "blocked") {
|
|
14646
|
+
process.stderr.write(
|
|
14647
|
+
`direct-chat-channel: another instance pid=${lockResult.holder.pid} already running (since ${lockResult.holder.started_at}), exiting
|
|
14648
|
+
`
|
|
14649
|
+
);
|
|
14650
|
+
process.exit(0);
|
|
14651
|
+
} else if (lockResult.kind === "acquired") {
|
|
14652
|
+
acquiredLockPath = lockResult.path;
|
|
14653
|
+
}
|
|
14654
|
+
}
|
|
14491
14655
|
process.stderr.write(
|
|
14492
14656
|
`direct-chat-channel: Started (agent=${AGT_AGENT_ID}, polling=disabled \u2014 using Realtime)
|
|
14493
14657
|
`
|
|
@@ -14498,6 +14662,10 @@ function shutdown(reason) {
|
|
|
14498
14662
|
isShuttingDown = true;
|
|
14499
14663
|
process.stderr.write(`direct-chat-channel: ${reason} \u2014 exiting
|
|
14500
14664
|
`);
|
|
14665
|
+
try {
|
|
14666
|
+
releaseMcpSpawnLock(acquiredLockPath);
|
|
14667
|
+
} catch {
|
|
14668
|
+
}
|
|
14501
14669
|
setTimeout(() => process.exit(0), 100).unref();
|
|
14502
14670
|
}
|
|
14503
14671
|
process.stdin.on("close", () => shutdown("stdin closed"));
|
|
@@ -14230,6 +14230,24 @@ function decideSlackEngagement(input) {
|
|
|
14230
14230
|
function decideSlackAckReaction(input) {
|
|
14231
14231
|
return Boolean(input.channel && input.ts);
|
|
14232
14232
|
}
|
|
14233
|
+
function extractAugmentedSlackLabel(evt) {
|
|
14234
|
+
if (evt.metadata?.event_type !== "augmented_agent_message") return null;
|
|
14235
|
+
return {
|
|
14236
|
+
teamId: evt.metadata.event_payload?.["augmented_team_id"],
|
|
14237
|
+
agentId: evt.metadata.event_payload?.["augmented_agent_id"]
|
|
14238
|
+
};
|
|
14239
|
+
}
|
|
14240
|
+
function decideSenderPolicyForward(evt, policy) {
|
|
14241
|
+
if (policy.mode === "all") return { forward: true };
|
|
14242
|
+
const label = extractAugmentedSlackLabel(evt);
|
|
14243
|
+
if (!label) return { forward: false, reason: "sender_policy" };
|
|
14244
|
+
if (policy.mode === "team_agents_only") {
|
|
14245
|
+
if (!policy.teamId || label.teamId !== policy.teamId) {
|
|
14246
|
+
return { forward: false, reason: "sender_policy" };
|
|
14247
|
+
}
|
|
14248
|
+
}
|
|
14249
|
+
return { forward: true };
|
|
14250
|
+
}
|
|
14233
14251
|
|
|
14234
14252
|
// src/slack-loop-throttle.ts
|
|
14235
14253
|
var DEFAULT_THROTTLE = {
|
|
@@ -15495,8 +15513,77 @@ function createConversationIngestClient(args) {
|
|
|
15495
15513
|
};
|
|
15496
15514
|
}
|
|
15497
15515
|
|
|
15498
|
-
// src/
|
|
15516
|
+
// src/inbound-context-client.ts
|
|
15499
15517
|
var REQUEST_TIMEOUT_MS3 = 1e4;
|
|
15518
|
+
function createInboundContextClient(args) {
|
|
15519
|
+
if (!args.agtHost || !args.agtApiKey || !args.agentId) return null;
|
|
15520
|
+
const fetchImpl = args.fetchImpl ?? fetch;
|
|
15521
|
+
const log = args.log ?? (() => {
|
|
15522
|
+
});
|
|
15523
|
+
const base = args.agtHost.replace(/\/+$/, "");
|
|
15524
|
+
const agentId = args.agentId;
|
|
15525
|
+
const apiKey = args.agtApiKey;
|
|
15526
|
+
let cachedToken = null;
|
|
15527
|
+
let cachedTokenExpiresAt = 0;
|
|
15528
|
+
async function getToken() {
|
|
15529
|
+
if (cachedToken && Date.now() < cachedTokenExpiresAt) return cachedToken;
|
|
15530
|
+
const resp = await fetchImpl(`${base}/host/exchange`, {
|
|
15531
|
+
method: "POST",
|
|
15532
|
+
headers: { "Content-Type": "application/json" },
|
|
15533
|
+
body: JSON.stringify({ host_key: apiKey }),
|
|
15534
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS3)
|
|
15535
|
+
});
|
|
15536
|
+
if (!resp.ok) {
|
|
15537
|
+
const body = await resp.text().catch(() => "");
|
|
15538
|
+
throw new Error(`/host/exchange failed (${resp.status}): ${body.slice(0, 200)}`);
|
|
15539
|
+
}
|
|
15540
|
+
const data = await resp.json();
|
|
15541
|
+
cachedToken = data.token;
|
|
15542
|
+
cachedTokenExpiresAt = data.expires_at ? new Date(data.expires_at).getTime() - 12e4 : Date.now() + 55 * 6e4;
|
|
15543
|
+
return cachedToken;
|
|
15544
|
+
}
|
|
15545
|
+
async function postOnce(body) {
|
|
15546
|
+
const token = await getToken();
|
|
15547
|
+
return fetchImpl(`${base}/host/inbound-context`, {
|
|
15548
|
+
method: "POST",
|
|
15549
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
15550
|
+
body: JSON.stringify(body),
|
|
15551
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS3)
|
|
15552
|
+
});
|
|
15553
|
+
}
|
|
15554
|
+
async function emit(args2) {
|
|
15555
|
+
const body = {
|
|
15556
|
+
agent_id: agentId,
|
|
15557
|
+
source_integration: args2.sourceIntegration,
|
|
15558
|
+
source_external_id: args2.sourceExternalId,
|
|
15559
|
+
...args2.sourceUrl ? { source_url: args2.sourceUrl } : {}
|
|
15560
|
+
};
|
|
15561
|
+
try {
|
|
15562
|
+
let resp = await postOnce(body);
|
|
15563
|
+
if (resp.status === 401) {
|
|
15564
|
+
cachedToken = null;
|
|
15565
|
+
cachedTokenExpiresAt = 0;
|
|
15566
|
+
resp = await postOnce(body);
|
|
15567
|
+
}
|
|
15568
|
+
if (!resp.ok) {
|
|
15569
|
+
const text = await resp.text().catch(() => "");
|
|
15570
|
+
log(
|
|
15571
|
+
`inbound-context: POST failed (${resp.status}) integration=${args2.sourceIntegration}: ${text.slice(0, 200)}`
|
|
15572
|
+
);
|
|
15573
|
+
}
|
|
15574
|
+
} catch (err) {
|
|
15575
|
+
log(`inbound-context: emit threw integration=${args2.sourceIntegration}: ${err.message}`);
|
|
15576
|
+
}
|
|
15577
|
+
}
|
|
15578
|
+
return {
|
|
15579
|
+
recordInbound(args2) {
|
|
15580
|
+
void emit(args2);
|
|
15581
|
+
}
|
|
15582
|
+
};
|
|
15583
|
+
}
|
|
15584
|
+
|
|
15585
|
+
// src/slack-bot-user-id-client.ts
|
|
15586
|
+
var REQUEST_TIMEOUT_MS4 = 1e4;
|
|
15500
15587
|
function createSlackBotUserIdClient(args) {
|
|
15501
15588
|
if (!args.agtHost || !args.agtApiKey || !args.agentId) return null;
|
|
15502
15589
|
const fetchImpl = args.fetchImpl ?? fetch;
|
|
@@ -15514,7 +15601,7 @@ function createSlackBotUserIdClient(args) {
|
|
|
15514
15601
|
method: "POST",
|
|
15515
15602
|
headers: { "Content-Type": "application/json" },
|
|
15516
15603
|
body: JSON.stringify({ host_key: apiKey }),
|
|
15517
|
-
signal: AbortSignal.timeout(
|
|
15604
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS4)
|
|
15518
15605
|
});
|
|
15519
15606
|
if (!resp.ok) {
|
|
15520
15607
|
const body = await resp.text().catch(() => "");
|
|
@@ -15531,7 +15618,7 @@ function createSlackBotUserIdClient(args) {
|
|
|
15531
15618
|
method: "POST",
|
|
15532
15619
|
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
15533
15620
|
body: JSON.stringify({ agent_id: agentId, bot_user_id: botUserId2 }),
|
|
15534
|
-
signal: AbortSignal.timeout(
|
|
15621
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS4)
|
|
15535
15622
|
});
|
|
15536
15623
|
}
|
|
15537
15624
|
async function emitAsync(botUserId2) {
|
|
@@ -15563,7 +15650,7 @@ function createSlackBotUserIdClient(args) {
|
|
|
15563
15650
|
method: "POST",
|
|
15564
15651
|
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
15565
15652
|
body: JSON.stringify({ agent_id: agentId, channel_id: "slack", healthy }),
|
|
15566
|
-
signal: AbortSignal.timeout(
|
|
15653
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS4)
|
|
15567
15654
|
});
|
|
15568
15655
|
};
|
|
15569
15656
|
try {
|
|
@@ -15607,7 +15694,7 @@ function createSlackBotUserIdClient(args) {
|
|
|
15607
15694
|
};
|
|
15608
15695
|
}
|
|
15609
15696
|
|
|
15610
|
-
// src/
|
|
15697
|
+
// src/mcp-spawn-lock.ts
|
|
15611
15698
|
import {
|
|
15612
15699
|
existsSync,
|
|
15613
15700
|
mkdirSync as mkdirSync2,
|
|
@@ -15617,7 +15704,6 @@ import {
|
|
|
15617
15704
|
writeFileSync as writeFileSync2
|
|
15618
15705
|
} from "fs";
|
|
15619
15706
|
import { join as join2 } from "path";
|
|
15620
|
-
var DEFAULT_LOCK_BASENAME = "slack-channel.lock";
|
|
15621
15707
|
function defaultIsPidAlive(pid) {
|
|
15622
15708
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
15623
15709
|
try {
|
|
@@ -15629,12 +15715,13 @@ function defaultIsPidAlive(pid) {
|
|
|
15629
15715
|
return true;
|
|
15630
15716
|
}
|
|
15631
15717
|
}
|
|
15632
|
-
function
|
|
15633
|
-
|
|
15634
|
-
|
|
15635
|
-
const
|
|
15636
|
-
const
|
|
15637
|
-
const
|
|
15718
|
+
function acquireMcpSpawnLock(args) {
|
|
15719
|
+
const { agentDir, basename: basename2, options = {} } = args;
|
|
15720
|
+
if (!agentDir) return { kind: "no-agent-dir" };
|
|
15721
|
+
const isPidAlive = options.isPidAlive ?? defaultIsPidAlive;
|
|
15722
|
+
const selfPid = options.selfPid ?? process.pid;
|
|
15723
|
+
const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
15724
|
+
const path = join2(agentDir, basename2);
|
|
15638
15725
|
const existing = readLockHolder(path);
|
|
15639
15726
|
if (existing) {
|
|
15640
15727
|
if (existing.pid === selfPid) {
|
|
@@ -15644,14 +15731,14 @@ function acquireSlackSpawnLock(slackAgentDir, opts = {}) {
|
|
|
15644
15731
|
return { kind: "blocked", path, holder: existing };
|
|
15645
15732
|
}
|
|
15646
15733
|
}
|
|
15647
|
-
mkdirSync2(
|
|
15734
|
+
mkdirSync2(agentDir, { recursive: true, mode: 448 });
|
|
15648
15735
|
const tmpPath = `${path}.${selfPid}.tmp`;
|
|
15649
15736
|
const payload = { pid: selfPid, started_at: now() };
|
|
15650
15737
|
writeFileSync2(tmpPath, JSON.stringify(payload), { mode: 384 });
|
|
15651
15738
|
renameSync(tmpPath, path);
|
|
15652
15739
|
return { kind: "acquired", path };
|
|
15653
15740
|
}
|
|
15654
|
-
function
|
|
15741
|
+
function releaseMcpSpawnLock(lockPath, opts = {}) {
|
|
15655
15742
|
if (!lockPath) return;
|
|
15656
15743
|
const selfPid = opts.selfPid ?? process.pid;
|
|
15657
15744
|
const existing = readLockHolder(lockPath);
|
|
@@ -15683,6 +15770,19 @@ var AGENT_CODE_NAME = process.env.AGT_AGENT_CODE_NAME ?? null;
|
|
|
15683
15770
|
var AGT_HOST = process.env.AGT_HOST ?? null;
|
|
15684
15771
|
var AGT_API_KEY = process.env.AGT_API_KEY ?? null;
|
|
15685
15772
|
var AGT_AGENT_ID = process.env.AGT_AGENT_ID ?? null;
|
|
15773
|
+
var AGT_TEAM_ID = process.env.AGT_TEAM_ID ?? null;
|
|
15774
|
+
var SLACK_SENDER_POLICY = (() => {
|
|
15775
|
+
const raw = (process.env.SLACK_SENDER_POLICY ?? "all").trim().toLowerCase();
|
|
15776
|
+
if (raw === "all") return { mode: "all" };
|
|
15777
|
+
if (raw === "agents_only") return { mode: "agents_only" };
|
|
15778
|
+
if (raw === "team_agents_only") {
|
|
15779
|
+
if (!AGT_TEAM_ID) {
|
|
15780
|
+
throw new Error("SLACK_SENDER_POLICY=team_agents_only requires AGT_TEAM_ID");
|
|
15781
|
+
}
|
|
15782
|
+
return { mode: "team_agents_only", teamId: AGT_TEAM_ID };
|
|
15783
|
+
}
|
|
15784
|
+
throw new Error(`Invalid SLACK_SENDER_POLICY=${JSON.stringify(process.env.SLACK_SENDER_POLICY)}`);
|
|
15785
|
+
})();
|
|
15686
15786
|
var BLOCK_KIT_ENABLED = process.env.SLACK_BLOCK_KIT_ENABLED === "true";
|
|
15687
15787
|
var BLOCK_KIT_ASK_USER_ENABLED = process.env.SLACK_BLOCK_KIT_ASK_USER_ENABLED === "true";
|
|
15688
15788
|
var BLOCK_KIT_DISABLED = process.env.SLACK_BLOCK_KIT_DISABLED === "true";
|
|
@@ -15721,6 +15821,13 @@ var conversationIngestClient = createConversationIngestClient({
|
|
|
15721
15821
|
log: (line) => process.stderr.write(`slack-channel: ${line}
|
|
15722
15822
|
`)
|
|
15723
15823
|
});
|
|
15824
|
+
var inboundContextClient = createInboundContextClient({
|
|
15825
|
+
agtHost: AGT_HOST,
|
|
15826
|
+
agtApiKey: AGT_API_KEY,
|
|
15827
|
+
agentId: AGT_AGENT_ID,
|
|
15828
|
+
log: (line) => process.stderr.write(`slack-channel: ${line}
|
|
15829
|
+
`)
|
|
15830
|
+
});
|
|
15724
15831
|
var SLACK_PEER_CLASSIFIER_CONFIG = {
|
|
15725
15832
|
peer_agent_mode: parsePeerAgentModeEnv(process.env.SLACK_PEER_AGENT_MODE),
|
|
15726
15833
|
peer_group_ids: parsePeerGroupIdsEnv(process.env.SLACK_PEER_GROUP_IDS),
|
|
@@ -16049,6 +16156,16 @@ function noteThreadActivityByMessageTs(channel, messageTs) {
|
|
|
16049
16156
|
}
|
|
16050
16157
|
}
|
|
16051
16158
|
var RESTART_FLAGS_DIR = join3(homedir2(), ".augmented", "restart-flags");
|
|
16159
|
+
function buildAugmentedSlackMetadata() {
|
|
16160
|
+
if (!AGT_TEAM_ID) return void 0;
|
|
16161
|
+
return {
|
|
16162
|
+
event_type: "augmented_agent_message",
|
|
16163
|
+
event_payload: {
|
|
16164
|
+
augmented_team_id: AGT_TEAM_ID,
|
|
16165
|
+
...AGT_AGENT_ID ? { augmented_agent_id: AGT_AGENT_ID } : {}
|
|
16166
|
+
}
|
|
16167
|
+
};
|
|
16168
|
+
}
|
|
16052
16169
|
function hashChannelId(id) {
|
|
16053
16170
|
return createHash("sha256").update(id).digest("hex").slice(0, 8);
|
|
16054
16171
|
}
|
|
@@ -16056,6 +16173,8 @@ function hashId(id) {
|
|
|
16056
16173
|
return createHash("sha256").update(id).digest("hex").slice(0, 8);
|
|
16057
16174
|
}
|
|
16058
16175
|
async function postSlackMessage(body) {
|
|
16176
|
+
const augmentedMeta = buildAugmentedSlackMetadata();
|
|
16177
|
+
const bodyWithLabel = augmentedMeta ? { ...body, metadata: augmentedMeta } : body;
|
|
16059
16178
|
try {
|
|
16060
16179
|
const res = await fetch("https://slack.com/api/chat.postMessage", {
|
|
16061
16180
|
method: "POST",
|
|
@@ -16063,7 +16182,7 @@ async function postSlackMessage(body) {
|
|
|
16063
16182
|
"Content-Type": "application/json; charset=utf-8",
|
|
16064
16183
|
Authorization: `Bearer ${BOT_TOKEN}`
|
|
16065
16184
|
},
|
|
16066
|
-
body: JSON.stringify(
|
|
16185
|
+
body: JSON.stringify(bodyWithLabel),
|
|
16067
16186
|
// Hard deadline so a hung Slack API can't stall the live Socket Mode
|
|
16068
16187
|
// event loop or the manager's restart ack path. Matches the timeout
|
|
16069
16188
|
// used elsewhere in this file for chat.postMessage.
|
|
@@ -16865,7 +16984,10 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
16865
16984
|
body: JSON.stringify({
|
|
16866
16985
|
channel,
|
|
16867
16986
|
text,
|
|
16868
|
-
...thread_ts ? { thread_ts } : {}
|
|
16987
|
+
...thread_ts ? { thread_ts } : {},
|
|
16988
|
+
...buildAugmentedSlackMetadata() ? { metadata: buildAugmentedSlackMetadata() } : {}
|
|
16989
|
+
// ↑ Labels this message as Augmented-agent-originated so peer agents
|
|
16990
|
+
// enforcing sender_policy=team_agents_only can verify the sender.
|
|
16869
16991
|
})
|
|
16870
16992
|
});
|
|
16871
16993
|
const data = await res.json();
|
|
@@ -17289,6 +17411,8 @@ function forwardingHostAvailable() {
|
|
|
17289
17411
|
return Boolean(AGT_HOST && AGT_API_KEY && AGT_AGENT_ID);
|
|
17290
17412
|
}
|
|
17291
17413
|
async function postSlackMessageWithTs(payload) {
|
|
17414
|
+
const augmentedMeta = buildAugmentedSlackMetadata();
|
|
17415
|
+
const payloadWithLabel = augmentedMeta ? { ...payload, metadata: augmentedMeta } : payload;
|
|
17292
17416
|
try {
|
|
17293
17417
|
const res = await fetch("https://slack.com/api/chat.postMessage", {
|
|
17294
17418
|
method: "POST",
|
|
@@ -17296,7 +17420,7 @@ async function postSlackMessageWithTs(payload) {
|
|
|
17296
17420
|
"Content-Type": "application/json; charset=utf-8",
|
|
17297
17421
|
Authorization: `Bearer ${BOT_TOKEN}`
|
|
17298
17422
|
},
|
|
17299
|
-
body: JSON.stringify(
|
|
17423
|
+
body: JSON.stringify(payloadWithLabel),
|
|
17300
17424
|
signal: AbortSignal.timeout(SLACK_DOWNLOAD_TIMEOUT_MS)
|
|
17301
17425
|
});
|
|
17302
17426
|
const data = await res.json();
|
|
@@ -17920,6 +18044,12 @@ async function connectSocketMode() {
|
|
|
17920
18044
|
const filterDecision = decideSlackMessageForward(evt);
|
|
17921
18045
|
if (!filterDecision.forward) {
|
|
17922
18046
|
process.stderr.write(`slack-channel: dropped message event (reason=${filterDecision.reason}, subtype=${evt.subtype ?? "none"}, ts=${evt.ts ?? "n/a"})
|
|
18047
|
+
`);
|
|
18048
|
+
return;
|
|
18049
|
+
}
|
|
18050
|
+
const senderPolicyDecision = decideSenderPolicyForward(evt, SLACK_SENDER_POLICY);
|
|
18051
|
+
if (!senderPolicyDecision.forward) {
|
|
18052
|
+
process.stderr.write(`slack-channel: dropped message event (reason=sender_policy, mode=${SLACK_SENDER_POLICY.mode}, ts=${evt.ts ?? "n/a"})
|
|
17923
18053
|
`);
|
|
17924
18054
|
return;
|
|
17925
18055
|
}
|
|
@@ -18094,6 +18224,12 @@ async function connectSocketMode() {
|
|
|
18094
18224
|
is_bot: isFromBot,
|
|
18095
18225
|
bot_id: evt.bot_id ?? null
|
|
18096
18226
|
});
|
|
18227
|
+
if (!isFromBot && threadTs) {
|
|
18228
|
+
inboundContextClient?.recordInbound({
|
|
18229
|
+
sourceIntegration: "slack",
|
|
18230
|
+
sourceExternalId: `${channel}:${threadTs}`
|
|
18231
|
+
});
|
|
18232
|
+
}
|
|
18097
18233
|
}
|
|
18098
18234
|
} catch (err) {
|
|
18099
18235
|
process.stderr.write(`slack-channel: Event error: ${err.message}
|
|
@@ -18133,7 +18269,7 @@ function shutdown(reason, exitCode = 0) {
|
|
|
18133
18269
|
} catch {
|
|
18134
18270
|
}
|
|
18135
18271
|
try {
|
|
18136
|
-
|
|
18272
|
+
releaseMcpSpawnLock(acquiredLockPath);
|
|
18137
18273
|
} catch {
|
|
18138
18274
|
}
|
|
18139
18275
|
setTimeout(() => process.exit(exitCode), 500).unref();
|
|
@@ -18149,7 +18285,10 @@ process.on("unhandledRejection", (reason) => {
|
|
|
18149
18285
|
`);
|
|
18150
18286
|
});
|
|
18151
18287
|
{
|
|
18152
|
-
const lockResult =
|
|
18288
|
+
const lockResult = acquireMcpSpawnLock({
|
|
18289
|
+
agentDir: SLACK_AGENT_DIR,
|
|
18290
|
+
basename: "slack-channel.lock"
|
|
18291
|
+
});
|
|
18153
18292
|
if (lockResult.kind === "blocked") {
|
|
18154
18293
|
process.stderr.write(
|
|
18155
18294
|
`slack-channel: another instance pid=${lockResult.holder.pid} already running (since ${lockResult.holder.started_at}), exiting
|