@integrity-labs/agt-cli 0.28.1171 → 0.28.1173
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-TJ4MVWNH.js → chunk-W34QK2EY.js} +2 -2
- package/dist/lib/manager-worker.js +2 -2
- package/dist/mcp/direct-chat-channel.js +5 -1
- package/dist/mcp/index.js +44 -0
- package/dist/mcp/slack-channel.js +50 -13
- package/dist/mcp/telegram-channel.js +5 -1
- package/package.json +1 -1
- /package/dist/{chunk-TJ4MVWNH.js.map → chunk-W34QK2EY.js.map} +0 -0
package/dist/bin/agt.js
CHANGED
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
success,
|
|
41
41
|
table,
|
|
42
42
|
warn
|
|
43
|
-
} from "../chunk-
|
|
43
|
+
} from "../chunk-W34QK2EY.js";
|
|
44
44
|
import {
|
|
45
45
|
getProjectDir,
|
|
46
46
|
isSessionResumeDisabled,
|
|
@@ -5513,7 +5513,7 @@ import { execFileSync, execSync } from "child_process";
|
|
|
5513
5513
|
import { existsSync as existsSync11, realpathSync as realpathSync2 } from "fs";
|
|
5514
5514
|
import chalk18 from "chalk";
|
|
5515
5515
|
import ora16 from "ora";
|
|
5516
|
-
var cliVersion = true ? "0.28.
|
|
5516
|
+
var cliVersion = true ? "0.28.1173" : "dev";
|
|
5517
5517
|
async function fetchLatestVersion() {
|
|
5518
5518
|
const host2 = getHost();
|
|
5519
5519
|
if (!host2) return null;
|
|
@@ -6773,7 +6773,7 @@ function handleError(err) {
|
|
|
6773
6773
|
}
|
|
6774
6774
|
|
|
6775
6775
|
// src/bin/agt.ts
|
|
6776
|
-
var cliVersion2 = true ? "0.28.
|
|
6776
|
+
var cliVersion2 = true ? "0.28.1173" : "dev";
|
|
6777
6777
|
var program = new Command();
|
|
6778
6778
|
program.name("agt").description("Augmented CLI \u2014 agent provisioning and management").version(cliVersion2).option("--json", "Emit machine-readable JSON output (suppress spinners and colors)").option("--skip-update-check", "Skip the automatic update check on startup");
|
|
6779
6779
|
program.hook("preAction", async (thisCommand, actionCommand) => {
|
|
@@ -8078,7 +8078,7 @@ function exchangeFailureKind(err) {
|
|
|
8078
8078
|
}
|
|
8079
8079
|
|
|
8080
8080
|
// src/lib/api-client.ts
|
|
8081
|
-
var agtCliVersion = true ? "0.28.
|
|
8081
|
+
var agtCliVersion = true ? "0.28.1173" : "dev";
|
|
8082
8082
|
var lastConfigHash = null;
|
|
8083
8083
|
function setConfigHash(hash) {
|
|
8084
8084
|
lastConfigHash = hash && hash.length > 0 ? hash : null;
|
|
@@ -13235,4 +13235,4 @@ export {
|
|
|
13235
13235
|
managerInstallSystemUnitCommand,
|
|
13236
13236
|
managerUninstallSystemUnitCommand
|
|
13237
13237
|
};
|
|
13238
|
-
//# sourceMappingURL=chunk-
|
|
13238
|
+
//# sourceMappingURL=chunk-W34QK2EY.js.map
|
|
@@ -77,7 +77,7 @@ import {
|
|
|
77
77
|
setConfigHash,
|
|
78
78
|
shellGuard,
|
|
79
79
|
tripClass
|
|
80
|
-
} from "../chunk-
|
|
80
|
+
} from "../chunk-W34QK2EY.js";
|
|
81
81
|
import {
|
|
82
82
|
CLAUDE_CODE_SECURITY_FLOOR,
|
|
83
83
|
SELF_UPDATE_TIMEOUTS,
|
|
@@ -15928,7 +15928,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
15928
15928
|
var lastVersionCheckAt = 0;
|
|
15929
15929
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
15930
15930
|
var lastResponsivenessProbeAt = 0;
|
|
15931
|
-
var agtCliVersion = true ? "0.28.
|
|
15931
|
+
var agtCliVersion = true ? "0.28.1173" : "dev";
|
|
15932
15932
|
function resolveBrewPath(execFileSync3) {
|
|
15933
15933
|
try {
|
|
15934
15934
|
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -47473,6 +47473,9 @@ function classifyUndeliverableCause(i) {
|
|
|
47473
47473
|
return null;
|
|
47474
47474
|
}
|
|
47475
47475
|
var UNDELIVERABLE_NOTICE_THROTTLE_MS = 5 * 60 * 1e3;
|
|
47476
|
+
function markerOwesNoReply(m) {
|
|
47477
|
+
return m.discretionary === true || m.ingress_only === true;
|
|
47478
|
+
}
|
|
47476
47479
|
function shouldPostUndeliverableNotice(lastNoticeAtMs, nowMs, throttleMs = UNDELIVERABLE_NOTICE_THROTTLE_MS) {
|
|
47477
47480
|
return lastNoticeAtMs == null || nowMs - lastNoticeAtMs >= throttleMs;
|
|
47478
47481
|
}
|
|
@@ -47644,7 +47647,7 @@ function oldestPendingMarkerAgeMs(dir, now = Date.now(), opts) {
|
|
|
47644
47647
|
let receivedAt;
|
|
47645
47648
|
try {
|
|
47646
47649
|
const raw = JSON.parse(readFileSync9(join10(dir, name), "utf-8"));
|
|
47647
|
-
if (raw
|
|
47650
|
+
if (markerOwesNoReply(raw)) continue;
|
|
47648
47651
|
if (!opts?.includeSeen && typeof raw.seen_at === "string" && raw.seen_at) continue;
|
|
47649
47652
|
receivedAt = raw.received_at;
|
|
47650
47653
|
} catch {
|
|
@@ -54079,6 +54082,7 @@ var MAINTENANCE_GATED_TOOLS = /* @__PURE__ */ new Set([
|
|
|
54079
54082
|
// ADR-0025 approval tools, registered by `approval-tools.ts` against the same
|
|
54080
54083
|
// server object, so the wrapper in index.ts covers them too.
|
|
54081
54084
|
"cancel_approval",
|
|
54085
|
+
"approval_annotate",
|
|
54082
54086
|
// Status / identity.
|
|
54083
54087
|
"status_standup",
|
|
54084
54088
|
"status_update",
|
package/dist/mcp/index.js
CHANGED
|
@@ -47352,6 +47352,7 @@ var MAINTENANCE_GATED_TOOLS = /* @__PURE__ */ new Set([
|
|
|
47352
47352
|
// ADR-0025 approval tools, registered by `approval-tools.ts` against the same
|
|
47353
47353
|
// server object, so the wrapper in index.ts covers them too.
|
|
47354
47354
|
"cancel_approval",
|
|
47355
|
+
"approval_annotate",
|
|
47355
47356
|
// Status / identity.
|
|
47356
47357
|
"status_standup",
|
|
47357
47358
|
"status_update",
|
|
@@ -48694,6 +48695,22 @@ function describeKanbanLink(requestedCardId, resp) {
|
|
|
48694
48695
|
}
|
|
48695
48696
|
return ` Card ${requestedCardId} was NOT linked to this approval (${why}), so the card is not waiting on it and answering the card will not decide it. Leave the request as is (the approver can still decide it from the Approvals page) and do not park the card as a human Approve/Deny wait.`;
|
|
48696
48697
|
}
|
|
48698
|
+
var APPROVAL_ANNOTATE_EVIDENCE_MAX = 1e3;
|
|
48699
|
+
function describeAnnotation(resp) {
|
|
48700
|
+
const head = `Recorded your recommendation (${resp.recommendation}) on request ${resp.request_id}. This is not a decision; the person still decides.`;
|
|
48701
|
+
switch (resp.card.outcome) {
|
|
48702
|
+
case "card_updated":
|
|
48703
|
+
return `${head} It now shows on their approval card.`;
|
|
48704
|
+
case "follow_up_posted":
|
|
48705
|
+
return `${head} It was posted as a follow-up beside their card. It also shows on the Approvals page.`;
|
|
48706
|
+
case "unchanged":
|
|
48707
|
+
return `${head} It is identical to your last one, which already reached their card, so nothing was re-sent.`;
|
|
48708
|
+
case "no_card":
|
|
48709
|
+
return `${head} No chat card was delivered for this request, so it shows on the Approvals page only.`;
|
|
48710
|
+
default:
|
|
48711
|
+
return `${head} It could NOT be added to their chat card (${resp.card.reason ?? "unknown"}), so it shows on the Approvals page only. Do not say they have seen it.`;
|
|
48712
|
+
}
|
|
48713
|
+
}
|
|
48697
48714
|
function statusToOutcome(status) {
|
|
48698
48715
|
switch (status) {
|
|
48699
48716
|
case "active":
|
|
@@ -48803,6 +48820,31 @@ function registerApprovalTools(server2, deps) {
|
|
|
48803
48820
|
}
|
|
48804
48821
|
}
|
|
48805
48822
|
);
|
|
48823
|
+
server2.tool(
|
|
48824
|
+
"approval_annotate",
|
|
48825
|
+
"Attach your recommendation and what you checked to an approval request from an agent that reports to you, directly or further down your reports-to chain. The person deciding sees it on their approval card, labelled as an agent recommendation. It is NOT a decision: it cannot approve, deny or change the request, and the human still decides. Use it after you have verified the facts yourself, never by repeating the requester's own words. Calling it again replaces your earlier recommendation. Only works while the request is pending.",
|
|
48826
|
+
{
|
|
48827
|
+
request_id: external_exports.string().min(1).describe("The request id from the notice telling you about your report's approval."),
|
|
48828
|
+
recommendation: external_exports.enum(["approve", "deny", "unsure"]).describe("What you recommend the person decides."),
|
|
48829
|
+
evidence: external_exports.string().min(1).max(APPROVAL_ANNOTATE_EVIDENCE_MAX).describe('What you checked and found, e.g. "tree clean, no stash, all commits on origin". Shown as one line of quoted text, attributed to you.')
|
|
48830
|
+
},
|
|
48831
|
+
async (params) => {
|
|
48832
|
+
try {
|
|
48833
|
+
const resp = await apiPost2(`/approvals/${encodeURIComponent(params.request_id)}/annotate`, {
|
|
48834
|
+
agent_id: agentId,
|
|
48835
|
+
recommendation: params.recommendation,
|
|
48836
|
+
evidence: params.evidence
|
|
48837
|
+
});
|
|
48838
|
+
return { content: [{ type: "text", text: describeAnnotation(resp) }] };
|
|
48839
|
+
} catch (err) {
|
|
48840
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
48841
|
+
return {
|
|
48842
|
+
content: [{ type: "text", text: `Could not attach the recommendation to ${params.request_id}: ${msg}` }],
|
|
48843
|
+
isError: true
|
|
48844
|
+
};
|
|
48845
|
+
}
|
|
48846
|
+
}
|
|
48847
|
+
);
|
|
48806
48848
|
server2.tool(
|
|
48807
48849
|
"cancel_approval",
|
|
48808
48850
|
"Withdraw an approval request you no longer need (only works while it is still pending). The Manager stops being asked. Use when the underlying need went away.",
|
|
@@ -52424,6 +52466,8 @@ var LOCAL_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
52424
52466
|
"request_approval",
|
|
52425
52467
|
"check_approval",
|
|
52426
52468
|
"cancel_approval",
|
|
52469
|
+
// ENG-11573: a managing agent's recommendation on a report's approval.
|
|
52470
|
+
"approval_annotate",
|
|
52427
52471
|
"kanban_list",
|
|
52428
52472
|
"kanban_search",
|
|
52429
52473
|
"kanban_get",
|
|
@@ -31065,6 +31065,7 @@ var MAINTENANCE_GATED_TOOLS = /* @__PURE__ */ new Set([
|
|
|
31065
31065
|
// ADR-0025 approval tools, registered by `approval-tools.ts` against the same
|
|
31066
31066
|
// server object, so the wrapper in index.ts covers them too.
|
|
31067
31067
|
"cancel_approval",
|
|
31068
|
+
"approval_annotate",
|
|
31068
31069
|
// Status / identity.
|
|
31069
31070
|
"status_standup",
|
|
31070
31071
|
"status_update",
|
|
@@ -41280,6 +41281,12 @@ var UNDELIVERABLE_NOTICE_THROTTLE_MS = 5 * 60 * 1e3;
|
|
|
41280
41281
|
function undeliverableNoticeEligible(shouldEngage) {
|
|
41281
41282
|
return shouldEngage;
|
|
41282
41283
|
}
|
|
41284
|
+
function decideInboundReplyOwed(i) {
|
|
41285
|
+
return i.shouldEngage && !i.ingressOnlyThread;
|
|
41286
|
+
}
|
|
41287
|
+
function markerOwesNoReply(m) {
|
|
41288
|
+
return m.discretionary === true || m.ingress_only === true;
|
|
41289
|
+
}
|
|
41283
41290
|
function shouldPostUndeliverableNotice(lastNoticeAtMs, nowMs, throttleMs = UNDELIVERABLE_NOTICE_THROTTLE_MS) {
|
|
41284
41291
|
return lastNoticeAtMs == null || nowMs - lastNoticeAtMs >= throttleMs;
|
|
41285
41292
|
}
|
|
@@ -41646,7 +41653,7 @@ function oldestPendingMarkerAgeMs(dir, now = Date.now(), opts) {
|
|
|
41646
41653
|
let receivedAt;
|
|
41647
41654
|
try {
|
|
41648
41655
|
const raw = JSON.parse(readFileSync3(join3(dir, name), "utf-8"));
|
|
41649
|
-
if (raw
|
|
41656
|
+
if (markerOwesNoReply(raw)) continue;
|
|
41650
41657
|
if (!opts?.includeSeen && typeof raw.seen_at === "string" && raw.seen_at) continue;
|
|
41651
41658
|
receivedAt = raw.received_at;
|
|
41652
41659
|
} catch {
|
|
@@ -43596,7 +43603,7 @@ function countOwedSlackRepliesForThread(dir, channel, threadTs) {
|
|
|
43596
43603
|
try {
|
|
43597
43604
|
const m = JSON.parse(readFileSync5(fullPath, "utf-8"));
|
|
43598
43605
|
if (!m || typeof m !== "object") return;
|
|
43599
|
-
if (m.discretionary === true || m.undeliverable === true) return;
|
|
43606
|
+
if (m.discretionary === true || m.undeliverable === true || m.ingress_only === true) return;
|
|
43600
43607
|
owed += 1;
|
|
43601
43608
|
} catch {
|
|
43602
43609
|
}
|
|
@@ -43607,6 +43614,21 @@ function markSeenAllSlackPendingMarkersForThread(dir, channel, threadTs, markSee
|
|
|
43607
43614
|
const prefix = `${sanitizeMarkerSegment(channel)}__${sanitizeMarkerSegment(threadTs)}__`;
|
|
43608
43615
|
return applyToMatchingMarkers(dir, prefix, ".json", markSeen);
|
|
43609
43616
|
}
|
|
43617
|
+
function clearIngressOnlySlackPendingMarkersForThread(dir, channel, threadTs, clear = defaultClearMarkerFile) {
|
|
43618
|
+
const cleared = [];
|
|
43619
|
+
markSeenAllSlackPendingMarkersForThread(dir, channel, threadTs, (fullPath) => {
|
|
43620
|
+
let marker;
|
|
43621
|
+
try {
|
|
43622
|
+
marker = JSON.parse(readFileSync5(fullPath, "utf-8"));
|
|
43623
|
+
} catch {
|
|
43624
|
+
return;
|
|
43625
|
+
}
|
|
43626
|
+
if (typeof marker !== "object" || marker === null || marker.ingress_only !== true) return;
|
|
43627
|
+
clear(fullPath);
|
|
43628
|
+
if (typeof marker.message_ts === "string") cleared.push(marker.message_ts);
|
|
43629
|
+
});
|
|
43630
|
+
return cleared;
|
|
43631
|
+
}
|
|
43610
43632
|
function clearSlackPendingMarkerByMessageTs(dir, channel, messageTs, clear = defaultClearMarkerFile) {
|
|
43611
43633
|
const channelPrefix = `${sanitizeMarkerSegment(channel)}__`;
|
|
43612
43634
|
const messageSuffix = `__${sanitizeMarkerSegment(messageTs)}.json`;
|
|
@@ -47915,7 +47937,7 @@ function sweepSlackStaleMarkers(thresholdMs) {
|
|
|
47915
47937
|
thresholdMs,
|
|
47916
47938
|
hardCeilingMs: STALE_MARKER_MS,
|
|
47917
47939
|
discretionaryThresholdMs: DISCRETIONARY_MARKER_MS,
|
|
47918
|
-
discretionary: marker
|
|
47940
|
+
discretionary: markerOwesNoReply(marker),
|
|
47919
47941
|
hasPayload: Boolean(marker.payload),
|
|
47920
47942
|
replayCount: marker.replay_count ?? 0,
|
|
47921
47943
|
replayEnabled
|
|
@@ -47923,7 +47945,7 @@ function sweepSlackStaleMarkers(thresholdMs) {
|
|
|
47923
47945
|
const structurallyBroken = !channel || !thread_ts || !message_ts;
|
|
47924
47946
|
const timeStale = isPendingMarkerStale(received_at, now, effectiveThresholdMs);
|
|
47925
47947
|
if (structurallyBroken || timeStale) {
|
|
47926
|
-
if (!marker
|
|
47948
|
+
if (!markerOwesNoReply(marker)) {
|
|
47927
47949
|
if (structurallyBroken || !isMarkerGenuinelyAged(received_at, now, effectiveThresholdMs)) {
|
|
47928
47950
|
recordChannelDeflection(SLACK_AGENT_DIR, "slack", "marker_corrupt");
|
|
47929
47951
|
} else if (marker.payload) {
|
|
@@ -48006,7 +48028,7 @@ function findSlackProgressTarget() {
|
|
|
48006
48028
|
continue;
|
|
48007
48029
|
}
|
|
48008
48030
|
if (!m.channel || !m.thread_ts) continue;
|
|
48009
|
-
if (m
|
|
48031
|
+
if (markerOwesNoReply(m) || m.undeliverable === true) continue;
|
|
48010
48032
|
const ms = Date.parse(m.received_at ?? "");
|
|
48011
48033
|
if (!Number.isFinite(ms)) continue;
|
|
48012
48034
|
if (ms < bestMs) {
|
|
@@ -48156,7 +48178,7 @@ function listPendingSlackConversations() {
|
|
|
48156
48178
|
);
|
|
48157
48179
|
if (typeof marker.channel !== "string" || !marker.channel) continue;
|
|
48158
48180
|
if (typeof marker.thread_ts !== "string" || !marker.thread_ts) continue;
|
|
48159
|
-
if (marker
|
|
48181
|
+
if (markerOwesNoReply(marker)) continue;
|
|
48160
48182
|
if (typeof marker.seen_at === "string" && marker.seen_at) continue;
|
|
48161
48183
|
const isThreadReply = typeof marker.message_ts === "string" && marker.message_ts !== marker.thread_ts;
|
|
48162
48184
|
const key2 = isThreadReply ? `${marker.channel}:${marker.thread_ts}` : marker.channel;
|
|
@@ -51315,7 +51337,8 @@ async function replayPendingSlackMarkers() {
|
|
|
51315
51337
|
// ENG-6366: auto-followed un-mentioned thread inbound the agent may
|
|
51316
51338
|
// legitimately silently skip — never re-deliver it (it never clears,
|
|
51317
51339
|
// so it would otherwise re-push MAX_MARKER_REPLAYS times under replay).
|
|
51318
|
-
|
|
51340
|
+
// ENG-11709: the same for a marker in a third-party-bot thread.
|
|
51341
|
+
discretionary: markerOwesNoReply(marker),
|
|
51319
51342
|
// ENG-7736: bound the pane-fresh defer (clamped under the orphan
|
|
51320
51343
|
// window) so a perpetually-fresh pane (respawn churn) can't hold off
|
|
51321
51344
|
// replay until the orphan sweep GCs the marker - the Sherlock loss.
|
|
@@ -51774,6 +51797,16 @@ async function connectSocketMode() {
|
|
|
51774
51797
|
}
|
|
51775
51798
|
} else if (access.kind !== "drop" && (!isBot || peerClassification?.kind === "peer-ingress")) {
|
|
51776
51799
|
ingressOnlyThreads.clear(evt.channel, ingressThreadTs);
|
|
51800
|
+
if (evt.channel && ingressThreadTs) {
|
|
51801
|
+
for (const clearedTs of clearIngressOnlySlackPendingMarkersForThread(
|
|
51802
|
+
SLACK_PENDING_INBOUND_DIR,
|
|
51803
|
+
evt.channel,
|
|
51804
|
+
ingressThreadTs,
|
|
51805
|
+
clearSlackMarkerFileWithHeal
|
|
51806
|
+
)) {
|
|
51807
|
+
slackInboundRegistry.markCleared(evt.channel, clearedTs);
|
|
51808
|
+
}
|
|
51809
|
+
}
|
|
51777
51810
|
}
|
|
51778
51811
|
if (access.kind === "drop") {
|
|
51779
51812
|
const channelHash = createHash3("sha256").update(evt.channel ?? "").digest("hex").slice(0, 8);
|
|
@@ -52044,6 +52077,10 @@ async function connectSocketMode() {
|
|
|
52044
52077
|
botPostedInThread,
|
|
52045
52078
|
addressesAnotherAgent
|
|
52046
52079
|
});
|
|
52080
|
+
const replyOwed = decideInboundReplyOwed({
|
|
52081
|
+
shouldEngage,
|
|
52082
|
+
ingressOnlyThread: ingressOnlyThreads.isIngressOnly(channel, threadTs)
|
|
52083
|
+
});
|
|
52047
52084
|
const ackProbe = process.env.TMUX && AGENT_CODE_NAME ? probeAgentSessionCached(AGENT_CODE_NAME) : { tmux: "unknown", claude: "unknown" };
|
|
52048
52085
|
let paneLogFreshAgeMs = null;
|
|
52049
52086
|
if (SLACK_AGENT_DIR) {
|
|
@@ -52083,13 +52120,13 @@ async function connectSocketMode() {
|
|
|
52083
52120
|
body: JSON.stringify({ channel, timestamp: ts, name: reactionName })
|
|
52084
52121
|
}).catch(() => {
|
|
52085
52122
|
});
|
|
52086
|
-
if (ackDecision === "undeliverable" && channel && undeliverableNoticeEligible(
|
|
52123
|
+
if (ackDecision === "undeliverable" && channel && undeliverableNoticeEligible(replyOwed)) {
|
|
52087
52124
|
postUndeliverableNotice(channel, threadTs, isThreadReply, cause);
|
|
52088
52125
|
}
|
|
52089
52126
|
}
|
|
52090
52127
|
if (channel && ts && armMarker) {
|
|
52091
|
-
trackPendingMessage(channel, threadTs, ts, ackDecision === "undeliverable", !
|
|
52092
|
-
if (ackDecision === "ack" &&
|
|
52128
|
+
trackPendingMessage(channel, threadTs, ts, ackDecision === "undeliverable", !replyOwed);
|
|
52129
|
+
if (ackDecision === "ack" && replyOwed) {
|
|
52093
52130
|
scheduleBusyAck(
|
|
52094
52131
|
channel,
|
|
52095
52132
|
threadTs,
|
|
@@ -52168,7 +52205,7 @@ async function connectSocketMode() {
|
|
|
52168
52205
|
// fork) - an auto-followed, un-addressed thread message (discretionary,
|
|
52169
52206
|
// !shouldEngage) owes no reply. Additive only; no consumer gates on
|
|
52170
52207
|
// these yet (Slice 2).
|
|
52171
|
-
...conversationalLaneMeta(
|
|
52208
|
+
...conversationalLaneMeta(replyOwed),
|
|
52172
52209
|
// ENG-7919: surface the effective auto-follow state (already cleared when
|
|
52173
52210
|
// the bot was @-mentioned) so the agent sees auto_followed="true" only
|
|
52174
52211
|
// when the message genuinely requires discretionary engagement judgment.
|
|
@@ -52199,7 +52236,7 @@ async function connectSocketMode() {
|
|
|
52199
52236
|
};
|
|
52200
52237
|
recordLaneClassification(SLACK_AGENT_DIR, "slack", {
|
|
52201
52238
|
lane: "conversational",
|
|
52202
|
-
expectsReply:
|
|
52239
|
+
expectsReply: replyOwed
|
|
52203
52240
|
});
|
|
52204
52241
|
if (channel && ts && armMarker) {
|
|
52205
52242
|
attachSlackReplayPayload(channel, threadTs, ts, replayPayload);
|
|
@@ -52250,7 +52287,7 @@ async function connectSocketMode() {
|
|
|
52250
52287
|
sinceMs: dispatchedAtMs
|
|
52251
52288
|
});
|
|
52252
52289
|
}
|
|
52253
|
-
if (
|
|
52290
|
+
if (replyOwed) seedSlackProgressHeartbeat();
|
|
52254
52291
|
if (channel) {
|
|
52255
52292
|
conversationIngestClient?.ingest({
|
|
52256
52293
|
channel: "slack",
|
|
@@ -31282,6 +31282,7 @@ var MAINTENANCE_GATED_TOOLS = /* @__PURE__ */ new Set([
|
|
|
31282
31282
|
// ADR-0025 approval tools, registered by `approval-tools.ts` against the same
|
|
31283
31283
|
// server object, so the wrapper in index.ts covers them too.
|
|
31284
31284
|
"cancel_approval",
|
|
31285
|
+
"approval_annotate",
|
|
31285
31286
|
// Status / identity.
|
|
31286
31287
|
"status_standup",
|
|
31287
31288
|
"status_update",
|
|
@@ -44212,6 +44213,9 @@ function decideRecoveryHeal(i) {
|
|
|
44212
44213
|
return i.wasUndeliverable && i.hasTarget ? "heal" : "none";
|
|
44213
44214
|
}
|
|
44214
44215
|
var UNDELIVERABLE_NOTICE_THROTTLE_MS = 5 * 60 * 1e3;
|
|
44216
|
+
function markerOwesNoReply(m) {
|
|
44217
|
+
return m.discretionary === true || m.ingress_only === true;
|
|
44218
|
+
}
|
|
44215
44219
|
function shouldPostUndeliverableNotice(lastNoticeAtMs, nowMs, throttleMs = UNDELIVERABLE_NOTICE_THROTTLE_MS) {
|
|
44216
44220
|
return lastNoticeAtMs == null || nowMs - lastNoticeAtMs >= throttleMs;
|
|
44217
44221
|
}
|
|
@@ -44553,7 +44557,7 @@ function oldestPendingMarkerAgeMs(dir, now = Date.now(), opts) {
|
|
|
44553
44557
|
let receivedAt;
|
|
44554
44558
|
try {
|
|
44555
44559
|
const raw = JSON.parse(readFileSync14(join17(dir, name), "utf-8"));
|
|
44556
|
-
if (raw
|
|
44560
|
+
if (markerOwesNoReply(raw)) continue;
|
|
44557
44561
|
if (!opts?.includeSeen && typeof raw.seen_at === "string" && raw.seen_at) continue;
|
|
44558
44562
|
receivedAt = raw.received_at;
|
|
44559
44563
|
} catch {
|
package/package.json
CHANGED
|
File without changes
|