@integrity-labs/agt-cli 0.28.44 → 0.28.46
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-HQHLMAIW.js → chunk-34NTBWVL.js} +24 -3
- package/dist/{chunk-HQHLMAIW.js.map → chunk-34NTBWVL.js.map} +1 -1
- package/dist/{chunk-SJUD2BWU.js → chunk-ONG7KSRP.js} +8 -1
- package/dist/chunk-ONG7KSRP.js.map +1 -0
- package/dist/{chunk-2BRF2FDJ.js → chunk-UVE6VSU3.js} +2 -2
- package/dist/{claude-pair-runtime-YPTMIWJF.js → claude-pair-runtime-QXRSXJ4D.js} +2 -2
- package/dist/lib/manager-worker.js +12 -8
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/augmented-admin.js +39 -2
- package/dist/mcp/slack-channel.js +14 -4
- package/dist/mcp/telegram-channel.js +13 -3
- package/dist/{persistent-session-PNY26VBX.js → persistent-session-Q73X7PPM.js} +3 -3
- package/dist/{responsiveness-probe-4YMZ6LXO.js → responsiveness-probe-R7WZXP2Y.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-SJUD2BWU.js.map +0 -1
- /package/dist/{chunk-2BRF2FDJ.js.map → chunk-UVE6VSU3.js.map} +0 -0
- /package/dist/{claude-pair-runtime-YPTMIWJF.js.map → claude-pair-runtime-QXRSXJ4D.js.map} +0 -0
- /package/dist/{persistent-session-PNY26VBX.js.map → persistent-session-Q73X7PPM.js.map} +0 -0
- /package/dist/{responsiveness-probe-4YMZ6LXO.js.map → responsiveness-probe-R7WZXP2Y.js.map} +0 -0
|
@@ -21182,6 +21182,19 @@ var AdminDebugClient = class _AdminDebugClient {
|
|
|
21182
21182
|
run_id: this.runId
|
|
21183
21183
|
});
|
|
21184
21184
|
}
|
|
21185
|
+
/** Request a HITL-gated, allowlisted diagnostic SSM run (ENG-6442). */
|
|
21186
|
+
requestSsmRun(args) {
|
|
21187
|
+
if (!this.agentId) {
|
|
21188
|
+
throw makeError(400, "AdminDebugClient.requestSsmRun requires agentId (set AGT_AGENT_ID)");
|
|
21189
|
+
}
|
|
21190
|
+
return this.post("/admin/debug/actions/ssm-run", {
|
|
21191
|
+
target_agent_id: args.target_agent_id,
|
|
21192
|
+
command_key: args.command,
|
|
21193
|
+
reason: args.reason,
|
|
21194
|
+
agent_id: this.agentId,
|
|
21195
|
+
run_id: this.runId
|
|
21196
|
+
});
|
|
21197
|
+
}
|
|
21185
21198
|
/** Poll a remedial action's HITL decision. */
|
|
21186
21199
|
getActionStatus(requestId) {
|
|
21187
21200
|
return this.get(`/admin/debug/actions/${encodeURIComponent(requestId)}`);
|
|
@@ -21259,7 +21272,14 @@ var requestConfigUpdateSchema = external_exports.object({
|
|
|
21259
21272
|
reason: external_exports.string().min(1).max(2e3).describe("Why this change is needed \u2014 shown verbatim to the human approver. Be specific.")
|
|
21260
21273
|
});
|
|
21261
21274
|
var checkActionStatusSchema = external_exports.object({
|
|
21262
|
-
request_id: external_exports.string().min(1).max(64).describe("The action request_id returned by request_action or
|
|
21275
|
+
request_id: external_exports.string().min(1).max(64).describe("The action request_id returned by request_action, request_config_update, or request_ssm_run.")
|
|
21276
|
+
});
|
|
21277
|
+
var requestSsmRunSchema = external_exports.object({
|
|
21278
|
+
target_agent_id: external_exports.string().min(1).max(64).describe("UUID of the customer agent whose host to run the diagnostic on."),
|
|
21279
|
+
command: external_exports.enum(["host_health", "manager_status", "manager_journal", "process_list", "agent_dir"]).describe(
|
|
21280
|
+
"The allowlisted, READ-ONLY diagnostic to run (closed set \u2014 no free-form shell). host_health = uptime + df -h + free -m (is the box wedged / out of disk / out of memory?); manager_status = systemctl status agt-manager.service (is the manager daemon up?); manager_journal = journalctl -u agt-manager.service -n 200 (recent systemd-captured manager output); process_list = ps (pid/ppid/user/etime/rss/comm, no argv/env) filtered to claude + agt-manager; agent_dir = ls -la ~/.augmented/<code_name>/ (file NAMES only \u2014 stuck markers, state files; never contents). For file CONTENTS use debug_tail_logs (it covers manager.log/pane.log/channel-stderr/manager-state.json)."
|
|
21281
|
+
),
|
|
21282
|
+
reason: external_exports.string().min(1).max(2e3).describe("Why this diagnostic is needed \u2014 shown verbatim to the human approver. Be specific.")
|
|
21263
21283
|
});
|
|
21264
21284
|
var queryAuditLogSchema = external_exports.object({
|
|
21265
21285
|
agent_id: external_exports.string().min(1).max(64).optional().describe(
|
|
@@ -21498,9 +21518,26 @@ server.tool(
|
|
|
21498
21518
|
}
|
|
21499
21519
|
}
|
|
21500
21520
|
);
|
|
21521
|
+
server.tool(
|
|
21522
|
+
"request_ssm_run",
|
|
21523
|
+
"Request a HITL-gated, ALLOWLISTED read-only DIAGNOSTIC command on a customer agent's host over SSM \u2014 the escape hatch for host/process/service facts the typed read tools (debug_get_agent, debug_tail_logs, debug_host_versions) don't cover. A HUMAN must approve the EXACT command in Slack before it runs, and only if writes are armed (shadow mode runs the approval but executes nothing). This is NOT a shell: `command` is a CLOSED enum \u2014 host_health (uptime/df/free), manager_status (systemctl status agt-manager), manager_journal (journalctl -n 200), process_list (ps comm-only, no argv/env), agent_dir (ls -la ~/.augmented/<code_name>/, names only). No free-form commands, no file-content reads (use debug_tail_logs for log contents). Async: returns { request_id, status, write_mode, command_key, resolved_command, notification_status }; after approval, poll check_action_status to read the command OUTPUT in result_payload. Pass { target_agent_id, command, reason }.",
|
|
21524
|
+
requestSsmRunSchema.shape,
|
|
21525
|
+
async (args) => {
|
|
21526
|
+
try {
|
|
21527
|
+
const result = await client.requestSsmRun({
|
|
21528
|
+
target_agent_id: args.target_agent_id,
|
|
21529
|
+
command: args.command,
|
|
21530
|
+
reason: args.reason
|
|
21531
|
+
});
|
|
21532
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
21533
|
+
} catch (err) {
|
|
21534
|
+
return { content: [{ type: "text", text: formatError2(err) }], isError: true };
|
|
21535
|
+
}
|
|
21536
|
+
}
|
|
21537
|
+
);
|
|
21501
21538
|
server.tool(
|
|
21502
21539
|
"check_action_status",
|
|
21503
|
-
"Poll the decision on a remedial action you requested (the approval result is also pushed to you via direct-chat). Returns { status, result_payload, denial_reason, resolved_at }. Pass { request_id }.",
|
|
21540
|
+
"Poll the decision on a remedial action you requested (the approval result is also pushed to you via direct-chat). Returns { status, result_payload, denial_reason, resolved_at } \u2014 for an approved request_ssm_run, result_payload carries the command output. Pass { request_id }.",
|
|
21504
21541
|
checkActionStatusSchema.shape,
|
|
21505
21542
|
async (args) => {
|
|
21506
21543
|
try {
|
|
@@ -14547,6 +14547,13 @@ function channelBusyAckThresholdMs() {
|
|
|
14547
14547
|
const raw = parseInt(process.env.AGT_CHANNEL_BUSY_ACK_THRESHOLD_MS ?? "", 10);
|
|
14548
14548
|
return Number.isFinite(raw) && raw > 0 ? raw : BUSY_ACK_THRESHOLD_MS;
|
|
14549
14549
|
}
|
|
14550
|
+
function channelSkipReactionEnabled() {
|
|
14551
|
+
return resolveHostBooleanFlag({
|
|
14552
|
+
key: "channel-skip-reaction",
|
|
14553
|
+
envVar: "AGT_CHANNEL_SKIP_REACTION_ENABLED",
|
|
14554
|
+
defaultValue: false
|
|
14555
|
+
});
|
|
14556
|
+
}
|
|
14550
14557
|
function decideBusyAck(i) {
|
|
14551
14558
|
if (!i.hasTarget) return false;
|
|
14552
14559
|
if (!i.stillPending) return false;
|
|
@@ -16607,6 +16614,8 @@ var BLOCK_KIT_ASK_USER_ENABLED = process.env.SLACK_BLOCK_KIT_ASK_USER_ENABLED ==
|
|
|
16607
16614
|
var BLOCK_KIT_DISABLED = process.env.SLACK_BLOCK_KIT_DISABLED === "true";
|
|
16608
16615
|
var ALLOWED_USERS = parseAllowedUsersCsv(process.env.SLACK_ALLOWED_USERS);
|
|
16609
16616
|
var THREAD_AUTO_FOLLOW = process.env.SLACK_THREAD_AUTO_FOLLOW ?? "off";
|
|
16617
|
+
var SLACK_SKIP_REACTION = (process.env.SLACK_SKIP_REACTION ?? "").trim();
|
|
16618
|
+
var SLACK_ACK_REACTION = (process.env.SLACK_ACK_REACTION ?? "").trim() || "eyes";
|
|
16610
16619
|
var CHANNEL_RESPONSE_MODE = parseResponseMode(process.env.SLACK_CHANNEL_RESPONSE_MODE);
|
|
16611
16620
|
var SLACK_PEER_DISABLED_MODE = (() => {
|
|
16612
16621
|
const raw = (process.env.PEER_DISABLED ?? "").trim().toLowerCase();
|
|
@@ -16773,7 +16782,7 @@ function healSlackUndeliverable(channel, messageTs) {
|
|
|
16773
16782
|
fetch("https://slack.com/api/reactions.add", {
|
|
16774
16783
|
method: "POST",
|
|
16775
16784
|
headers,
|
|
16776
|
-
body: JSON.stringify({ channel, timestamp: messageTs, name:
|
|
16785
|
+
body: JSON.stringify({ channel, timestamp: messageTs, name: SLACK_ACK_REACTION })
|
|
16777
16786
|
}).catch(() => {
|
|
16778
16787
|
});
|
|
16779
16788
|
});
|
|
@@ -18145,6 +18154,7 @@ void resolveBotUserIdOrThrow().then((id) => {
|
|
|
18145
18154
|
);
|
|
18146
18155
|
if (authFailed) slackBotUserIdClient?.reportAuthHealth(false);
|
|
18147
18156
|
});
|
|
18157
|
+
var SKIP_REACTION_ON = channelSkipReactionEnabled() && SLACK_SKIP_REACTION.length > 0;
|
|
18148
18158
|
var mcp = new Server(
|
|
18149
18159
|
{ name: "slack", version: "0.1.0" },
|
|
18150
18160
|
{
|
|
@@ -18163,8 +18173,8 @@ var mcp = new Server(
|
|
|
18163
18173
|
"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.",
|
|
18164
18174
|
"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.",
|
|
18165
18175
|
'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).',
|
|
18166
|
-
|
|
18167
|
-
`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.`,
|
|
18176
|
+
`Reaction taxonomy (use slack.react sparingly \u2014 prefer a reply): :${SLACK_ACK_REACTION}: = ack (already auto-added on inbound, do not duplicate); \u2705 = success.` + (SKIP_REACTION_ON ? ` "${SLACK_SKIP_REACTION}" = seen but not replying (see below).` : "") + " NEVER react to signal failure of YOUR work \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). (The \u23F3 you may see on an inbound is applied by the system, not you \u2014 it marks a message that arrived while the agent couldn't reply; never add \u23F3 or \u274C yourself.)",
|
|
18177
|
+
SKIP_REACTION_ON ? `When you read a DM or thread message and decide NOT to reply (different @-mention, side conversation, auto_followed catch-up, or simply nothing useful to add): call slack.react with emoji "${SLACK_SKIP_REACTION}" so the sender knows you saw it \u2014 never post a "this wasn't for me" message. Top-level channel messages (not a DM, not a thread reply) you may still skip silently.` : `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.`,
|
|
18168
18178
|
"To deliver a file: save under your project dir, call slack.upload_file with path + channel + thread_ts."
|
|
18169
18179
|
].join(" ")
|
|
18170
18180
|
}
|
|
@@ -19777,7 +19787,7 @@ async function connectSocketMode() {
|
|
|
19777
19787
|
);
|
|
19778
19788
|
}
|
|
19779
19789
|
if (ackDecision !== "none") {
|
|
19780
|
-
const reactionName = ackDecision === "undeliverable" ? SLACK_UNDELIVERABLE_REACTION :
|
|
19790
|
+
const reactionName = ackDecision === "undeliverable" ? SLACK_UNDELIVERABLE_REACTION : SLACK_ACK_REACTION;
|
|
19781
19791
|
fetch("https://slack.com/api/reactions.add", {
|
|
19782
19792
|
method: "POST",
|
|
19783
19793
|
headers: {
|
|
@@ -16198,6 +16198,13 @@ function channelBusyAckThresholdMs() {
|
|
|
16198
16198
|
const raw = parseInt(process.env.AGT_CHANNEL_BUSY_ACK_THRESHOLD_MS ?? "", 10);
|
|
16199
16199
|
return Number.isFinite(raw) && raw > 0 ? raw : BUSY_ACK_THRESHOLD_MS;
|
|
16200
16200
|
}
|
|
16201
|
+
function channelSkipReactionEnabled() {
|
|
16202
|
+
return resolveHostBooleanFlag({
|
|
16203
|
+
key: "channel-skip-reaction",
|
|
16204
|
+
envVar: "AGT_CHANNEL_SKIP_REACTION_ENABLED",
|
|
16205
|
+
defaultValue: false
|
|
16206
|
+
});
|
|
16207
|
+
}
|
|
16201
16208
|
function decideBusyAck(i) {
|
|
16202
16209
|
if (!i.hasTarget) return false;
|
|
16203
16210
|
if (!i.stillPending) return false;
|
|
@@ -16506,7 +16513,8 @@ function telegramApiCall(method, body, timeoutMs) {
|
|
|
16506
16513
|
req.end();
|
|
16507
16514
|
});
|
|
16508
16515
|
}
|
|
16509
|
-
var ACK_EMOJI = "\u{1F440}";
|
|
16516
|
+
var ACK_EMOJI = (process.env.TELEGRAM_ACK_REACTION ?? "").trim() || "\u{1F440}";
|
|
16517
|
+
var TELEGRAM_SKIP_REACTION = (process.env.TELEGRAM_SKIP_REACTION ?? "").trim();
|
|
16510
16518
|
async function setMessageReaction(chatId, messageId, emoji2) {
|
|
16511
16519
|
try {
|
|
16512
16520
|
const resp = await telegramApiCall(
|
|
@@ -17698,6 +17706,7 @@ function noteThreadActivity(chatId, cutoffMs = Number.POSITIVE_INFINITY) {
|
|
|
17698
17706
|
if (!chatId) return;
|
|
17699
17707
|
clearPendingMessage(chatId, cutoffMs);
|
|
17700
17708
|
}
|
|
17709
|
+
var SKIP_REACTION_ON = channelSkipReactionEnabled() && TELEGRAM_SKIP_REACTION.length > 0;
|
|
17701
17710
|
var mcp = new Server(
|
|
17702
17711
|
{ name: "telegram", version: "0.1.0" },
|
|
17703
17712
|
{
|
|
@@ -17716,8 +17725,9 @@ var mcp = new Server(
|
|
|
17716
17725
|
"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 telegram.download_attachment. Use that tool only for entries with `file_id` but NO `path` (PDF, docx, voice, audio, video, animations): pass file_id + chat_id verbatim, then Read the returned path. Single-image messages also get a top-level `image_path`. Caption arrives as channel content. Don't surface internal file-handling errors that don't affect the answer.",
|
|
17717
17726
|
'For work >30s follow CLAUDE.md kanban flow: kanban_add \u2192 reply "On it \u2014 tracking here: <kanban URL>" \u2192 move to in_progress \u2192 do the work \u2192 reply with the result. Simple lookups skip kanban but still reply.',
|
|
17718
17727
|
"Address users by user_name; user is the numeric Telegram ID. Resolve ambiguous times against your own Timezone from CLAUDE.md \u2014 do not ask.",
|
|
17719
|
-
|
|
17720
|
-
|
|
17728
|
+
"Reaction taxonomy (use telegram.react sparingly \u2014 prefer telegram.reply): \u{1F440} = ack (already auto-added on inbound, do not duplicate); \u{1F44D} or \u{1F389} = success." + (SKIP_REACTION_ON ? ` ${TELEGRAM_SKIP_REACTION} = seen but not replying (see below).` : "") + ` NEVER react to signal failure of YOUR work. On failure, telegram.reply with one sentence explaining what went wrong. Free-tier emoji: \u{1F44D} \u{1F44E} \u2764 \u{1F525} \u{1F389} \u{1F914} \u{1F92F} \u{1F64F} \u{1F44C} \u{1F440} \u{1F4AF} \u270D \u{1FAE1} \u{1F192} \u{1F973} \u{1F494}. (If a message arrived while you were offline you may see a system-posted "can't respond right now" notice \u2014 that's the runtime, not you; don't repeat or apologise for it.)`,
|
|
17729
|
+
SKIP_REACTION_ON ? `When you read a message you decide NOT to reply to (nothing useful to add): call telegram.react with emoji "${TELEGRAM_SKIP_REACTION}" so the sender knows you saw it \u2014 never post a "this wasn't for me" message.` : ""
|
|
17730
|
+
].filter(Boolean).join(" ")
|
|
17721
17731
|
}
|
|
17722
17732
|
);
|
|
17723
17733
|
mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
@@ -25,8 +25,8 @@ import {
|
|
|
25
25
|
takeZombieDetection,
|
|
26
26
|
writeDirectChatSessionState,
|
|
27
27
|
writePersistentClaudeWrapper
|
|
28
|
-
} from "./chunk-
|
|
29
|
-
import "./chunk-
|
|
28
|
+
} from "./chunk-UVE6VSU3.js";
|
|
29
|
+
import "./chunk-ONG7KSRP.js";
|
|
30
30
|
import "./chunk-XWVM4KPK.js";
|
|
31
31
|
export {
|
|
32
32
|
SEND_KEYS_ENTER_DELAY_MS,
|
|
@@ -56,4 +56,4 @@ export {
|
|
|
56
56
|
writeDirectChatSessionState,
|
|
57
57
|
writePersistentClaudeWrapper
|
|
58
58
|
};
|
|
59
|
-
//# sourceMappingURL=persistent-session-
|
|
59
|
+
//# sourceMappingURL=persistent-session-Q73X7PPM.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
paneLogPath
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-UVE6VSU3.js";
|
|
4
|
+
import "./chunk-ONG7KSRP.js";
|
|
5
5
|
import "./chunk-XWVM4KPK.js";
|
|
6
6
|
|
|
7
7
|
// src/lib/responsiveness-probe.ts
|
|
@@ -250,4 +250,4 @@ export {
|
|
|
250
250
|
parkPendingInbound,
|
|
251
251
|
readAndResetChannelDeflections
|
|
252
252
|
};
|
|
253
|
-
//# sourceMappingURL=responsiveness-probe-
|
|
253
|
+
//# sourceMappingURL=responsiveness-probe-R7WZXP2Y.js.map
|