@integrity-labs/agt-cli 0.28.570 → 0.28.571
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-6XCGZUSS.js → chunk-72K46XUZ.js} +3 -3
- package/dist/{chunk-6XCGZUSS.js.map → chunk-72K46XUZ.js.map} +1 -1
- package/dist/{chunk-LNLLMDJJ.js → chunk-KXUYJUGI.js} +3 -3
- package/dist/{claude-pair-runtime-NSIF6AYH.js → claude-pair-runtime-XTRJNDP2.js} +2 -2
- package/dist/lib/manager-worker.js +10 -10
- package/dist/mcp/direct-chat-channel.js +2 -2
- package/dist/mcp/origami.js +2 -2
- package/dist/mcp/slack-channel.js +63 -9
- package/dist/mcp/telegram-channel.js +2 -2
- package/dist/{persistent-session-HY6GUPBQ.js → persistent-session-74MH2XTM.js} +2 -2
- package/dist/{responsiveness-probe-6EEZKJVV.js → responsiveness-probe-5VNQQZNJ.js} +2 -2
- package/package.json +1 -1
- /package/dist/{chunk-LNLLMDJJ.js.map → chunk-KXUYJUGI.js.map} +0 -0
- /package/dist/{claude-pair-runtime-NSIF6AYH.js.map → claude-pair-runtime-XTRJNDP2.js.map} +0 -0
- /package/dist/{persistent-session-HY6GUPBQ.js.map → persistent-session-74MH2XTM.js.map} +0 -0
- /package/dist/{responsiveness-probe-6EEZKJVV.js.map → responsiveness-probe-5VNQQZNJ.js.map} +0 -0
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
resolveConnectivityProbe,
|
|
47
47
|
worseConnectivityOutcome,
|
|
48
48
|
wrapScheduledTaskPrompt
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-72K46XUZ.js";
|
|
50
50
|
import {
|
|
51
51
|
parsePsRows
|
|
52
52
|
} from "./chunk-XWVM4KPK.js";
|
|
@@ -5646,7 +5646,7 @@ function exchangeFailureKind(err) {
|
|
|
5646
5646
|
}
|
|
5647
5647
|
|
|
5648
5648
|
// src/lib/api-client.ts
|
|
5649
|
-
var agtCliVersion = true ? "0.28.
|
|
5649
|
+
var agtCliVersion = true ? "0.28.571" : "dev";
|
|
5650
5650
|
var lastConfigHash = null;
|
|
5651
5651
|
function setConfigHash(hash) {
|
|
5652
5652
|
lastConfigHash = hash && hash.length > 0 ? hash : null;
|
|
@@ -9011,4 +9011,4 @@ export {
|
|
|
9011
9011
|
managerInstallSystemUnitCommand,
|
|
9012
9012
|
managerUninstallSystemUnitCommand
|
|
9013
9013
|
};
|
|
9014
|
-
//# sourceMappingURL=chunk-
|
|
9014
|
+
//# sourceMappingURL=chunk-KXUYJUGI.js.map
|
|
@@ -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-74MH2XTM.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-XTRJNDP2.js.map
|
|
@@ -53,7 +53,7 @@ import {
|
|
|
53
53
|
safeWriteJsonAtomic,
|
|
54
54
|
setConfigHash,
|
|
55
55
|
tripClass
|
|
56
|
-
} from "../chunk-
|
|
56
|
+
} from "../chunk-KXUYJUGI.js";
|
|
57
57
|
import {
|
|
58
58
|
getProjectDir as getProjectDir2,
|
|
59
59
|
getReadyTasks,
|
|
@@ -182,7 +182,7 @@ import {
|
|
|
182
182
|
toOpencodeModel,
|
|
183
183
|
transcriptActivityAgeSeconds,
|
|
184
184
|
writeEgressAllowlist
|
|
185
|
-
} from "../chunk-
|
|
185
|
+
} from "../chunk-72K46XUZ.js";
|
|
186
186
|
import {
|
|
187
187
|
reapOrphanChannelMcps
|
|
188
188
|
} from "../chunk-XWVM4KPK.js";
|
|
@@ -11527,7 +11527,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
11527
11527
|
var lastVersionCheckAt = 0;
|
|
11528
11528
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
11529
11529
|
var lastResponsivenessProbeAt = 0;
|
|
11530
|
-
var agtCliVersion = true ? "0.28.
|
|
11530
|
+
var agtCliVersion = true ? "0.28.571" : "dev";
|
|
11531
11531
|
function resolveBrewPath(execFileSync2) {
|
|
11532
11532
|
try {
|
|
11533
11533
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -12834,7 +12834,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
12834
12834
|
if (codeNames.length === 0) return;
|
|
12835
12835
|
void (async () => {
|
|
12836
12836
|
try {
|
|
12837
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
12837
|
+
const { collectDiagnostics } = await import("../persistent-session-74MH2XTM.js");
|
|
12838
12838
|
await api.post("/host/heartbeat", {
|
|
12839
12839
|
host_id: hostId,
|
|
12840
12840
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics)
|
|
@@ -12942,7 +12942,7 @@ async function pollCycle() {
|
|
|
12942
12942
|
}
|
|
12943
12943
|
try {
|
|
12944
12944
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
12945
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
12945
|
+
const { collectDiagnostics } = await import("../persistent-session-74MH2XTM.js");
|
|
12946
12946
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
12947
12947
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics) : void 0;
|
|
12948
12948
|
let tailscaleHostname;
|
|
@@ -13065,7 +13065,7 @@ async function pollCycle() {
|
|
|
13065
13065
|
collectPanelessActivityProbes,
|
|
13066
13066
|
getResponsivenessIntervalMs,
|
|
13067
13067
|
occupancyQualificationClassifications
|
|
13068
|
-
} = await import("../responsiveness-probe-
|
|
13068
|
+
} = await import("../responsiveness-probe-5VNQQZNJ.js");
|
|
13069
13069
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
13070
13070
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
13071
13071
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -13156,7 +13156,7 @@ async function pollCycle() {
|
|
|
13156
13156
|
collectResponsivenessProbes,
|
|
13157
13157
|
livePendingInboundOldestAgeSeconds,
|
|
13158
13158
|
parkPendingInbound
|
|
13159
|
-
} = await import("../responsiveness-probe-
|
|
13159
|
+
} = await import("../responsiveness-probe-5VNQQZNJ.js");
|
|
13160
13160
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
13161
13161
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
13162
13162
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -16715,7 +16715,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
16715
16715
|
void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
|
|
16716
16716
|
void (async () => {
|
|
16717
16717
|
try {
|
|
16718
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
16718
|
+
const { collectDiagnostics } = await import("../persistent-session-74MH2XTM.js");
|
|
16719
16719
|
await api.post("/host/heartbeat", {
|
|
16720
16720
|
host_id: hostId,
|
|
16721
16721
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics)
|
|
@@ -16766,7 +16766,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
16766
16766
|
}
|
|
16767
16767
|
try {
|
|
16768
16768
|
const hostId = await getHostId();
|
|
16769
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
16769
|
+
const { collectDiagnostics } = await import("../persistent-session-74MH2XTM.js");
|
|
16770
16770
|
await api.post("/host/heartbeat", {
|
|
16771
16771
|
host_id: hostId,
|
|
16772
16772
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics)
|
|
@@ -17344,7 +17344,7 @@ async function processClaudePairSessions(agents) {
|
|
|
17344
17344
|
killPairSession,
|
|
17345
17345
|
pairTmuxSession,
|
|
17346
17346
|
finalizeClaudePairOnboarding
|
|
17347
|
-
} = await import("../claude-pair-runtime-
|
|
17347
|
+
} = await import("../claude-pair-runtime-XTRJNDP2.js");
|
|
17348
17348
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
17349
17349
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
17350
17350
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -35721,9 +35721,9 @@ var FLAG_REGISTRY = [
|
|
|
35721
35721
|
},
|
|
35722
35722
|
{
|
|
35723
35723
|
key: "notify-dispatch",
|
|
35724
|
-
description:
|
|
35724
|
+
description: `Membership-based channel-notify dispatch (ENG-7682 / notify Slice 1). off = today's behaviour: a non-@mention top-level channel message is dropped by the mention_only engagement gate (SLACK_CHANNEL_RESPONSE_MODE). membership = the agent's Slack MCP ADMITS non-@mention channel messages in channels its bot is a member of (the Socket Mode websocket already receives them), waking the agent in-thread via the SAME existing wake path used for @mentions/DMs. Only the mention_only engagement gate is relaxed - the echo/dedup, bot_id/self, and peer-classifier safety leaves still apply, so this never opens a bot-to-bot wake loop. The channel server can't evaluate flags, so the manager materializes the resolved value into the AGT_NOTIFY_DISPATCH spawn env (operator/canary override, ADR-0022). filter = like membership (opt-out) but honours a per-channel mute list: a member-channel message wakes the agent UNLESS the user muted that channel via the /notify slash command. The manager materializes the muted set into AGT_NOTIFY_MUTED_CHANNELS from agent_notify_channel_prefs (ENG-7682 Slice 2). addressed = like filter (same per-channel mute, checked FIRST so a mute outranks being named), but a member-channel message additionally has to address THIS agent to wake it: a real Slack mention of its bot user id, \`@<code_name>\` typed verbatim, or the code name used as a vocative at the start of the message ("koda:", "hey koda"). @team / @everyone still wake everyone. This is the fix for one named agent waking every agent in a shared channel (ENG-8657); matching is deliberately conservative, so a name mentioned mid-sentence does NOT wake, and an agent whose identity is unknown to the channel server stays asleep rather than waking on everything. Ships dark (default off).`,
|
|
35725
35725
|
flagType: "enum",
|
|
35726
|
-
allowedValues: ["off", "membership", "filter"],
|
|
35726
|
+
allowedValues: ["off", "membership", "filter", "addressed"],
|
|
35727
35727
|
// Declared safe value is `off`: the mention_only gate stays in force, byte-
|
|
35728
35728
|
// identical to today. membership is the deliberate, per-agent flip that
|
|
35729
35729
|
// widens what wakes the agent.
|
package/dist/mcp/origami.js
CHANGED
|
@@ -41612,9 +41612,9 @@ var FLAG_REGISTRY = [
|
|
|
41612
41612
|
},
|
|
41613
41613
|
{
|
|
41614
41614
|
key: "notify-dispatch",
|
|
41615
|
-
description:
|
|
41615
|
+
description: `Membership-based channel-notify dispatch (ENG-7682 / notify Slice 1). off = today's behaviour: a non-@mention top-level channel message is dropped by the mention_only engagement gate (SLACK_CHANNEL_RESPONSE_MODE). membership = the agent's Slack MCP ADMITS non-@mention channel messages in channels its bot is a member of (the Socket Mode websocket already receives them), waking the agent in-thread via the SAME existing wake path used for @mentions/DMs. Only the mention_only engagement gate is relaxed - the echo/dedup, bot_id/self, and peer-classifier safety leaves still apply, so this never opens a bot-to-bot wake loop. The channel server can't evaluate flags, so the manager materializes the resolved value into the AGT_NOTIFY_DISPATCH spawn env (operator/canary override, ADR-0022). filter = like membership (opt-out) but honours a per-channel mute list: a member-channel message wakes the agent UNLESS the user muted that channel via the /notify slash command. The manager materializes the muted set into AGT_NOTIFY_MUTED_CHANNELS from agent_notify_channel_prefs (ENG-7682 Slice 2). addressed = like filter (same per-channel mute, checked FIRST so a mute outranks being named), but a member-channel message additionally has to address THIS agent to wake it: a real Slack mention of its bot user id, \`@<code_name>\` typed verbatim, or the code name used as a vocative at the start of the message ("koda:", "hey koda"). @team / @everyone still wake everyone. This is the fix for one named agent waking every agent in a shared channel (ENG-8657); matching is deliberately conservative, so a name mentioned mid-sentence does NOT wake, and an agent whose identity is unknown to the channel server stays asleep rather than waking on everything. Ships dark (default off).`,
|
|
41616
41616
|
flagType: "enum",
|
|
41617
|
-
allowedValues: ["off", "membership", "filter"],
|
|
41617
|
+
allowedValues: ["off", "membership", "filter", "addressed"],
|
|
41618
41618
|
// Declared safe value is `off`: the mention_only gate stays in force, byte-
|
|
41619
41619
|
// identical to today. membership is the deliberate, per-agent flip that
|
|
41620
41620
|
// widens what wakes the agent.
|
|
@@ -14991,7 +14991,7 @@ var require_lib = __commonJS({
|
|
|
14991
14991
|
">": ">",
|
|
14992
14992
|
"\\": "\"
|
|
14993
14993
|
};
|
|
14994
|
-
var
|
|
14994
|
+
var escapeRegex3 = /[&"'<>\\]/g;
|
|
14995
14995
|
var _exports = module.exports = {};
|
|
14996
14996
|
function hasOwnProp(obj, k) {
|
|
14997
14997
|
return ObjProto.hasOwnProperty.call(obj, k);
|
|
@@ -15095,7 +15095,7 @@ var require_lib = __commonJS({
|
|
|
15095
15095
|
}
|
|
15096
15096
|
_exports.TemplateError = TemplateError2;
|
|
15097
15097
|
function escape2(val) {
|
|
15098
|
-
return val.replace(
|
|
15098
|
+
return val.replace(escapeRegex3, lookupEscape);
|
|
15099
15099
|
}
|
|
15100
15100
|
_exports.escape = escape2;
|
|
15101
15101
|
function isFunction(obj) {
|
|
@@ -36057,9 +36057,9 @@ var FLAG_REGISTRY = [
|
|
|
36057
36057
|
},
|
|
36058
36058
|
{
|
|
36059
36059
|
key: "notify-dispatch",
|
|
36060
|
-
description:
|
|
36060
|
+
description: `Membership-based channel-notify dispatch (ENG-7682 / notify Slice 1). off = today's behaviour: a non-@mention top-level channel message is dropped by the mention_only engagement gate (SLACK_CHANNEL_RESPONSE_MODE). membership = the agent's Slack MCP ADMITS non-@mention channel messages in channels its bot is a member of (the Socket Mode websocket already receives them), waking the agent in-thread via the SAME existing wake path used for @mentions/DMs. Only the mention_only engagement gate is relaxed - the echo/dedup, bot_id/self, and peer-classifier safety leaves still apply, so this never opens a bot-to-bot wake loop. The channel server can't evaluate flags, so the manager materializes the resolved value into the AGT_NOTIFY_DISPATCH spawn env (operator/canary override, ADR-0022). filter = like membership (opt-out) but honours a per-channel mute list: a member-channel message wakes the agent UNLESS the user muted that channel via the /notify slash command. The manager materializes the muted set into AGT_NOTIFY_MUTED_CHANNELS from agent_notify_channel_prefs (ENG-7682 Slice 2). addressed = like filter (same per-channel mute, checked FIRST so a mute outranks being named), but a member-channel message additionally has to address THIS agent to wake it: a real Slack mention of its bot user id, \`@<code_name>\` typed verbatim, or the code name used as a vocative at the start of the message ("koda:", "hey koda"). @team / @everyone still wake everyone. This is the fix for one named agent waking every agent in a shared channel (ENG-8657); matching is deliberately conservative, so a name mentioned mid-sentence does NOT wake, and an agent whose identity is unknown to the channel server stays asleep rather than waking on everything. Ships dark (default off).`,
|
|
36061
36061
|
flagType: "enum",
|
|
36062
|
-
allowedValues: ["off", "membership", "filter"],
|
|
36062
|
+
allowedValues: ["off", "membership", "filter", "addressed"],
|
|
36063
36063
|
// Declared safe value is `off`: the mention_only gate stays in force, byte-
|
|
36064
36064
|
// identical to today. membership is the deliberate, per-agent flip that
|
|
36065
36065
|
// widens what wakes the agent.
|
|
@@ -39908,6 +39908,26 @@ function matchesAddressedTeam(text) {
|
|
|
39908
39908
|
if (/^(everyone|all)\s*[:,—-]/i.test(t)) return true;
|
|
39909
39909
|
return false;
|
|
39910
39910
|
}
|
|
39911
|
+
function matchesAddressedAgent(text, agent) {
|
|
39912
|
+
const t = text.trim();
|
|
39913
|
+
if (t.length === 0) return false;
|
|
39914
|
+
const botUserId2 = agent.botUserId?.trim();
|
|
39915
|
+
if (botUserId2 && new RegExp(`<@${escapeRegex2(botUserId2)}(?:\\|[^>]*)?>`).test(t)) return true;
|
|
39916
|
+
const codeName = agent.codeName?.trim();
|
|
39917
|
+
if (!codeName) return false;
|
|
39918
|
+
const name = escapeRegex2(codeName);
|
|
39919
|
+
if (new RegExp(`(?:^|\\s)@${name}(?=$|[\\s.,!?;:])`, "i").test(t)) return true;
|
|
39920
|
+
if (new RegExp(`^${name}\\s*[:,\u2014-]`, "i").test(t)) return true;
|
|
39921
|
+
if (new RegExp(
|
|
39922
|
+
`^(hey|hi|hello|howdy|good (morning|afternoon|evening)|morning|afternoon)\\s+${name}(?=$|[\\s,.!?:])`,
|
|
39923
|
+
"i"
|
|
39924
|
+
).test(t))
|
|
39925
|
+
return true;
|
|
39926
|
+
return false;
|
|
39927
|
+
}
|
|
39928
|
+
function escapeRegex2(value) {
|
|
39929
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
39930
|
+
}
|
|
39911
39931
|
function channelMessageShouldRespond(text, mode) {
|
|
39912
39932
|
if (mode === "all") return true;
|
|
39913
39933
|
if (mode === "mention_only") return false;
|
|
@@ -39920,6 +39940,7 @@ function parseNotifyDispatchMode(raw) {
|
|
|
39920
39940
|
const v = raw.trim().toLowerCase();
|
|
39921
39941
|
if (v === "membership") return "membership";
|
|
39922
39942
|
if (v === "filter") return "filter";
|
|
39943
|
+
if (v === "addressed") return "addressed";
|
|
39923
39944
|
return "off";
|
|
39924
39945
|
}
|
|
39925
39946
|
function parseMutedChannels(raw) {
|
|
@@ -39928,12 +39949,17 @@ function parseMutedChannels(raw) {
|
|
|
39928
39949
|
raw.split(",").map((s) => s.trim()).filter(Boolean)
|
|
39929
39950
|
);
|
|
39930
39951
|
}
|
|
39931
|
-
function channelMessageShouldWake(text, responseMode, notifyMode, channelId, mutedChannels) {
|
|
39952
|
+
function channelMessageShouldWake(text, responseMode, notifyMode, channelId, mutedChannels, agent) {
|
|
39932
39953
|
if (notifyMode === "membership") return true;
|
|
39933
39954
|
if (notifyMode === "filter") {
|
|
39934
39955
|
if (channelId && mutedChannels && mutedChannels.has(channelId)) return false;
|
|
39935
39956
|
return true;
|
|
39936
39957
|
}
|
|
39958
|
+
if (notifyMode === "addressed") {
|
|
39959
|
+
if (channelId && mutedChannels && mutedChannels.has(channelId)) return false;
|
|
39960
|
+
if (!agent) return false;
|
|
39961
|
+
return matchesAddressedAgent(text, agent);
|
|
39962
|
+
}
|
|
39937
39963
|
return channelMessageShouldRespond(text, responseMode);
|
|
39938
39964
|
}
|
|
39939
39965
|
function parseNotifyCommand(text, currentChannelId) {
|
|
@@ -39943,6 +39969,15 @@ function parseNotifyCommand(text, currentChannelId) {
|
|
|
39943
39969
|
if (arg === "" || arg === "status") return { action: "status", channelId: currentChannelId };
|
|
39944
39970
|
return { action: "help", channelId: currentChannelId };
|
|
39945
39971
|
}
|
|
39972
|
+
function notifyStatusMessage(muted, mode) {
|
|
39973
|
+
if (mode === "filter") {
|
|
39974
|
+
return muted ? ":mute: This channel is *muted* \u2014 I won\u2019t wake on its messages (an @-mention still reaches me). `/notify on` to resume." : ":bell: This channel is *active* \u2014 I wake on its messages. `/notify off` to mute.";
|
|
39975
|
+
}
|
|
39976
|
+
if (mode === "addressed") {
|
|
39977
|
+
return muted ? ":mute: This channel is *muted* \u2014 I won\u2019t wake on its messages, including ones that name me (a direct @-mention still reaches me). `/notify on` to resume." : ":bell: This channel is *active* \u2014 I wake on messages that address me by name, not on every message here (an @-mention always reaches me). `/notify off` to mute.";
|
|
39978
|
+
}
|
|
39979
|
+
return muted ? ":grey_question: Your *mute* for this channel is *saved but not in effect* \u2014 I\u2019m not in a per-channel dispatch mode right now, so it isn\u2019t changing what wakes me. It applies as soon as an operator enables one." : ":grey_question: *No mute saved* for this channel \u2014 though it wouldn\u2019t apply yet either way: I\u2019m not in a per-channel dispatch mode right now. `/notify off` saves one for when an operator enables it.";
|
|
39980
|
+
}
|
|
39946
39981
|
|
|
39947
39982
|
// src/slack-list-channels.ts
|
|
39948
39983
|
function normaliseForMatch(s) {
|
|
@@ -42887,7 +42922,8 @@ async function handleNotifyCommand(payload, codeName) {
|
|
|
42887
42922
|
);
|
|
42888
42923
|
return;
|
|
42889
42924
|
}
|
|
42890
|
-
const
|
|
42925
|
+
const muteIsLive = NOTIFY_DISPATCH_MODE === "filter" || NOTIFY_DISPATCH_MODE === "addressed";
|
|
42926
|
+
const inactiveNote = muteIsLive ? "" : " _(note: I\u2019m not in a per-channel dispatch mode right now, so this is saved but won\u2019t take effect until an operator enables it.)_";
|
|
42891
42927
|
const { action } = parseNotifyCommand(payload.text, channelId);
|
|
42892
42928
|
if (action === "help") {
|
|
42893
42929
|
await postEphemeralViaResponseUrl(
|
|
@@ -42901,7 +42937,9 @@ async function handleNotifyCommand(payload, codeName) {
|
|
|
42901
42937
|
const muted = MUTED_CHANNELS.has(channelId);
|
|
42902
42938
|
await postEphemeralViaResponseUrl(
|
|
42903
42939
|
responseUrl,
|
|
42904
|
-
|
|
42940
|
+
// Pass the MODE, not muteIsLive: `filter` and `addressed` both honour the
|
|
42941
|
+
// mute but do not wake alike, and the status line has to say which.
|
|
42942
|
+
notifyStatusMessage(muted, NOTIFY_DISPATCH_MODE),
|
|
42905
42943
|
codeName
|
|
42906
42944
|
);
|
|
42907
42945
|
return;
|
|
@@ -45422,7 +45460,20 @@ async function seedMutedChannelsFromApi() {
|
|
|
45422
45460
|
}
|
|
45423
45461
|
}
|
|
45424
45462
|
function connectSocketModeSafely() {
|
|
45425
|
-
|
|
45463
|
+
void startSocketModeAfterSeedingMutes();
|
|
45464
|
+
}
|
|
45465
|
+
async function startSocketModeAfterSeedingMutes() {
|
|
45466
|
+
if (NOTIFY_DISPATCH_MODE === "filter" || NOTIFY_DISPATCH_MODE === "addressed") {
|
|
45467
|
+
try {
|
|
45468
|
+
await seedMutedChannelsFromApi();
|
|
45469
|
+
} catch (err) {
|
|
45470
|
+
process.stderr.write(
|
|
45471
|
+
`slack-channel: notify-prefs seed threw, connecting anyway: ${err.message}
|
|
45472
|
+
`
|
|
45473
|
+
);
|
|
45474
|
+
}
|
|
45475
|
+
}
|
|
45476
|
+
if (isShuttingDown) return;
|
|
45426
45477
|
void runOrRetry(connectSocketMode, {
|
|
45427
45478
|
retryDelayMs: 1e4,
|
|
45428
45479
|
onError: (err) => process.stderr.write(
|
|
@@ -45848,7 +45899,10 @@ async function connectSocketMode() {
|
|
|
45848
45899
|
CHANNEL_RESPONSE_MODE,
|
|
45849
45900
|
NOTIFY_DISPATCH_MODE,
|
|
45850
45901
|
evt.channel,
|
|
45851
|
-
MUTED_CHANNELS
|
|
45902
|
+
MUTED_CHANNELS,
|
|
45903
|
+
// ENG-8657: who this agent is, so `addressed` can tell a message
|
|
45904
|
+
// naming IT from one naming a different agent in the same channel.
|
|
45905
|
+
{ botUserId, codeName: AGENT_CODE_NAME }
|
|
45852
45906
|
))
|
|
45853
45907
|
return;
|
|
45854
45908
|
}
|
|
@@ -36216,9 +36216,9 @@ var FLAG_REGISTRY = [
|
|
|
36216
36216
|
},
|
|
36217
36217
|
{
|
|
36218
36218
|
key: "notify-dispatch",
|
|
36219
|
-
description:
|
|
36219
|
+
description: `Membership-based channel-notify dispatch (ENG-7682 / notify Slice 1). off = today's behaviour: a non-@mention top-level channel message is dropped by the mention_only engagement gate (SLACK_CHANNEL_RESPONSE_MODE). membership = the agent's Slack MCP ADMITS non-@mention channel messages in channels its bot is a member of (the Socket Mode websocket already receives them), waking the agent in-thread via the SAME existing wake path used for @mentions/DMs. Only the mention_only engagement gate is relaxed - the echo/dedup, bot_id/self, and peer-classifier safety leaves still apply, so this never opens a bot-to-bot wake loop. The channel server can't evaluate flags, so the manager materializes the resolved value into the AGT_NOTIFY_DISPATCH spawn env (operator/canary override, ADR-0022). filter = like membership (opt-out) but honours a per-channel mute list: a member-channel message wakes the agent UNLESS the user muted that channel via the /notify slash command. The manager materializes the muted set into AGT_NOTIFY_MUTED_CHANNELS from agent_notify_channel_prefs (ENG-7682 Slice 2). addressed = like filter (same per-channel mute, checked FIRST so a mute outranks being named), but a member-channel message additionally has to address THIS agent to wake it: a real Slack mention of its bot user id, \`@<code_name>\` typed verbatim, or the code name used as a vocative at the start of the message ("koda:", "hey koda"). @team / @everyone still wake everyone. This is the fix for one named agent waking every agent in a shared channel (ENG-8657); matching is deliberately conservative, so a name mentioned mid-sentence does NOT wake, and an agent whose identity is unknown to the channel server stays asleep rather than waking on everything. Ships dark (default off).`,
|
|
36220
36220
|
flagType: "enum",
|
|
36221
|
-
allowedValues: ["off", "membership", "filter"],
|
|
36221
|
+
allowedValues: ["off", "membership", "filter", "addressed"],
|
|
36222
36222
|
// Declared safe value is `off`: the mention_only gate stays in force, byte-
|
|
36223
36223
|
// identical to today. membership is the deliberate, per-agent flip that
|
|
36224
36224
|
// widens what wakes the agent.
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
writeDirectChatSessionState,
|
|
42
42
|
writeEgressAllowlist,
|
|
43
43
|
writePersistentClaudeWrapper
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-72K46XUZ.js";
|
|
45
45
|
import "./chunk-XWVM4KPK.js";
|
|
46
46
|
export {
|
|
47
47
|
EGRESS_BASELINE_DOMAINS,
|
|
@@ -87,4 +87,4 @@ export {
|
|
|
87
87
|
writeEgressAllowlist,
|
|
88
88
|
writePersistentClaudeWrapper
|
|
89
89
|
};
|
|
90
|
-
//# sourceMappingURL=persistent-session-
|
|
90
|
+
//# sourceMappingURL=persistent-session-74MH2XTM.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
paneLogPath
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-72K46XUZ.js";
|
|
4
4
|
import "./chunk-XWVM4KPK.js";
|
|
5
5
|
|
|
6
6
|
// src/lib/responsiveness-probe.ts
|
|
@@ -689,4 +689,4 @@ export {
|
|
|
689
689
|
readAndResetSlackReplyBindingClassifications,
|
|
690
690
|
readAndResetSlackReplyTargetClassifications
|
|
691
691
|
};
|
|
692
|
-
//# sourceMappingURL=responsiveness-probe-
|
|
692
|
+
//# sourceMappingURL=responsiveness-probe-5VNQQZNJ.js.map
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|