@integrity-labs/agt-cli 0.28.678 → 0.28.680
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-3PCP5NT2.js → chunk-4JTDWOBW.js} +4 -4
- package/dist/{chunk-5DHJE2G7.js → chunk-OOFJUWMT.js} +77 -17
- package/dist/chunk-OOFJUWMT.js.map +1 -0
- package/dist/{chunk-LTOGVWUR.js → chunk-ZKNKHAHX.js} +2 -2
- package/dist/{claude-pair-runtime-X6CWJNW2.js → claude-pair-runtime-HPCXQDVY.js} +2 -2
- package/dist/lib/manager-worker.js +13 -13
- package/dist/mcp/direct-chat-channel.js +76 -16
- package/dist/mcp/index.js +160 -16
- package/dist/mcp/origami.js +76 -16
- package/dist/mcp/slack-channel.js +76 -16
- package/dist/mcp/telegram-channel.js +76 -16
- package/dist/{persistent-session-EZEYH3PM.js → persistent-session-OQ7MFVEH.js} +3 -3
- package/dist/{responsiveness-probe-VS6GODYP.js → responsiveness-probe-MDL53OT2.js} +3 -3
- package/dist/{session-auth-dead-7U24PZZS.js → session-auth-dead-4OJ2XLH4.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-5DHJE2G7.js.map +0 -1
- /package/dist/{chunk-3PCP5NT2.js.map → chunk-4JTDWOBW.js.map} +0 -0
- /package/dist/{chunk-LTOGVWUR.js.map → chunk-ZKNKHAHX.js.map} +0 -0
- /package/dist/{claude-pair-runtime-X6CWJNW2.js.map → claude-pair-runtime-HPCXQDVY.js.map} +0 -0
- /package/dist/{persistent-session-EZEYH3PM.js.map → persistent-session-OQ7MFVEH.js.map} +0 -0
- /package/dist/{responsiveness-probe-VS6GODYP.js.map → responsiveness-probe-MDL53OT2.js.map} +0 -0
- /package/dist/{session-auth-dead-7U24PZZS.js.map → session-auth-dead-4OJ2XLH4.js.map} +0 -0
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
rotateDailySession,
|
|
18
18
|
sessionFileExists,
|
|
19
19
|
todayLocalIso
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-OOFJUWMT.js";
|
|
21
21
|
import {
|
|
22
22
|
reapOrphanChannelMcps
|
|
23
23
|
} from "./chunk-XWVM4KPK.js";
|
|
@@ -4531,4 +4531,4 @@ export {
|
|
|
4531
4531
|
stopAllSessionsAndWait,
|
|
4532
4532
|
getProjectDir
|
|
4533
4533
|
};
|
|
4534
|
-
//# sourceMappingURL=chunk-
|
|
4534
|
+
//# sourceMappingURL=chunk-ZKNKHAHX.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-OQ7MFVEH.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-HPCXQDVY.js.map
|
|
@@ -55,7 +55,7 @@ import {
|
|
|
55
55
|
setConfigHash,
|
|
56
56
|
setSecretFileTmpfsBacking,
|
|
57
57
|
tripClass
|
|
58
|
-
} from "../chunk-
|
|
58
|
+
} from "../chunk-4JTDWOBW.js";
|
|
59
59
|
import {
|
|
60
60
|
getProjectDir as getProjectDir2,
|
|
61
61
|
getReadyTasks,
|
|
@@ -113,7 +113,7 @@ import {
|
|
|
113
113
|
takeZombieDetection,
|
|
114
114
|
toOpencodeModel,
|
|
115
115
|
writeEgressAllowlist
|
|
116
|
-
} from "../chunk-
|
|
116
|
+
} from "../chunk-ZKNKHAHX.js";
|
|
117
117
|
import {
|
|
118
118
|
ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
|
|
119
119
|
AnchorSessionClient,
|
|
@@ -194,7 +194,7 @@ import {
|
|
|
194
194
|
subagentActivityAgeSeconds,
|
|
195
195
|
sumTranscriptUsageInWindow,
|
|
196
196
|
transcriptActivityAgeSeconds
|
|
197
|
-
} from "../chunk-
|
|
197
|
+
} from "../chunk-OOFJUWMT.js";
|
|
198
198
|
import {
|
|
199
199
|
reapOrphanChannelMcps
|
|
200
200
|
} from "../chunk-XWVM4KPK.js";
|
|
@@ -11712,7 +11712,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
11712
11712
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
11713
11713
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
11714
11714
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
11715
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
11715
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-MDL53OT2.js");
|
|
11716
11716
|
const newest = newestPendingInboundActivityMtimeMs(dirname10(paneLogPath(codeName)));
|
|
11717
11717
|
if (newest === null) return null;
|
|
11718
11718
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
@@ -12360,7 +12360,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
12360
12360
|
var lastVersionCheckAt = 0;
|
|
12361
12361
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
12362
12362
|
var lastResponsivenessProbeAt = 0;
|
|
12363
|
-
var agtCliVersion = true ? "0.28.
|
|
12363
|
+
var agtCliVersion = true ? "0.28.680" : "dev";
|
|
12364
12364
|
function resolveBrewPath(execFileSync3) {
|
|
12365
12365
|
try {
|
|
12366
12366
|
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -13821,7 +13821,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
13821
13821
|
if (codeNames.length === 0) return;
|
|
13822
13822
|
void (async () => {
|
|
13823
13823
|
try {
|
|
13824
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
13824
|
+
const { collectDiagnostics } = await import("../persistent-session-OQ7MFVEH.js");
|
|
13825
13825
|
await api.post("/host/heartbeat", {
|
|
13826
13826
|
host_id: hostId,
|
|
13827
13827
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
|
|
@@ -13938,7 +13938,7 @@ async function pollCycleInner() {
|
|
|
13938
13938
|
}
|
|
13939
13939
|
try {
|
|
13940
13940
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
13941
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
13941
|
+
const { collectDiagnostics } = await import("../persistent-session-OQ7MFVEH.js");
|
|
13942
13942
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
13943
13943
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor) : void 0;
|
|
13944
13944
|
let tailscaleHostname;
|
|
@@ -14090,7 +14090,7 @@ async function pollCycleInner() {
|
|
|
14090
14090
|
collectPanelessActivityProbes,
|
|
14091
14091
|
getResponsivenessIntervalMs,
|
|
14092
14092
|
occupancyQualificationClassifications
|
|
14093
|
-
} = await import("../responsiveness-probe-
|
|
14093
|
+
} = await import("../responsiveness-probe-MDL53OT2.js");
|
|
14094
14094
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
14095
14095
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
14096
14096
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -14200,7 +14200,7 @@ async function pollCycleInner() {
|
|
|
14200
14200
|
collectResponsivenessProbes,
|
|
14201
14201
|
livePendingInboundOldestAgeSeconds,
|
|
14202
14202
|
parkPendingInbound
|
|
14203
|
-
} = await import("../responsiveness-probe-
|
|
14203
|
+
} = await import("../responsiveness-probe-MDL53OT2.js");
|
|
14204
14204
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
14205
14205
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
14206
14206
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -14356,7 +14356,7 @@ async function pollCycleInner() {
|
|
|
14356
14356
|
}
|
|
14357
14357
|
try {
|
|
14358
14358
|
const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-JA437JIB.js");
|
|
14359
|
-
const { probeSessionAuth } = await import("../session-auth-dead-
|
|
14359
|
+
const { probeSessionAuth } = await import("../session-auth-dead-4OJ2XLH4.js");
|
|
14360
14360
|
const observations = [];
|
|
14361
14361
|
const pendingCacheCommits = [];
|
|
14362
14362
|
const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
|
|
@@ -18117,7 +18117,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
18117
18117
|
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}`));
|
|
18118
18118
|
void (async () => {
|
|
18119
18119
|
try {
|
|
18120
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
18120
|
+
const { collectDiagnostics } = await import("../persistent-session-OQ7MFVEH.js");
|
|
18121
18121
|
await api.post("/host/heartbeat", {
|
|
18122
18122
|
host_id: hostId,
|
|
18123
18123
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
|
|
@@ -18168,7 +18168,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
18168
18168
|
}
|
|
18169
18169
|
try {
|
|
18170
18170
|
const hostId = await getHostId();
|
|
18171
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
18171
|
+
const { collectDiagnostics } = await import("../persistent-session-OQ7MFVEH.js");
|
|
18172
18172
|
await api.post("/host/heartbeat", {
|
|
18173
18173
|
host_id: hostId,
|
|
18174
18174
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
|
|
@@ -18800,7 +18800,7 @@ async function processClaudePairSessions(agents) {
|
|
|
18800
18800
|
killPairSession,
|
|
18801
18801
|
pairTmuxSession,
|
|
18802
18802
|
finalizeClaudePairOnboarding
|
|
18803
|
-
} = await import("../claude-pair-runtime-
|
|
18803
|
+
} = await import("../claude-pair-runtime-HPCXQDVY.js");
|
|
18804
18804
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
18805
18805
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
18806
18806
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -32291,6 +32291,15 @@ var MARKUP_BRIDGE_SCRIPT = `<script>(function(){
|
|
|
32291
32291
|
// long note on the window-capture click handler for why this is a mode and
|
|
32292
32292
|
// not just always-on.
|
|
32293
32293
|
var editMode = false;
|
|
32294
|
+
// ENG-9383: the ONE gate every edit-entry path asks. It exists because the
|
|
32295
|
+
// last time a path was added, the old ones did not come with it: ENG-8477
|
|
32296
|
+
// introduced editMode for the deep-probe handlers and left the ENG-6821
|
|
32297
|
+
// direct click/hover on an arming-only check, so text stayed editable with
|
|
32298
|
+
// the toggle off and the button gated one of two paths. A funnel is the fix
|
|
32299
|
+
// for that class of bug; adding the term twice is only the fix for this
|
|
32300
|
+
// instance of it. A fifth handler cannot forget the mode.
|
|
32301
|
+
function canEdit(){ return editEnabled && editMode && !editing; }
|
|
32302
|
+
var hoverCued = []; // ENG-9383: elements currently wearing the mouseover cue
|
|
32294
32303
|
|
|
32295
32304
|
// Element-child indices from <body> down to el. Counts ELEMENT children only
|
|
32296
32305
|
// (children, not childNodes), matching how the server walks source_html; our
|
|
@@ -32484,14 +32493,48 @@ var MARKUP_BRIDGE_SCRIPT = `<script>(function(){
|
|
|
32484
32493
|
// Hover affordance (only when armed and not mid-edit). Highlight leaves AND
|
|
32485
32494
|
// inline-only containers (their bare text is per-node editable, ENG-6856).
|
|
32486
32495
|
document.addEventListener('mouseover', function(e){
|
|
32487
|
-
if(!
|
|
32488
|
-
if(editable(el)||inlineOnlyEditable(el)){
|
|
32496
|
+
if(!canEdit()) return; var el=e.target;
|
|
32497
|
+
if(editable(el)||inlineOnlyEditable(el)){
|
|
32498
|
+
// ENG-9383: remember what the author's cursor was before we overwrite it.
|
|
32499
|
+
// Blanking it on the way out would delete an inline cursor the artefact
|
|
32500
|
+
// set itself; '' is a legitimate saved value meaning "there was none".
|
|
32501
|
+
if(el.__alCur===undefined) el.__alCur = el.style.cursor || '';
|
|
32502
|
+
el.style.cursor='text'; el.style.outline=el.style.outline||'1px dashed rgba(110,231,183,.6)'; el.__alHover=1; hoverCued.push(el);
|
|
32503
|
+
}
|
|
32489
32504
|
});
|
|
32490
32505
|
document.addEventListener('mouseout', function(e){
|
|
32491
|
-
var el=e.target; if(el&&el.__alHover&&el!==editing){ el.style.outline=''; el.__alHover=0; }
|
|
32506
|
+
var el=e.target; if(el&&el.__alHover&&el!==editing){ el.style.outline=''; restoreCursor(el); el.__alHover=0; dropHoverCue(el); }
|
|
32492
32507
|
});
|
|
32508
|
+
// ENG-9383 (CodeRabbit on #4956): the cue is an outline AND an I-beam cursor.
|
|
32509
|
+
// Clearing only the outline leaves the text still saying "you can type here"
|
|
32510
|
+
// on a page that will now refuse the click - the same misdirection this ticket
|
|
32511
|
+
// is about, one property over.
|
|
32512
|
+
function restoreCursor(el){
|
|
32513
|
+
if(el.__alCur!==undefined){ try{ el.style.cursor=el.__alCur; }catch(e){} el.__alCur=undefined; }
|
|
32514
|
+
}
|
|
32515
|
+
// Keep hoverCued bounded. Without this it grows once per hovered element for
|
|
32516
|
+
// the life of the page and pins every one of them against GC - a list that
|
|
32517
|
+
// only ever empties when the viewer toggles the mode off is a leak on any page
|
|
32518
|
+
// nobody toggles.
|
|
32519
|
+
function dropHoverCue(el){
|
|
32520
|
+
var i=hoverCued.indexOf(el); if(i!==-1) hoverCued.splice(i,1);
|
|
32521
|
+
}
|
|
32522
|
+
// ENG-9383: drop every outline the mouseover cue left behind, without waiting
|
|
32523
|
+
// for a mouseout that may never come - the mode can go off while the pointer is
|
|
32524
|
+
// parked on the text, and then the artefact wears a dashed "editable" outline
|
|
32525
|
+
// on a page where you no longer can. Tracked in a list rather than queried back
|
|
32526
|
+
// out of the DOM: more than one element can carry the cue if the pointer moved
|
|
32527
|
+
// between mouseover and mouseout, and the bridge should not depend on a
|
|
32528
|
+
// selector matching an inline style it wrote.
|
|
32529
|
+
function clearHoverCues(){
|
|
32530
|
+
for(var i=0;i<hoverCued.length;i++){
|
|
32531
|
+
var el=hoverCued[i];
|
|
32532
|
+
if(el && el.__alHover && el!==editing){ try{ el.style.outline=''; }catch(e){} restoreCursor(el); el.__alHover=0; }
|
|
32533
|
+
}
|
|
32534
|
+
hoverCued.length=0;
|
|
32535
|
+
}
|
|
32493
32536
|
document.addEventListener('click', function(e){
|
|
32494
|
-
if(!
|
|
32537
|
+
if(!canEdit()) return;
|
|
32495
32538
|
var sel=document.getSelection(); if(sel && String(sel).trim()) return; // a selection => comment flow
|
|
32496
32539
|
var el=e.target;
|
|
32497
32540
|
if(editable(el)){ e.preventDefault(); e.stopPropagation(); startEdit(el); return; }
|
|
@@ -32535,7 +32578,7 @@ var MARKUP_BRIDGE_SCRIPT = `<script>(function(){
|
|
|
32535
32578
|
// Deliberately general: nothing here knows about .clickzone or any class name.
|
|
32536
32579
|
// It fixes any artefact that covers its own content.
|
|
32537
32580
|
window.addEventListener('click', function(e){
|
|
32538
|
-
if(!
|
|
32581
|
+
if(!canEdit()) return;
|
|
32539
32582
|
var sel=document.getSelection(); if(sel && String(sel).trim()) return; // selection => comment flow
|
|
32540
32583
|
var t=e.target;
|
|
32541
32584
|
// Our own toolbar (Save/Cancel) must keep its clicks.
|
|
@@ -32593,7 +32636,7 @@ var MARKUP_BRIDGE_SCRIPT = `<script>(function(){
|
|
|
32593
32636
|
hoverEl=null;
|
|
32594
32637
|
}
|
|
32595
32638
|
document.addEventListener('mousemove', function(e){
|
|
32596
|
-
if(!
|
|
32639
|
+
if(!canEdit()){ clearDeepHover(); return; }
|
|
32597
32640
|
var t=e.target;
|
|
32598
32641
|
if(editable(t)||inlineOnlyEditable(t)){ clearDeepHover(); return; }
|
|
32599
32642
|
var now=Date.now(); if(now-hoverProbeAt<80) return; hoverProbeAt=now;
|
|
@@ -32693,12 +32736,17 @@ var MARKUP_BRIDGE_SCRIPT = `<script>(function(){
|
|
|
32693
32736
|
var d=e.data; if(!d || d['${MARKUP_CONTROL_MARKER}']!==true) return;
|
|
32694
32737
|
if(d.type==='enable-edit'){ editEnabled=true; }
|
|
32695
32738
|
else if(d.type==='enable-comment'){ commentEnabled=true; }
|
|
32696
|
-
// ENG-8477: the viewer toggled Edit
|
|
32739
|
+
// ENG-8477: the viewer toggled Edit mode in the shell. Turning it OFF must
|
|
32697
32740
|
// also close anything open and drop the hover cue, or the artefact is left
|
|
32698
32741
|
// wearing our outlines with no way to clear them.
|
|
32742
|
+
// ENG-9383: clearDeepHover() only knows the deep-probe path's outline. The
|
|
32743
|
+
// ENG-6821 mouseover path marks its own element with __alHover and relies on
|
|
32744
|
+
// mouseout to undo it - which never fires if the pointer is still sitting on
|
|
32745
|
+
// the text when the mode goes off, leaving a dashed "you can edit this"
|
|
32746
|
+
// outline on a page where you now cannot. Clear both.
|
|
32699
32747
|
else if(d.type==='set-edit-mode'){
|
|
32700
32748
|
editMode = !!d.on;
|
|
32701
|
-
if(!editMode){ if(editing) endEdit(false); clearDeepHover(); }
|
|
32749
|
+
if(!editMode){ if(editing) endEdit(false); clearDeepHover(); clearHoverCues(); }
|
|
32702
32750
|
}
|
|
32703
32751
|
else if(d.type==='edit-result'){
|
|
32704
32752
|
if(d.ok){ /* republish hot-swaps the iframe; nothing to do */ }
|
|
@@ -35909,14 +35957,15 @@ var FLAG_REGISTRY = [
|
|
|
35909
35957
|
// hand-written process.env gate) — same posture as memory-extraction /
|
|
35910
35958
|
// tool-call-audit above. Gives a per-host canary before the DB flag exists.
|
|
35911
35959
|
envVar: "AGT_SECRET_FILES_TMPFS_ENABLED",
|
|
35912
|
-
//
|
|
35913
|
-
//
|
|
35914
|
-
//
|
|
35915
|
-
//
|
|
35916
|
-
//
|
|
35917
|
-
//
|
|
35918
|
-
//
|
|
35919
|
-
|
|
35960
|
+
// The real published build that carries the manager reader + core writer,
|
|
35961
|
+
// replacing the deliberately-unreachable `99.0.0` this flag shipped with.
|
|
35962
|
+
// Verified against the tarball (`npm pack @integrity-labs/agt-cli@0.28.678`):
|
|
35963
|
+
// `setSecretFileTmpfsBacking` is present in package/dist/lib/manager-worker.js
|
|
35964
|
+
// and the `secret-files-tmpfs` key ships in the bundle. Auto-publish patch-
|
|
35965
|
+
// bumps from main, so if a CLI-touching PR landed between the ENG-9348 merge
|
|
35966
|
+
// and this one the real cut is higher than 0.28.678 and reach under-reports;
|
|
35967
|
+
// re-verify before flipping the flag on for a canary (ENG-8575/ENG-9350).
|
|
35968
|
+
since: "0.28.678"
|
|
35920
35969
|
},
|
|
35921
35970
|
{
|
|
35922
35971
|
key: "memory-file-tombstones",
|
|
@@ -36700,6 +36749,17 @@ var FLAG_REGISTRY = [
|
|
|
36700
36749
|
// control that does nothing, which is the ENG-8303 class exactly.
|
|
36701
36750
|
// enforce arms automated downtime on a customer's production host.
|
|
36702
36751
|
sensitive: true
|
|
36752
|
+
},
|
|
36753
|
+
{
|
|
36754
|
+
key: "live-meeting-advisor",
|
|
36755
|
+
description: "Live meeting advising in Ninja Notes (ENG-9381). When ON for an org, a person recording a meeting on the Mac may arm an agent to watch it in flight: audio chunks stream to POST /notes/live/:id/chunks, a server-side Haiku vet decides moment by moment whether to escalate, and escalations reach the agent in a server-minted chat thread. Gates the CAPABILITY, not a surface: the refusal is in startLiveAdvisorSession, so a client that ignores the flag still cannot open a session, and GET /notes/destinations reports the same answer as advisor_enabled so the app can skip the arming modal entirely. Boolean gate; ships dark. OFF NEVER COSTS THE RECORDING. An unentitled org \u2014 or a flag read that fails \u2014 costs the advisor only; the microphone still starts and the note is still transcribed and delivered. That direction is deliberate: the user pressed Record and a recording is what they are owed, while arming on a failed read would spend money per minute on a session nobody confirmed. Deliberately NO envVar. This is an org-scoped gate, and an envVar is highest-precedence per ADR-0022 \u2014 a literal in sst.config.ts would pin every stage and make the admin control do nothing, the ENG-8303 class exactly.",
|
|
36756
|
+
flagType: "boolean",
|
|
36757
|
+
defaultValue: false,
|
|
36758
|
+
// Turning it ON arms a per-minute-metered capability AND starts streaming
|
|
36759
|
+
// meeting content to a server-side vet. Both halves are the deliberate,
|
|
36760
|
+
// audited decision ADR-0022 §4 reserves confirmation for — same treatment as
|
|
36761
|
+
// agent-hours-billing-enabled.
|
|
36762
|
+
sensitive: true
|
|
36703
36763
|
}
|
|
36704
36764
|
];
|
|
36705
36765
|
var REGISTRY_BY_KEY = new Map(FLAG_REGISTRY.map((definition) => [definition.key, definition]));
|
package/dist/mcp/index.js
CHANGED
|
@@ -37038,6 +37038,30 @@ var BLOCKED_ON_ME_SECTION_NOTE = "_Another agent has PARKED its own work until y
|
|
|
37038
37038
|
var HUMAN_ASSIGNED_SECTION_HEADING = "Assigned to a person (not yours to action)";
|
|
37039
37039
|
var HUMAN_ASSIGNED_SECTION_NOTE = "_These belong to a person, not to you. You cannot move, note or complete them \u2014 every kanban write is refused. If the work is finished (or was never really theirs), use `kanban_recall` to pull the card back onto your board, then close it as normal._";
|
|
37040
37040
|
|
|
37041
|
+
// src/kanban-peek-render.ts
|
|
37042
|
+
var PEEK_RENDER_COLUMNS = [
|
|
37043
|
+
["in_progress", "in progress"],
|
|
37044
|
+
["todo", "todo"],
|
|
37045
|
+
["backlog", "backlog"],
|
|
37046
|
+
["waiting", "waiting"],
|
|
37047
|
+
["needs_attention", "needs attention"]
|
|
37048
|
+
];
|
|
37049
|
+
function formatPeekAge(ageHours) {
|
|
37050
|
+
if (!Number.isFinite(ageHours) || ageHours <= 0) return "<1h";
|
|
37051
|
+
if (ageHours < 48) return `${Math.floor(ageHours)}h`;
|
|
37052
|
+
return `${Math.floor(ageHours / 24)}d`;
|
|
37053
|
+
}
|
|
37054
|
+
function renderKanbanPeek(data, fallbackTeam) {
|
|
37055
|
+
const parts = PEEK_RENDER_COLUMNS.map(([key, label]) => {
|
|
37056
|
+
const count = data[key];
|
|
37057
|
+
const oldest = data.oldest?.[key];
|
|
37058
|
+
const age = oldest === void 0 ? "" : ` (oldest ${formatPeekAge(oldest.age_hours)}, id ${oldest.card_id})`;
|
|
37059
|
+
return `${label}: ${count}${age}`;
|
|
37060
|
+
});
|
|
37061
|
+
const where = data.cross_team ? ` on team ${data.target_team ?? fallbackTeam ?? "?"}` : "";
|
|
37062
|
+
return `${data.target_agent}${where} \u2014 ${parts.join(" \xB7 ")}`;
|
|
37063
|
+
}
|
|
37064
|
+
|
|
37041
37065
|
// src/kanban-person-waiting-kind.ts
|
|
37042
37066
|
function isPersonWaitingKindMcp(kind) {
|
|
37043
37067
|
if (kind === void 0 || kind === null || kind === "") return true;
|
|
@@ -39667,6 +39691,15 @@ var MARKUP_BRIDGE_SCRIPT = `<script>(function(){
|
|
|
39667
39691
|
// long note on the window-capture click handler for why this is a mode and
|
|
39668
39692
|
// not just always-on.
|
|
39669
39693
|
var editMode = false;
|
|
39694
|
+
// ENG-9383: the ONE gate every edit-entry path asks. It exists because the
|
|
39695
|
+
// last time a path was added, the old ones did not come with it: ENG-8477
|
|
39696
|
+
// introduced editMode for the deep-probe handlers and left the ENG-6821
|
|
39697
|
+
// direct click/hover on an arming-only check, so text stayed editable with
|
|
39698
|
+
// the toggle off and the button gated one of two paths. A funnel is the fix
|
|
39699
|
+
// for that class of bug; adding the term twice is only the fix for this
|
|
39700
|
+
// instance of it. A fifth handler cannot forget the mode.
|
|
39701
|
+
function canEdit(){ return editEnabled && editMode && !editing; }
|
|
39702
|
+
var hoverCued = []; // ENG-9383: elements currently wearing the mouseover cue
|
|
39670
39703
|
|
|
39671
39704
|
// Element-child indices from <body> down to el. Counts ELEMENT children only
|
|
39672
39705
|
// (children, not childNodes), matching how the server walks source_html; our
|
|
@@ -39860,14 +39893,48 @@ var MARKUP_BRIDGE_SCRIPT = `<script>(function(){
|
|
|
39860
39893
|
// Hover affordance (only when armed and not mid-edit). Highlight leaves AND
|
|
39861
39894
|
// inline-only containers (their bare text is per-node editable, ENG-6856).
|
|
39862
39895
|
document.addEventListener('mouseover', function(e){
|
|
39863
|
-
if(!
|
|
39864
|
-
if(editable(el)||inlineOnlyEditable(el)){
|
|
39896
|
+
if(!canEdit()) return; var el=e.target;
|
|
39897
|
+
if(editable(el)||inlineOnlyEditable(el)){
|
|
39898
|
+
// ENG-9383: remember what the author's cursor was before we overwrite it.
|
|
39899
|
+
// Blanking it on the way out would delete an inline cursor the artefact
|
|
39900
|
+
// set itself; '' is a legitimate saved value meaning "there was none".
|
|
39901
|
+
if(el.__alCur===undefined) el.__alCur = el.style.cursor || '';
|
|
39902
|
+
el.style.cursor='text'; el.style.outline=el.style.outline||'1px dashed rgba(110,231,183,.6)'; el.__alHover=1; hoverCued.push(el);
|
|
39903
|
+
}
|
|
39865
39904
|
});
|
|
39866
39905
|
document.addEventListener('mouseout', function(e){
|
|
39867
|
-
var el=e.target; if(el&&el.__alHover&&el!==editing){ el.style.outline=''; el.__alHover=0; }
|
|
39906
|
+
var el=e.target; if(el&&el.__alHover&&el!==editing){ el.style.outline=''; restoreCursor(el); el.__alHover=0; dropHoverCue(el); }
|
|
39868
39907
|
});
|
|
39908
|
+
// ENG-9383 (CodeRabbit on #4956): the cue is an outline AND an I-beam cursor.
|
|
39909
|
+
// Clearing only the outline leaves the text still saying "you can type here"
|
|
39910
|
+
// on a page that will now refuse the click - the same misdirection this ticket
|
|
39911
|
+
// is about, one property over.
|
|
39912
|
+
function restoreCursor(el){
|
|
39913
|
+
if(el.__alCur!==undefined){ try{ el.style.cursor=el.__alCur; }catch(e){} el.__alCur=undefined; }
|
|
39914
|
+
}
|
|
39915
|
+
// Keep hoverCued bounded. Without this it grows once per hovered element for
|
|
39916
|
+
// the life of the page and pins every one of them against GC - a list that
|
|
39917
|
+
// only ever empties when the viewer toggles the mode off is a leak on any page
|
|
39918
|
+
// nobody toggles.
|
|
39919
|
+
function dropHoverCue(el){
|
|
39920
|
+
var i=hoverCued.indexOf(el); if(i!==-1) hoverCued.splice(i,1);
|
|
39921
|
+
}
|
|
39922
|
+
// ENG-9383: drop every outline the mouseover cue left behind, without waiting
|
|
39923
|
+
// for a mouseout that may never come - the mode can go off while the pointer is
|
|
39924
|
+
// parked on the text, and then the artefact wears a dashed "editable" outline
|
|
39925
|
+
// on a page where you no longer can. Tracked in a list rather than queried back
|
|
39926
|
+
// out of the DOM: more than one element can carry the cue if the pointer moved
|
|
39927
|
+
// between mouseover and mouseout, and the bridge should not depend on a
|
|
39928
|
+
// selector matching an inline style it wrote.
|
|
39929
|
+
function clearHoverCues(){
|
|
39930
|
+
for(var i=0;i<hoverCued.length;i++){
|
|
39931
|
+
var el=hoverCued[i];
|
|
39932
|
+
if(el && el.__alHover && el!==editing){ try{ el.style.outline=''; }catch(e){} restoreCursor(el); el.__alHover=0; }
|
|
39933
|
+
}
|
|
39934
|
+
hoverCued.length=0;
|
|
39935
|
+
}
|
|
39869
39936
|
document.addEventListener('click', function(e){
|
|
39870
|
-
if(!
|
|
39937
|
+
if(!canEdit()) return;
|
|
39871
39938
|
var sel=document.getSelection(); if(sel && String(sel).trim()) return; // a selection => comment flow
|
|
39872
39939
|
var el=e.target;
|
|
39873
39940
|
if(editable(el)){ e.preventDefault(); e.stopPropagation(); startEdit(el); return; }
|
|
@@ -39911,7 +39978,7 @@ var MARKUP_BRIDGE_SCRIPT = `<script>(function(){
|
|
|
39911
39978
|
// Deliberately general: nothing here knows about .clickzone or any class name.
|
|
39912
39979
|
// It fixes any artefact that covers its own content.
|
|
39913
39980
|
window.addEventListener('click', function(e){
|
|
39914
|
-
if(!
|
|
39981
|
+
if(!canEdit()) return;
|
|
39915
39982
|
var sel=document.getSelection(); if(sel && String(sel).trim()) return; // selection => comment flow
|
|
39916
39983
|
var t=e.target;
|
|
39917
39984
|
// Our own toolbar (Save/Cancel) must keep its clicks.
|
|
@@ -39969,7 +40036,7 @@ var MARKUP_BRIDGE_SCRIPT = `<script>(function(){
|
|
|
39969
40036
|
hoverEl=null;
|
|
39970
40037
|
}
|
|
39971
40038
|
document.addEventListener('mousemove', function(e){
|
|
39972
|
-
if(!
|
|
40039
|
+
if(!canEdit()){ clearDeepHover(); return; }
|
|
39973
40040
|
var t=e.target;
|
|
39974
40041
|
if(editable(t)||inlineOnlyEditable(t)){ clearDeepHover(); return; }
|
|
39975
40042
|
var now=Date.now(); if(now-hoverProbeAt<80) return; hoverProbeAt=now;
|
|
@@ -40069,12 +40136,17 @@ var MARKUP_BRIDGE_SCRIPT = `<script>(function(){
|
|
|
40069
40136
|
var d=e.data; if(!d || d['${MARKUP_CONTROL_MARKER}']!==true) return;
|
|
40070
40137
|
if(d.type==='enable-edit'){ editEnabled=true; }
|
|
40071
40138
|
else if(d.type==='enable-comment'){ commentEnabled=true; }
|
|
40072
|
-
// ENG-8477: the viewer toggled Edit
|
|
40139
|
+
// ENG-8477: the viewer toggled Edit mode in the shell. Turning it OFF must
|
|
40073
40140
|
// also close anything open and drop the hover cue, or the artefact is left
|
|
40074
40141
|
// wearing our outlines with no way to clear them.
|
|
40142
|
+
// ENG-9383: clearDeepHover() only knows the deep-probe path's outline. The
|
|
40143
|
+
// ENG-6821 mouseover path marks its own element with __alHover and relies on
|
|
40144
|
+
// mouseout to undo it - which never fires if the pointer is still sitting on
|
|
40145
|
+
// the text when the mode goes off, leaving a dashed "you can edit this"
|
|
40146
|
+
// outline on a page where you now cannot. Clear both.
|
|
40075
40147
|
else if(d.type==='set-edit-mode'){
|
|
40076
40148
|
editMode = !!d.on;
|
|
40077
|
-
if(!editMode){ if(editing) endEdit(false); clearDeepHover(); }
|
|
40149
|
+
if(!editMode){ if(editing) endEdit(false); clearDeepHover(); clearHoverCues(); }
|
|
40078
40150
|
}
|
|
40079
40151
|
else if(d.type==='edit-result'){
|
|
40080
40152
|
if(d.ok){ /* republish hot-swaps the iframe; nothing to do */ }
|
|
@@ -42836,14 +42908,15 @@ var FLAG_REGISTRY = [
|
|
|
42836
42908
|
// hand-written process.env gate) — same posture as memory-extraction /
|
|
42837
42909
|
// tool-call-audit above. Gives a per-host canary before the DB flag exists.
|
|
42838
42910
|
envVar: "AGT_SECRET_FILES_TMPFS_ENABLED",
|
|
42839
|
-
//
|
|
42840
|
-
//
|
|
42841
|
-
//
|
|
42842
|
-
//
|
|
42843
|
-
//
|
|
42844
|
-
//
|
|
42845
|
-
//
|
|
42846
|
-
|
|
42911
|
+
// The real published build that carries the manager reader + core writer,
|
|
42912
|
+
// replacing the deliberately-unreachable `99.0.0` this flag shipped with.
|
|
42913
|
+
// Verified against the tarball (`npm pack @integrity-labs/agt-cli@0.28.678`):
|
|
42914
|
+
// `setSecretFileTmpfsBacking` is present in package/dist/lib/manager-worker.js
|
|
42915
|
+
// and the `secret-files-tmpfs` key ships in the bundle. Auto-publish patch-
|
|
42916
|
+
// bumps from main, so if a CLI-touching PR landed between the ENG-9348 merge
|
|
42917
|
+
// and this one the real cut is higher than 0.28.678 and reach under-reports;
|
|
42918
|
+
// re-verify before flipping the flag on for a canary (ENG-8575/ENG-9350).
|
|
42919
|
+
since: "0.28.678"
|
|
42847
42920
|
},
|
|
42848
42921
|
{
|
|
42849
42922
|
key: "memory-file-tombstones",
|
|
@@ -43627,6 +43700,17 @@ var FLAG_REGISTRY = [
|
|
|
43627
43700
|
// control that does nothing, which is the ENG-8303 class exactly.
|
|
43628
43701
|
// enforce arms automated downtime on a customer's production host.
|
|
43629
43702
|
sensitive: true
|
|
43703
|
+
},
|
|
43704
|
+
{
|
|
43705
|
+
key: "live-meeting-advisor",
|
|
43706
|
+
description: "Live meeting advising in Ninja Notes (ENG-9381). When ON for an org, a person recording a meeting on the Mac may arm an agent to watch it in flight: audio chunks stream to POST /notes/live/:id/chunks, a server-side Haiku vet decides moment by moment whether to escalate, and escalations reach the agent in a server-minted chat thread. Gates the CAPABILITY, not a surface: the refusal is in startLiveAdvisorSession, so a client that ignores the flag still cannot open a session, and GET /notes/destinations reports the same answer as advisor_enabled so the app can skip the arming modal entirely. Boolean gate; ships dark. OFF NEVER COSTS THE RECORDING. An unentitled org \u2014 or a flag read that fails \u2014 costs the advisor only; the microphone still starts and the note is still transcribed and delivered. That direction is deliberate: the user pressed Record and a recording is what they are owed, while arming on a failed read would spend money per minute on a session nobody confirmed. Deliberately NO envVar. This is an org-scoped gate, and an envVar is highest-precedence per ADR-0022 \u2014 a literal in sst.config.ts would pin every stage and make the admin control do nothing, the ENG-8303 class exactly.",
|
|
43707
|
+
flagType: "boolean",
|
|
43708
|
+
defaultValue: false,
|
|
43709
|
+
// Turning it ON arms a per-minute-metered capability AND starts streaming
|
|
43710
|
+
// meeting content to a server-side vet. Both halves are the deliberate,
|
|
43711
|
+
// audited decision ADR-0022 §4 reserves confirmation for — same treatment as
|
|
43712
|
+
// agent-hours-billing-enabled.
|
|
43713
|
+
sensitive: true
|
|
43630
43714
|
}
|
|
43631
43715
|
];
|
|
43632
43716
|
var REGISTRY_BY_KEY = new Map(FLAG_REGISTRY.map((definition) => [definition.key, definition]));
|
|
@@ -44570,6 +44654,64 @@ server.tool(
|
|
|
44570
44654
|
}
|
|
44571
44655
|
}
|
|
44572
44656
|
);
|
|
44657
|
+
server.tool(
|
|
44658
|
+
"kanban_peek",
|
|
44659
|
+
"Look at ANOTHER agent's board WITHOUT seeing what is on it: how many cards sit in each column, and how long the oldest card in each column has been sitting there. Use it before routing work with kanban_assign, to tell an agent that is genuinely free from one that is buried, and to spot a board where something has been rotting for days. You get NUMBERS ONLY \u2014 no titles, descriptions, results or notes ever cross between agents, so this tells you the SHAPE of their queue, never its content. A deep board is not automatically a problem and an empty one is not automatically fine: the age of the oldest card is usually the more useful of the two. By default the target must be an agent on your OWN team; pass `target_team` to peek across teams in your organization, which works only where your org has enabled cross-team assignment and a peer grant links the teams \u2014 otherwise it reads as not-found, exactly like kanban_assign. Don't know the agent's code_name? Call directory_lookup first.",
|
|
44660
|
+
{
|
|
44661
|
+
target_agent: external_exports.string().describe(
|
|
44662
|
+
"The agent whose board you want to size up: their agent code_name (kebab-case) or agent UUID. On your own team unless target_team is also set."
|
|
44663
|
+
),
|
|
44664
|
+
target_team: external_exports.string().trim().min(1).optional().describe(
|
|
44665
|
+
"Optional: the slug (or UUID) of ANOTHER team in your organization, to peek across teams. Omit for a teammate on your own team. Requires the org to have cross-team assignment enabled and a peer grant; otherwise the target reads as not-found."
|
|
44666
|
+
)
|
|
44667
|
+
},
|
|
44668
|
+
async (params) => {
|
|
44669
|
+
try {
|
|
44670
|
+
const data = await apiPost(
|
|
44671
|
+
"/host/kanban/peek",
|
|
44672
|
+
{
|
|
44673
|
+
agent_id: AGT_AGENT_ID,
|
|
44674
|
+
target_agent: params.target_agent,
|
|
44675
|
+
// Only sent when peeking across teams — the route branches on its
|
|
44676
|
+
// presence, so omit it for the same-team path (identical contract to
|
|
44677
|
+
// kanban_assign). The schema rejects empty strings, so a present value
|
|
44678
|
+
// is always meaningful; check presence, not truthiness.
|
|
44679
|
+
...params.target_team !== void 0 ? { target_team: params.target_team } : {}
|
|
44680
|
+
},
|
|
44681
|
+
false,
|
|
44682
|
+
15e3,
|
|
44683
|
+
"kanban_peek",
|
|
44684
|
+
// Genuinely read-only: a timeout or transport error here can never have
|
|
44685
|
+
// committed anything, and saying so keeps the retry decision obvious.
|
|
44686
|
+
true
|
|
44687
|
+
);
|
|
44688
|
+
return {
|
|
44689
|
+
content: [
|
|
44690
|
+
{
|
|
44691
|
+
type: "text",
|
|
44692
|
+
// Rendering lives in a sibling module so it is reachable by a test —
|
|
44693
|
+
// importing this file boots the stdio server, so anything inline
|
|
44694
|
+
// here is checked exactly once, on the day it is written.
|
|
44695
|
+
text: renderKanbanPeek(data, params.target_team)
|
|
44696
|
+
}
|
|
44697
|
+
]
|
|
44698
|
+
};
|
|
44699
|
+
} catch (err) {
|
|
44700
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
44701
|
+
const notFound = /returned 404/.test(msg);
|
|
44702
|
+
const notFoundText = params.target_team ? `Could not peek: no agent "${params.target_agent}" reachable on team "${params.target_team}". Check the team slug and agent code_name, and note cross-team access only works when your org has enabled it and a peer grant links the teams.` : `Could not peek: no agent "${params.target_agent}" found on your team. Check the code_name and make sure they're a teammate on the same team.`;
|
|
44703
|
+
return {
|
|
44704
|
+
content: [
|
|
44705
|
+
{
|
|
44706
|
+
type: "text",
|
|
44707
|
+
text: notFound ? notFoundText : `Could not peek at ${params.target_agent}: ${msg}`
|
|
44708
|
+
}
|
|
44709
|
+
],
|
|
44710
|
+
isError: true
|
|
44711
|
+
};
|
|
44712
|
+
}
|
|
44713
|
+
}
|
|
44714
|
+
);
|
|
44573
44715
|
server.tool(
|
|
44574
44716
|
"kanban_reassign",
|
|
44575
44717
|
"Move an EXISTING kanban card to ANOTHER agent\u2019s board, preserving its id, history, comments, priority and status. Use this to re-home a task you already have (e.g. you picked up a card but it\u2019s really another specialist\u2019s job) - it removes the card from the current board and places the same card on the target agent\u2019s board. This is different from kanban_assign, which CREATES a new card. The card must currently live on your team. To move across teams in your organization, also pass `target_team` (same cross-team rules as kanban_assign). Don\u2019t know the agent code_name or team slug? Call directory_lookup first.",
|
|
@@ -46357,6 +46499,8 @@ var LOCAL_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
46357
46499
|
"kanban_recall",
|
|
46358
46500
|
// ENG-9050: the return path for delegated work.
|
|
46359
46501
|
"kanban_reopen",
|
|
46502
|
+
// ENG-9375: the READ path over a teammate's board (counts only).
|
|
46503
|
+
"kanban_peek",
|
|
46360
46504
|
// ENG-6953: agent + people directory lookup (always registered locally).
|
|
46361
46505
|
"directory_lookup",
|
|
46362
46506
|
"status_standup",
|