@integrity-labs/agt-cli 0.28.811 → 0.28.813
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 +5 -5
- package/dist/{chunk-GBSP65E7.js → chunk-IABI5AX5.js} +6 -6
- package/dist/chunk-IABI5AX5.js.map +1 -0
- package/dist/{chunk-SBRKT2AV.js → chunk-Y33QUAGQ.js} +3 -3
- package/dist/{chunk-SBRKT2AV.js.map → chunk-Y33QUAGQ.js.map} +1 -1
- package/dist/{chunk-NSTXVHVG.js → chunk-YCE5BY6D.js} +5 -5
- package/dist/chunk-YCE5BY6D.js.map +1 -0
- package/dist/{claude-pair-runtime-WAXQINIW.js → claude-pair-runtime-HFNDYS4V.js} +2 -2
- package/dist/lib/manager-worker.js +13 -13
- package/dist/mcp/augmented-support.js +4 -4
- package/dist/mcp/direct-chat-channel.js +1 -1
- package/dist/mcp/index.js +4 -4
- package/dist/mcp/slack-channel.js +52 -36
- package/dist/mcp/telegram-channel.js +10 -7
- package/dist/{persistent-session-LYJCGKH3.js → persistent-session-5XVEPXBT.js} +3 -3
- package/dist/{responsiveness-probe-XRSACVMN.js → responsiveness-probe-7LZMXEWA.js} +3 -3
- package/dist/{session-auth-dead-Y6MASYWN.js → session-auth-dead-CDFUCZPH.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-GBSP65E7.js.map +0 -1
- package/dist/chunk-NSTXVHVG.js.map +0 -1
- /package/dist/{claude-pair-runtime-WAXQINIW.js.map → claude-pair-runtime-HFNDYS4V.js.map} +0 -0
- /package/dist/{persistent-session-LYJCGKH3.js.map → persistent-session-5XVEPXBT.js.map} +0 -0
- /package/dist/{responsiveness-probe-XRSACVMN.js.map → responsiveness-probe-7LZMXEWA.js.map} +0 -0
- /package/dist/{session-auth-dead-Y6MASYWN.js.map → session-auth-dead-CDFUCZPH.js.map} +0 -0
|
@@ -100,7 +100,7 @@ async function spawnPairSession(session) {
|
|
|
100
100
|
return { ok: true };
|
|
101
101
|
} catch {
|
|
102
102
|
}
|
|
103
|
-
const { resolveClaudeBinary } = await import("./persistent-session-
|
|
103
|
+
const { resolveClaudeBinary } = await import("./persistent-session-5XVEPXBT.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-HFNDYS4V.js.map
|
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
safeWriteJsonAtomic,
|
|
59
59
|
setConfigHash,
|
|
60
60
|
tripClass
|
|
61
|
-
} from "../chunk-
|
|
61
|
+
} from "../chunk-YCE5BY6D.js";
|
|
62
62
|
import {
|
|
63
63
|
getProjectDir as getProjectDir2,
|
|
64
64
|
getReadyTasks,
|
|
@@ -123,7 +123,7 @@ import {
|
|
|
123
123
|
takeZombieDetection,
|
|
124
124
|
toOpencodeModel,
|
|
125
125
|
writeEgressAllowlist
|
|
126
|
-
} from "../chunk-
|
|
126
|
+
} from "../chunk-Y33QUAGQ.js";
|
|
127
127
|
import {
|
|
128
128
|
ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
|
|
129
129
|
AnchorSessionClient,
|
|
@@ -215,7 +215,7 @@ import {
|
|
|
215
215
|
subagentActivityAgeSeconds,
|
|
216
216
|
sumTranscriptUsageInWindow,
|
|
217
217
|
transcriptActivityAgeSeconds
|
|
218
|
-
} from "../chunk-
|
|
218
|
+
} from "../chunk-IABI5AX5.js";
|
|
219
219
|
import {
|
|
220
220
|
reapOrphanChannelMcps
|
|
221
221
|
} from "../chunk-XWVM4KPK.js";
|
|
@@ -12918,7 +12918,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
12918
12918
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
12919
12919
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
12920
12920
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
12921
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
12921
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-7LZMXEWA.js");
|
|
12922
12922
|
const newest = newestPendingInboundActivityMtimeMs(dirname10(paneLogPath(codeName)));
|
|
12923
12923
|
if (newest === null) return null;
|
|
12924
12924
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
@@ -13578,7 +13578,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
13578
13578
|
var lastVersionCheckAt = 0;
|
|
13579
13579
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
13580
13580
|
var lastResponsivenessProbeAt = 0;
|
|
13581
|
-
var agtCliVersion = true ? "0.28.
|
|
13581
|
+
var agtCliVersion = true ? "0.28.813" : "dev";
|
|
13582
13582
|
function resolveBrewPath(execFileSync2) {
|
|
13583
13583
|
try {
|
|
13584
13584
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -15125,7 +15125,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
15125
15125
|
if (codeNames.length === 0) return;
|
|
15126
15126
|
void (async () => {
|
|
15127
15127
|
try {
|
|
15128
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15128
|
+
const { collectDiagnostics } = await import("../persistent-session-5XVEPXBT.js");
|
|
15129
15129
|
await api.post("/host/heartbeat", {
|
|
15130
15130
|
host_id: hostId,
|
|
15131
15131
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -15266,7 +15266,7 @@ async function pollCycleInner() {
|
|
|
15266
15266
|
}
|
|
15267
15267
|
try {
|
|
15268
15268
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
15269
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15269
|
+
const { collectDiagnostics } = await import("../persistent-session-5XVEPXBT.js");
|
|
15270
15270
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
15271
15271
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor) : void 0;
|
|
15272
15272
|
let tailscaleHostname;
|
|
@@ -15435,7 +15435,7 @@ async function pollCycleInner() {
|
|
|
15435
15435
|
collectPanelessActivityProbes,
|
|
15436
15436
|
getResponsivenessIntervalMs,
|
|
15437
15437
|
occupancyQualificationClassifications
|
|
15438
|
-
} = await import("../responsiveness-probe-
|
|
15438
|
+
} = await import("../responsiveness-probe-7LZMXEWA.js");
|
|
15439
15439
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
15440
15440
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
15441
15441
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -15552,7 +15552,7 @@ async function pollCycleInner() {
|
|
|
15552
15552
|
collectResponsivenessProbes,
|
|
15553
15553
|
livePendingInboundOldestAgeSeconds,
|
|
15554
15554
|
parkPendingInbound
|
|
15555
|
-
} = await import("../responsiveness-probe-
|
|
15555
|
+
} = await import("../responsiveness-probe-7LZMXEWA.js");
|
|
15556
15556
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
15557
15557
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
15558
15558
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -15708,7 +15708,7 @@ async function pollCycleInner() {
|
|
|
15708
15708
|
}
|
|
15709
15709
|
try {
|
|
15710
15710
|
const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-JA437JIB.js");
|
|
15711
|
-
const { probeSessionAuth } = await import("../session-auth-dead-
|
|
15711
|
+
const { probeSessionAuth } = await import("../session-auth-dead-CDFUCZPH.js");
|
|
15712
15712
|
const observations = [];
|
|
15713
15713
|
const pendingCacheCommits = [];
|
|
15714
15714
|
const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
|
|
@@ -19868,7 +19868,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
19868
19868
|
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}`));
|
|
19869
19869
|
void (async () => {
|
|
19870
19870
|
try {
|
|
19871
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
19871
|
+
const { collectDiagnostics } = await import("../persistent-session-5XVEPXBT.js");
|
|
19872
19872
|
await api.post("/host/heartbeat", {
|
|
19873
19873
|
host_id: hostId,
|
|
19874
19874
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -19914,7 +19914,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
19914
19914
|
}
|
|
19915
19915
|
try {
|
|
19916
19916
|
const hostId = await getHostId();
|
|
19917
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
19917
|
+
const { collectDiagnostics } = await import("../persistent-session-5XVEPXBT.js");
|
|
19918
19918
|
await api.post("/host/heartbeat", {
|
|
19919
19919
|
host_id: hostId,
|
|
19920
19920
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -20550,7 +20550,7 @@ async function processClaudePairSessions(agents) {
|
|
|
20550
20550
|
killPairSession,
|
|
20551
20551
|
pairTmuxSession,
|
|
20552
20552
|
finalizeClaudePairOnboarding
|
|
20553
|
-
} = await import("../claude-pair-runtime-
|
|
20553
|
+
} = await import("../claude-pair-runtime-HFNDYS4V.js");
|
|
20554
20554
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
20555
20555
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
20556
20556
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -21173,10 +21173,10 @@ var fileRequestSchema = external_exports.object({
|
|
|
21173
21173
|
description: external_exports.string().min(1).describe("Full detail: what happened / what is wanted, and any reproduction steps."),
|
|
21174
21174
|
provider: external_exports.string().optional().describe('Optional provider/service name when asking for a new integration (e.g. "notion").'),
|
|
21175
21175
|
requester_email: external_exports.string().email().max(320).optional().describe(
|
|
21176
|
-
"The email of the person this request is for, so
|
|
21176
|
+
"The email of the person this request is for, so Ninjafy can email them when it's resolved. Only include an email they gave you and agreed to be contacted at - do NOT guess one."
|
|
21177
21177
|
),
|
|
21178
21178
|
requester_user_id: external_exports.string().uuid().optional().describe(
|
|
21179
|
-
"Optional
|
|
21179
|
+
"Optional Ninjafy user id (UUID) of the requester, used to look up their email for the resolved-notification when you have an id but not an address."
|
|
21180
21180
|
)
|
|
21181
21181
|
});
|
|
21182
21182
|
var searchKbSchema = external_exports.object({
|
|
@@ -21387,7 +21387,7 @@ server.tool(
|
|
|
21387
21387
|
);
|
|
21388
21388
|
server.tool(
|
|
21389
21389
|
"support_file_support_request",
|
|
21390
|
-
"File a BUG report to
|
|
21390
|
+
"File a BUG report to Ninjafy support when you hit a platform problem you cannot resolve from your own org (Ninjafy was formerly Augmented Team; either name means this platform). It goes to the Ninjafy support queue, not your org. Pass { title, description }. Returns { ok, status } - relay the outcome to the user.",
|
|
21391
21391
|
fileRequestSchema.shape,
|
|
21392
21392
|
async (args) => {
|
|
21393
21393
|
try {
|
|
@@ -21399,7 +21399,7 @@ server.tool(
|
|
|
21399
21399
|
);
|
|
21400
21400
|
server.tool(
|
|
21401
21401
|
"support_file_feature_request",
|
|
21402
|
-
'File a FEATURE or new-integration request to Augmented Team
|
|
21402
|
+
'File a FEATURE or new-integration request to Ninjafy support, formerly Augmented Team (goes to the support queue, not your org). Use `provider` for an integration ask (e.g. "notion"). Pass { title, description, provider? }. Returns { ok, status }.',
|
|
21403
21403
|
fileRequestSchema.shape,
|
|
21404
21404
|
async (args) => {
|
|
21405
21405
|
try {
|
|
@@ -38819,7 +38819,7 @@ function createKanbanCardActiveClient(args) {
|
|
|
38819
38819
|
|
|
38820
38820
|
// src/maintenance-mode.ts
|
|
38821
38821
|
var FLAG_KEY = "platform-maintenance-mode";
|
|
38822
|
-
var MAINTENANCE_OFFLINE_MESSAGE = "The
|
|
38822
|
+
var MAINTENANCE_OFFLINE_MESSAGE = "The Ninjafy platform is offline for scheduled maintenance right now, so I can't pick this up \u2014 please try again shortly.";
|
|
38823
38823
|
function isMaintenanceModeActive(opts) {
|
|
38824
38824
|
return resolveHostBooleanFlag({
|
|
38825
38825
|
key: FLAG_KEY,
|
package/dist/mcp/index.js
CHANGED
|
@@ -44658,7 +44658,7 @@ var FEATURE_REQUEST_TYPES = [
|
|
|
44658
44658
|
function describeFeatureRequestResult(resp) {
|
|
44659
44659
|
if (resp.status === "created") {
|
|
44660
44660
|
return {
|
|
44661
|
-
text: "Feature request submitted to
|
|
44661
|
+
text: "Feature request submitted to Ninjafy support.",
|
|
44662
44662
|
isError: false
|
|
44663
44663
|
};
|
|
44664
44664
|
}
|
|
@@ -46351,7 +46351,7 @@ server.tool(
|
|
|
46351
46351
|
);
|
|
46352
46352
|
server.tool(
|
|
46353
46353
|
"request_feature",
|
|
46354
|
-
'Send a feature request to Augmented Team
|
|
46354
|
+
'Send a feature request to Ninjafy support (formerly Augmented Team \u2014 the same platform either way, so use this whichever name the user says) \u2014 most often to ask for a NEW third-party integration that is not in your toolkit yet (set feature_type="integration" and put the service name in provider). Also accepts general product feedback (other feature_type values). Use this when a user needs a capability you do not have and that you cannot configure yourself. Do not use it for things you can already do or set up. If the request came from a specific end user, you can pass their requester_email (only with their consent) so Ninjafy can email them directly when it is resolved.',
|
|
46355
46355
|
{
|
|
46356
46356
|
feature_type: external_exports.enum(FEATURE_REQUEST_TYPES).describe(
|
|
46357
46357
|
'What kind of request this is. Use "integration" to ask for a new third-party integration/toolkit; otherwise: tool, channel, capability, bug, or other.'
|
|
@@ -46367,10 +46367,10 @@ server.tool(
|
|
|
46367
46367
|
"ENG-9246. Leave this unset on a first attempt. If your request is declined because Augmented already sells the capability, the reply names the integration and the request_integration_access call to make instead \u2014 do that. Only set this to true, and say why in the description, when the customer genuinely needs a DIFFERENT vendor rather than the capability itself. It does not make a stronger case; it just records that you checked."
|
|
46368
46368
|
),
|
|
46369
46369
|
requester_email: external_exports.string().email().max(320).optional().describe(
|
|
46370
|
-
"The email address of the end user who asked for this, so
|
|
46370
|
+
"The email address of the end user who asked for this, so Ninjafy can email them when it is resolved. Only include an email the user has given you and agreed to be contacted at - do NOT guess or invent one. Omit if you don't have their consent or an address."
|
|
46371
46371
|
),
|
|
46372
46372
|
requester_user_id: external_exports.string().uuid().optional().describe(
|
|
46373
|
-
"Optional
|
|
46373
|
+
"Optional Ninjafy user id (UUID) of the requester, used to look up their email for the resolved-notification when you have an id but not an address. Omit unless you know the actual Ninjafy user id."
|
|
46374
46374
|
)
|
|
46375
46375
|
},
|
|
46376
46376
|
async (params) => {
|
|
@@ -23330,6 +23330,38 @@ ${forwarded.text}` : forwarded.text;
|
|
|
23330
23330
|
};
|
|
23331
23331
|
}
|
|
23332
23332
|
|
|
23333
|
+
// src/help-command-syntax.ts
|
|
23334
|
+
var SLACK_COMMAND_MAX_LENGTH = 32;
|
|
23335
|
+
function agentSlashCommand(base, rawCodeName) {
|
|
23336
|
+
const codeName = rawCodeName?.trim().toLowerCase();
|
|
23337
|
+
if (!codeName || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(codeName)) return base;
|
|
23338
|
+
const suffixed = `${base}-${codeName}`;
|
|
23339
|
+
return suffixed.length > SLACK_COMMAND_MAX_LENGTH ? base : suffixed;
|
|
23340
|
+
}
|
|
23341
|
+
function stripLeadingSlackMention(text) {
|
|
23342
|
+
return text.replace(/^\s*<@[^>]+>\s*/, "").trim();
|
|
23343
|
+
}
|
|
23344
|
+
function isSlackHelpCommand(text, helpSuffixed) {
|
|
23345
|
+
const stripped = stripLeadingSlackMention(text);
|
|
23346
|
+
return stripped === "/help" || stripped.startsWith("/help ") || stripped === helpSuffixed || stripped.startsWith(`${helpSuffixed} `);
|
|
23347
|
+
}
|
|
23348
|
+
function buildSlackHelpMessage(codeName, rawCodeName) {
|
|
23349
|
+
const cmd = (base) => agentSlashCommand(base, rawCodeName);
|
|
23350
|
+
return [
|
|
23351
|
+
`\u{1F916} *Available commands for \`${codeName}\`*`,
|
|
23352
|
+
"",
|
|
23353
|
+
"All commands are real Slack slash commands (autocomplete via `/`). For backward compatibility, `/help` and the restart command can also be typed as plain messages in any channel where the bot is present:",
|
|
23354
|
+
`\u2022 \`${cmd("/help")}\` (or type \`/help\`) \u2014 show this help`,
|
|
23355
|
+
`\u2022 \`${cmd("/restart")}\` \u2014 restart this agent`,
|
|
23356
|
+
`\u2022 \`${cmd("/onboard")}\` \u2014 re-run this agent's onboarding: re-interview, existing config kept (allowlisted users)`,
|
|
23357
|
+
`\u2022 \`${cmd("/resume-onboarding")}\` \u2014 resume this agent's onboarding where it left off (allowlisted users)`,
|
|
23358
|
+
`\u2022 \`${cmd("/status")}\` - full health report: model, session, uptime + per-channel and per-integration status (cached snapshot, then this channel's own live check)`,
|
|
23359
|
+
`\u2022 \`${cmd("/ping")}\` - confirm this agent's channel is connected: posts a visible pong (team + manager only)`,
|
|
23360
|
+
"\u2022 `/watch <google-doc-url> [duration]` (type it in chat) \u2014 watch a Google Doc for comments that mention me (default 2h, max 7d; auto-pauses when the window ends). In a shared channel, address me as `/watch-<my-name>`.",
|
|
23361
|
+
`\u2022 \`${cmd("/investigate")}\` \u2014 live tail of this agent's terminal pane (DM only, allowlisted users; works while the channel process is alive \u2014 a wedged host still needs SSM diagnostics)`
|
|
23362
|
+
].join("\n");
|
|
23363
|
+
}
|
|
23364
|
+
|
|
23333
23365
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v4/core/core.js
|
|
23334
23366
|
var NEVER = Object.freeze({
|
|
23335
23367
|
status: "aborted"
|
|
@@ -30659,7 +30691,7 @@ function resolveSlackScheduledChannelGuardMode(opts) {
|
|
|
30659
30691
|
|
|
30660
30692
|
// src/maintenance-mode.ts
|
|
30661
30693
|
var FLAG_KEY = "platform-maintenance-mode";
|
|
30662
|
-
var MAINTENANCE_OFFLINE_MESSAGE = "The
|
|
30694
|
+
var MAINTENANCE_OFFLINE_MESSAGE = "The Ninjafy platform is offline for scheduled maintenance right now, so I can't pick this up \u2014 please try again shortly.";
|
|
30663
30695
|
function isMaintenanceModeActive(opts) {
|
|
30664
30696
|
return resolveHostBooleanFlag({
|
|
30665
30697
|
key: FLAG_KEY,
|
|
@@ -41407,7 +41439,7 @@ function resolveSlackInboundDir(codeName) {
|
|
|
41407
41439
|
function explainSlackFileAccessError(stage, detail) {
|
|
41408
41440
|
if (stage === "files.info") {
|
|
41409
41441
|
if (detail === "missing_scope") {
|
|
41410
|
-
return "the bot token lacks the files:read OAuth scope; add it to the Slack app (
|
|
41442
|
+
return "the bot token lacks the files:read OAuth scope; add it to the Slack app (Ninjafy installs include it by default) and reinstall the app";
|
|
41411
41443
|
}
|
|
41412
41444
|
if (detail === "file_not_found" || detail === "not_visible" || detail === "access_denied") {
|
|
41413
41445
|
return "Slack reports this for files the bot token cannot access, not only for deleted files. If the file was uploaded by another (peer) agent, verify this bot has the files:read scope and is a member of the conversation where the file was shared";
|
|
@@ -42473,11 +42505,11 @@ function parseTeamPeerUserIdsEnv(raw) {
|
|
|
42473
42505
|
function reasonGuidance(reason) {
|
|
42474
42506
|
switch (reason) {
|
|
42475
42507
|
case "mode_off":
|
|
42476
|
-
return "Peer collaboration is off for this agent (peer_agent_mode). Enable it in the
|
|
42508
|
+
return "Peer collaboration is off for this agent (peer_agent_mode). Enable it in the Ninjafy console: Agent > Channels > Slack > Advanced > Multi-agent collaboration (set mode to listen/respond and add this channel to the allowed channels), then declare the peer under CHARTER multi_agent.slack_peers.";
|
|
42477
42509
|
case "chat_not_allowed":
|
|
42478
|
-
return "Peer collaboration is on but this channel is not in peer_group_ids. Add it in the
|
|
42510
|
+
return "Peer collaboration is on but this channel is not in peer_group_ids. Add it in the Ninjafy console: Agent > Channels > Slack > Advanced > Multi-agent collaboration > allowed channels.";
|
|
42479
42511
|
case "unknown_peer":
|
|
42480
|
-
return "Peer collaboration is on but this sender is not a declared peer. Declare it under CHARTER multi_agent.slack_peers (Agent > Charter in the
|
|
42512
|
+
return "Peer collaboration is on but this sender is not a declared peer. Declare it under CHARTER multi_agent.slack_peers (Agent > Charter in the Ninjafy console) with the peer agent's code_name and bot_user_id.";
|
|
42481
42513
|
default:
|
|
42482
42514
|
return "";
|
|
42483
42515
|
}
|
|
@@ -42489,7 +42521,7 @@ function maybePeerEnablementHint(args) {
|
|
|
42489
42521
|
const key2 = `${channel}:${senderUserId}`;
|
|
42490
42522
|
if (seen.has(key2)) return null;
|
|
42491
42523
|
seen.add(key2);
|
|
42492
|
-
return `slack-channel(${agentCodeName}): [peer-hint] dropped a message from same-team agent ${senderUserId} (reason=${reason}) in channel ${channelHash}. Another
|
|
42524
|
+
return `slack-channel(${agentCodeName}): [peer-hint] dropped a message from same-team agent ${senderUserId} (reason=${reason}) in channel ${channelHash}. Another Ninjafy managed agent is posting in this channel, but this agent cannot see it. ${reasonGuidance(reason)} This hint is logged once per channel/peer.`;
|
|
42493
42525
|
}
|
|
42494
42526
|
|
|
42495
42527
|
// src/cross-team-peer-audit-client.ts
|
|
@@ -43052,15 +43084,11 @@ var BOT_TOKEN = process.env.SLACK_BOT_TOKEN;
|
|
|
43052
43084
|
var APP_TOKEN = process.env.SLACK_APP_TOKEN;
|
|
43053
43085
|
var AGENT_CODE_NAME = process.env.AGT_AGENT_CODE_NAME ?? null;
|
|
43054
43086
|
var AGENT_AVATAR_URL = process.env.SLACK_AGENT_AVATAR_URL?.trim() || null;
|
|
43055
|
-
|
|
43056
|
-
|
|
43057
|
-
const codeName = AGENT_CODE_NAME?.trim().toLowerCase();
|
|
43058
|
-
if (!codeName || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(codeName)) return base;
|
|
43059
|
-
const suffixed = `${base}-${codeName}`;
|
|
43060
|
-
return suffixed.length > SLACK_COMMAND_MAX_LENGTH ? base : suffixed;
|
|
43087
|
+
function agentSlashCommand3(base) {
|
|
43088
|
+
return agentSlashCommand(base, AGENT_CODE_NAME);
|
|
43061
43089
|
}
|
|
43062
43090
|
function matchesAgentCommand(command, base) {
|
|
43063
|
-
return command === base || command ===
|
|
43091
|
+
return command === base || command === agentSlashCommand3(base);
|
|
43064
43092
|
}
|
|
43065
43093
|
var AGT_HOST = process.env.AGT_HOST ?? null;
|
|
43066
43094
|
var AGT_API_KEY = process.env.AGT_API_KEY ?? null;
|
|
@@ -45019,20 +45047,8 @@ async function postSlackMessage(body) {
|
|
|
45019
45047
|
return { ok: false, error: isTimeout ? "timeout" : err.message };
|
|
45020
45048
|
}
|
|
45021
45049
|
}
|
|
45022
|
-
function
|
|
45023
|
-
return
|
|
45024
|
-
`\u{1F916} *Available commands for \`${codeName}\`*`,
|
|
45025
|
-
"",
|
|
45026
|
-
"All commands are real Slack slash commands (autocomplete via `/`). For backward compatibility, `/help` and the restart command can also be typed as plain messages in any channel where the bot is present:",
|
|
45027
|
-
`\u2022 \`${agentSlashCommand2("/help")}\` (or type \`/help\`) \u2014 show this help`,
|
|
45028
|
-
`\u2022 \`${agentSlashCommand2("/restart")}\` \u2014 restart this agent`,
|
|
45029
|
-
`\u2022 \`${agentSlashCommand2("/onboard")}\` \u2014 re-run this agent's onboarding: re-interview, existing config kept (allowlisted users)`,
|
|
45030
|
-
`\u2022 \`${agentSlashCommand2("/resume-onboarding")}\` \u2014 resume this agent's onboarding where it left off (allowlisted users)`,
|
|
45031
|
-
`\u2022 \`${agentSlashCommand2("/status")}\` - full health report: model, session, uptime + per-channel and per-integration status (cached snapshot, then this channel's own live check)`,
|
|
45032
|
-
`\u2022 \`${agentSlashCommand2("/ping")}\` - confirm this agent's channel is connected: posts a visible pong (team + manager only)`,
|
|
45033
|
-
"\u2022 `/watch <google-doc-url> [duration]` (type it in chat) \u2014 watch a Google Doc for comments that mention me (default 2h, max 7d; auto-pauses when the window ends). In a shared channel, address me as `/watch-<my-name>`.",
|
|
45034
|
-
`\u2022 \`${agentSlashCommand2("/investigate")}\` \u2014 live tail of this agent's terminal pane (DM only, allowlisted users; works while the channel process is alive \u2014 a wedged host still needs SSM diagnostics)`
|
|
45035
|
-
].join("\n");
|
|
45050
|
+
function buildSlackHelpMessage2(codeName) {
|
|
45051
|
+
return buildSlackHelpMessage(codeName, AGENT_CODE_NAME);
|
|
45036
45052
|
}
|
|
45037
45053
|
var lastActivityAt = null;
|
|
45038
45054
|
var lastActivityKind = null;
|
|
@@ -45214,7 +45230,7 @@ async function handleNotifyCommand(payload, codeName) {
|
|
|
45214
45230
|
`);
|
|
45215
45231
|
await postEphemeralViaResponseUrl(
|
|
45216
45232
|
responseUrl,
|
|
45217
|
-
`\u{1F6AB} \`/notify\` is limited to \`${codeName}\`'s team and the person it reports to. If that's you, link your Slack in your
|
|
45233
|
+
`\u{1F6AB} \`/notify\` is limited to \`${codeName}\`'s team and the person it reports to. If that's you, link your Slack in your Ninjafy contact preferences and wait for the next refresh.`,
|
|
45218
45234
|
codeName
|
|
45219
45235
|
);
|
|
45220
45236
|
return;
|
|
@@ -45422,7 +45438,7 @@ async function runDebugTailLoop(opts) {
|
|
|
45422
45438
|
capturedAtLabel: last.capturedAtLabel,
|
|
45423
45439
|
status: { kind: "expired" },
|
|
45424
45440
|
// ENG-6044: advertise the renamed command in the expired header.
|
|
45425
|
-
commandName:
|
|
45441
|
+
commandName: agentSlashCommand3("/investigate")
|
|
45426
45442
|
})
|
|
45427
45443
|
);
|
|
45428
45444
|
}
|
|
@@ -45434,7 +45450,7 @@ async function handleDebugSlashCommand(payload, responseUrl) {
|
|
|
45434
45450
|
userId: payload.user_id,
|
|
45435
45451
|
allowedUsers: getEffectiveAllowedUsers()
|
|
45436
45452
|
});
|
|
45437
|
-
const investigateCmd =
|
|
45453
|
+
const investigateCmd = agentSlashCommand3("/investigate");
|
|
45438
45454
|
if (!verdict.ok) {
|
|
45439
45455
|
debugAuditLog(`denied reason=${verdict.reason} user=${payload.user_id ?? "unknown"}`);
|
|
45440
45456
|
const denialText = verdict.reason === "not-dm" ? `:warning: \`${investigateCmd}\` only works in a direct message with \`${codeName}\` \u2014 it shows the agent's raw terminal, so it stays 1:1. Open a DM with the bot and run \`${investigateCmd}\` there.` : verdict.reason === "allowlist-empty" ? `\u{1F6AB} \`${investigateCmd}\` is disabled for \`${codeName}\` \u2014 no diagnostic allowlist is configured. Because it exposes the agent's raw terminal, \`${investigateCmd}\` requires a non-empty \`SLACK_ALLOWED_USERS\` on the host (unlike the restart command, it does not open up when the allowlist is unset).` : `\u{1F6AB} \`${investigateCmd}\` denied \u2014 your Slack user isn't on the diagnostic allowlist for \`${codeName}\`. Ask whoever operates this host to add you to \`SLACK_ALLOWED_USERS\`.`;
|
|
@@ -45534,7 +45550,7 @@ async function handleSlashCommandEnvelope(payload) {
|
|
|
45534
45550
|
return;
|
|
45535
45551
|
}
|
|
45536
45552
|
if (matchesAgentCommand(command, "/help")) {
|
|
45537
|
-
await postEphemeralViaResponseUrl(responseUrl,
|
|
45553
|
+
await postEphemeralViaResponseUrl(responseUrl, buildSlackHelpMessage2(codeName), codeName);
|
|
45538
45554
|
return;
|
|
45539
45555
|
}
|
|
45540
45556
|
if (matchesAgentCommand(command, "/restart")) {
|
|
@@ -45657,7 +45673,7 @@ async function handleSlashCommandEnvelope(payload) {
|
|
|
45657
45673
|
);
|
|
45658
45674
|
await postEphemeralViaResponseUrl(
|
|
45659
45675
|
responseUrl,
|
|
45660
|
-
`\u{1F6AB} \`/ping\` is limited to \`${codeName}\`'s team and the person it reports to. If that's you, link your Slack in your
|
|
45676
|
+
`\u{1F6AB} \`/ping\` is limited to \`${codeName}\`'s team and the person it reports to. If that's you, link your Slack in your Ninjafy contact preferences and wait for the next refresh.`,
|
|
45661
45677
|
codeName
|
|
45662
45678
|
);
|
|
45663
45679
|
return;
|
|
@@ -45686,7 +45702,7 @@ async function handleHelpCommand(opts) {
|
|
|
45686
45702
|
const replyThread = opts.threadTs ?? opts.ts;
|
|
45687
45703
|
const ack = await postSlackMessage({
|
|
45688
45704
|
channel: opts.channel,
|
|
45689
|
-
text:
|
|
45705
|
+
text: buildSlackHelpMessage2(codeName),
|
|
45690
45706
|
...replyThread ? { thread_ts: replyThread } : {}
|
|
45691
45707
|
});
|
|
45692
45708
|
if (!ack.ok) {
|
|
@@ -48106,10 +48122,10 @@ async function connectSocketMode() {
|
|
|
48106
48122
|
) : void 0;
|
|
48107
48123
|
const rawText = evt.text ?? "";
|
|
48108
48124
|
const strippedText = rawText.replace(/^\s*<@[^>]+>\s*/, "").trim();
|
|
48109
|
-
const restartSuffixed =
|
|
48110
|
-
const helpSuffixed =
|
|
48125
|
+
const restartSuffixed = agentSlashCommand3("/restart");
|
|
48126
|
+
const helpSuffixed = agentSlashCommand3("/help");
|
|
48111
48127
|
const isRestartCommand = strippedText === "/restart" || strippedText.startsWith("/restart ") || strippedText === restartSuffixed || strippedText.startsWith(`${restartSuffixed} `);
|
|
48112
|
-
const isHelpCommand =
|
|
48128
|
+
const isHelpCommand = isSlackHelpCommand(rawText, helpSuffixed);
|
|
48113
48129
|
const isWatchDm = evt.channel?.startsWith("D") ?? false;
|
|
48114
48130
|
const isWatchCommand = !isBot && watchArgsFromText(strippedText, AGENT_CODE_NAME, { allowBare: isWatchDm }) !== null;
|
|
48115
48131
|
const command = isBot ? void 0 : isHelpCommand ? { command: "help", authorized: true } : isWatchCommand ? { command: "watch", authorized: isRestartSenderAllowed(getEffectiveAllowedUsers(), evt.user) } : isRestartCommand ? { command: "restart", authorized: isRestartSenderAllowed(getEffectiveAllowedUsers(), evt.user) } : void 0;
|
|
@@ -30740,6 +30740,12 @@ function decideInboundAccess(input) {
|
|
|
30740
30740
|
return { kind: "admit" };
|
|
30741
30741
|
}
|
|
30742
30742
|
|
|
30743
|
+
// src/help-command-syntax.ts
|
|
30744
|
+
var TELEGRAM_HELP_SYNTAX_RE = /^\/help(?:@([A-Za-z0-9_]{1,64}))?(?:\s|$)/;
|
|
30745
|
+
function isTelegramHelpSyntax(text) {
|
|
30746
|
+
return TELEGRAM_HELP_SYNTAX_RE.test(text);
|
|
30747
|
+
}
|
|
30748
|
+
|
|
30743
30749
|
// ../core/dist/channels/governance/telegram-chat-type.js
|
|
30744
30750
|
function isTelegramPrivateChat(chatType) {
|
|
30745
30751
|
return chatType === "private";
|
|
@@ -30823,7 +30829,7 @@ function resolveGhostReplyMode(opts) {
|
|
|
30823
30829
|
|
|
30824
30830
|
// src/maintenance-mode.ts
|
|
30825
30831
|
var FLAG_KEY = "platform-maintenance-mode";
|
|
30826
|
-
var MAINTENANCE_OFFLINE_MESSAGE = "The
|
|
30832
|
+
var MAINTENANCE_OFFLINE_MESSAGE = "The Ninjafy platform is offline for scheduled maintenance right now, so I can't pick this up \u2014 please try again shortly.";
|
|
30827
30833
|
function isMaintenanceModeActive(opts) {
|
|
30828
30834
|
return resolveHostBooleanFlag({
|
|
30829
30835
|
key: FLAG_KEY,
|
|
@@ -42717,7 +42723,7 @@ async function handleInvestigateCommand(opts) {
|
|
|
42717
42723
|
`denied reason=${verdict.reason} sender=${opts.senderId ? redactId(opts.senderId) : "unknown"}`
|
|
42718
42724
|
);
|
|
42719
42725
|
emitAudit("denied", verdict.reason);
|
|
42720
|
-
const denialText = verdict.reason === "not-dm" ? `\u26A0\uFE0F \`${investigateCmd}\` only works in a direct message with \`${AGENT_CODE_NAME}\` \u2014 it shows the agent's raw terminal, so it stays 1:1. Open a DM with the bot and run it there.` : verdict.reason === "allowlist-empty" ? `\u{1F6AB} \`${investigateCmd}\` is disabled for \`${AGENT_CODE_NAME}\` \u2014 no diagnostic allowlist reached this host. It is derived from team owners/admins and the agent's reports-to person; if that's you, link your Telegram in your
|
|
42726
|
+
const denialText = verdict.reason === "not-dm" ? `\u26A0\uFE0F \`${investigateCmd}\` only works in a direct message with \`${AGENT_CODE_NAME}\` \u2014 it shows the agent's raw terminal, so it stays 1:1. Open a DM with the bot and run it there.` : verdict.reason === "allowlist-empty" ? `\u{1F6AB} \`${investigateCmd}\` is disabled for \`${AGENT_CODE_NAME}\` \u2014 no diagnostic allowlist reached this host. It is derived from team owners/admins and the agent's reports-to person; if that's you, link your Telegram in your Ninjafy contact preferences and wait for the next refresh.` : `\u{1F6AB} \`${investigateCmd}\` denied \u2014 it's limited to team owners/admins and the person this agent reports to. If that's you, link your Telegram in your Ninjafy contact preferences and wait for the next refresh.`;
|
|
42721
42727
|
await sendInvestigateReply(opts.chatId, opts.messageId, denialText);
|
|
42722
42728
|
return;
|
|
42723
42729
|
}
|
|
@@ -42855,10 +42861,7 @@ async function resolveBotIdentity() {
|
|
|
42855
42861
|
return { bot_id: cachedBotId, bot_username: cachedBotUsername };
|
|
42856
42862
|
}
|
|
42857
42863
|
var RESTART_SYNTAX_RE = /^\/restart(?:@([A-Za-z0-9_]{1,64}))?(?:\s|$)/;
|
|
42858
|
-
var
|
|
42859
|
-
function isHelpSyntax(text) {
|
|
42860
|
-
return HELP_SYNTAX_RE.test(text);
|
|
42861
|
-
}
|
|
42864
|
+
var isHelpSyntax = isTelegramHelpSyntax;
|
|
42862
42865
|
var STATUS_SYNTAX_RE = /^\/status(?:@([A-Za-z0-9_]{1,64}))?(?:\s|$)/;
|
|
42863
42866
|
function isStatusSyntax(text) {
|
|
42864
42867
|
return STATUS_SYNTAX_RE.test(text);
|
|
@@ -45290,7 +45293,7 @@ async function pollLoop() {
|
|
|
45290
45293
|
"sendMessage",
|
|
45291
45294
|
{
|
|
45292
45295
|
chat_id: chatId,
|
|
45293
|
-
text: `\u{1F6AB} /ping is limited to ${AGENT_CODE_NAME}'s team and the person it reports to. If that's you, link your Telegram in your
|
|
45296
|
+
text: `\u{1F6AB} /ping is limited to ${AGENT_CODE_NAME}'s team and the person it reports to. If that's you, link your Telegram in your Ninjafy contact preferences and wait for the next refresh.`,
|
|
45294
45297
|
reply_to_message_id: Number(msg.message_id)
|
|
45295
45298
|
},
|
|
45296
45299
|
1e4
|
|
@@ -49,8 +49,8 @@ import {
|
|
|
49
49
|
writeDirectChatSessionState,
|
|
50
50
|
writeEgressAllowlist,
|
|
51
51
|
writePersistentClaudeWrapper
|
|
52
|
-
} from "./chunk-
|
|
53
|
-
import "./chunk-
|
|
52
|
+
} from "./chunk-Y33QUAGQ.js";
|
|
53
|
+
import "./chunk-IABI5AX5.js";
|
|
54
54
|
import "./chunk-XWVM4KPK.js";
|
|
55
55
|
export {
|
|
56
56
|
EGRESS_BASELINE_DOMAINS,
|
|
@@ -104,4 +104,4 @@ export {
|
|
|
104
104
|
writeEgressAllowlist,
|
|
105
105
|
writePersistentClaudeWrapper
|
|
106
106
|
};
|
|
107
|
-
//# sourceMappingURL=persistent-session-
|
|
107
|
+
//# sourceMappingURL=persistent-session-5XVEPXBT.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
paneLogPath
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-Y33QUAGQ.js";
|
|
4
|
+
import "./chunk-IABI5AX5.js";
|
|
5
5
|
import "./chunk-XWVM4KPK.js";
|
|
6
6
|
|
|
7
7
|
// src/lib/responsiveness-probe.ts
|
|
@@ -745,4 +745,4 @@ export {
|
|
|
745
745
|
readAndResetSlackReplyBindingClassifications,
|
|
746
746
|
readAndResetSlackReplyTargetClassifications
|
|
747
747
|
};
|
|
748
|
-
//# sourceMappingURL=responsiveness-probe-
|
|
748
|
+
//# sourceMappingURL=responsiveness-probe-7LZMXEWA.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
sessionTranscriptDir
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-IABI5AX5.js";
|
|
4
4
|
|
|
5
5
|
// src/lib/session-auth-dead.ts
|
|
6
6
|
import { closeSync, openSync, readSync, readdirSync, statSync } from "fs";
|
|
@@ -203,4 +203,4 @@ export {
|
|
|
203
203
|
decideSessionAuthState,
|
|
204
204
|
probeSessionAuth
|
|
205
205
|
};
|
|
206
|
-
//# sourceMappingURL=session-auth-dead-
|
|
206
|
+
//# sourceMappingURL=session-auth-dead-CDFUCZPH.js.map
|