@integrity-labs/agt-cli 0.28.1088 → 0.28.1089

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/mcp/index.js CHANGED
@@ -18867,7 +18867,7 @@ var require_filters = __commonJS({
18867
18867
  return r.copySafeness(str, res);
18868
18868
  }
18869
18869
  _exports.indent = indent;
18870
- function join7(arr, del, attr) {
18870
+ function join10(arr, del, attr) {
18871
18871
  del = del || "";
18872
18872
  if (attr) {
18873
18873
  arr = lib.map(arr, function(v) {
@@ -18876,7 +18876,7 @@ var require_filters = __commonJS({
18876
18876
  }
18877
18877
  return arr.join(del);
18878
18878
  }
18879
- _exports.join = join7;
18879
+ _exports.join = join10;
18880
18880
  function last(arr) {
18881
18881
  return arr[arr.length - 1];
18882
18882
  }
@@ -20042,9 +20042,9 @@ var require_handler = __commonJS({
20042
20042
  if (this.fsw.closed) {
20043
20043
  return;
20044
20044
  }
20045
- const dirname3 = sysPath.dirname(file);
20045
+ const dirname5 = sysPath.dirname(file);
20046
20046
  const basename2 = sysPath.basename(file);
20047
- const parent = this.fsw._getWatchedDir(dirname3);
20047
+ const parent = this.fsw._getWatchedDir(dirname5);
20048
20048
  let prevStats = stats;
20049
20049
  if (parent.has(basename2))
20050
20050
  return;
@@ -20071,7 +20071,7 @@ var require_handler = __commonJS({
20071
20071
  prevStats = newStats2;
20072
20072
  }
20073
20073
  } catch (error2) {
20074
- this.fsw._remove(dirname3, basename2);
20074
+ this.fsw._remove(dirname5, basename2);
20075
20075
  }
20076
20076
  } else if (parent.has(basename2)) {
20077
20077
  const at = newStats.atimeMs;
@@ -35540,8 +35540,8 @@ function renderKnowledgeBody(content) {
35540
35540
  }
35541
35541
 
35542
35542
  // src/index.ts
35543
- import { homedir as homedir3 } from "os";
35544
- import { basename, isAbsolute as isAbsolute2, join as join6, resolve as pathResolve, sep as sep2 } from "path";
35543
+ import { homedir as homedir4 } from "os";
35544
+ import { basename, isAbsolute as isAbsolute2, join as join9, resolve as pathResolve, sep as sep2 } from "path";
35545
35545
 
35546
35546
  // src/host-file-path.ts
35547
35547
  var SKILL_BODY_PATH_MAX_BYTES = 512 * 1024;
@@ -35779,6 +35779,133 @@ async function makeArtefactWorkDir(prefix, env2) {
35779
35779
  return mkdtemp(join2(scratch, prefix));
35780
35780
  }
35781
35781
 
35782
+ // src/turn-context.ts
35783
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync3 } from "fs";
35784
+ import { homedir } from "os";
35785
+ import { dirname as dirname3, join as join5 } from "path";
35786
+
35787
+ // src/turn-initiator-marker.ts
35788
+ import { writeFileSync, readFileSync, mkdirSync, renameSync } from "fs";
35789
+ import { dirname as dirname2, join as join3 } from "path";
35790
+ var TURN_INITIATOR_MAX_AGE_MS = 5 * 60 * 1e3;
35791
+ var TURN_INITIATOR_LEDGER_FILENAME = ".turn-initiator-ledger.json";
35792
+
35793
+ // src/scheduled-turn-marker.ts
35794
+ import { readFileSync as readFileSync2, unlinkSync } from "fs";
35795
+ import { join as join4 } from "path";
35796
+ var SCHEDULED_TURN_MARKER_FILENAME2 = ".current-scheduled-turn.json";
35797
+ var SCHEDULED_TURN_MAX_AGE_MS = 15 * 60 * 1e3;
35798
+ function validateScheduledTurnMarker(raw, now, maxAgeMs = SCHEDULED_TURN_MAX_AGE_MS) {
35799
+ if (!raw || typeof raw !== "object") return null;
35800
+ const m = raw;
35801
+ if (typeof m.ts !== "number" || !Number.isFinite(m.ts)) return null;
35802
+ if (now - m.ts > maxAgeMs || now - m.ts < 0) return null;
35803
+ const out = { ts: m.ts };
35804
+ if (typeof m.task_id === "string" && m.task_id.length > 0) out.task_id = m.task_id;
35805
+ const t = m.target;
35806
+ if (t && typeof t === "object") {
35807
+ const tc = t;
35808
+ if (typeof tc.channel_id === "string" && tc.channel_id.length > 0) {
35809
+ out.target = {
35810
+ channel_id: tc.channel_id,
35811
+ ...typeof tc.thread_ts === "string" && tc.thread_ts.length > 0 ? { thread_ts: tc.thread_ts } : {}
35812
+ };
35813
+ }
35814
+ }
35815
+ return out;
35816
+ }
35817
+
35818
+ // src/turn-context.ts
35819
+ var TURN_INITIATOR_MARKER_FILENAME = ".current-turn-initiator.json";
35820
+ function asSender(raw, now, maxAgeMs) {
35821
+ if (!raw || typeof raw !== "object") return null;
35822
+ const e = raw;
35823
+ if (typeof e["channel"] !== "string" || !e["channel"]) return null;
35824
+ if (typeof e["sender_id"] !== "string" || !e["sender_id"]) return null;
35825
+ const ts = e["ts"];
35826
+ if (typeof ts !== "number" || !Number.isFinite(ts) || now - ts < 0 || now - ts > maxAgeMs) return null;
35827
+ const kind = e["chat_kind"] === "direct" || e["chat_kind"] === "group" ? e["chat_kind"] : "unknown";
35828
+ const chatId = typeof e["chat_id"] === "string" && e["chat_id"] ? e["chat_id"] : void 0;
35829
+ const threadRef = typeof e["channel_ref"] === "string" && e["channel_ref"] ? e["channel_ref"] : void 0;
35830
+ return {
35831
+ channel: e["channel"],
35832
+ sender_id: e["sender_id"],
35833
+ chat_kind: kind,
35834
+ ...chatId ? { chat_id: chatId } : {},
35835
+ ...threadRef ? { thread_ref: threadRef } : {},
35836
+ ts
35837
+ };
35838
+ }
35839
+ function readJson(file) {
35840
+ try {
35841
+ return JSON.parse(readFileSync3(file, "utf8"));
35842
+ } catch {
35843
+ return void 0;
35844
+ }
35845
+ }
35846
+ function freshUnattributed(ledger, now, maxAgeMs) {
35847
+ if (!ledger || !Array.isArray(ledger.entries)) return false;
35848
+ return ledger.entries.some((e) => {
35849
+ const r = e;
35850
+ return r?.unattributed === true && typeof r.ts === "number" && Number.isFinite(r.ts) && now - r.ts >= 0 && now - r.ts <= maxAgeMs;
35851
+ });
35852
+ }
35853
+ function freshSenders(markerFile, ledger, now, maxAgeMs) {
35854
+ if (ledger && ledger.v === 1 && Array.isArray(ledger.entries)) {
35855
+ const fresh = ledger.entries.map((e) => asSender(e, now, maxAgeMs)).filter((s) => s !== null);
35856
+ if (fresh.length > 0) return fresh;
35857
+ }
35858
+ const single = asSender(readJson(markerFile), now, maxAgeMs);
35859
+ return single ? [single] : [];
35860
+ }
35861
+ function resolveTurnInitiatorFile(env2 = process.env, home = homedir()) {
35862
+ const injected = env2["AGT_TURN_INITIATOR_FILE"]?.trim();
35863
+ if (injected) return injected;
35864
+ const dir = resolveAgentDirAlias({
35865
+ codeName: env2["AGT_AGENT_CODE_NAME"],
35866
+ agentId: env2["AGT_AGENT_ID"],
35867
+ turnInitiatorFile: null,
35868
+ homeDir: home
35869
+ });
35870
+ return dir ? join5(dir, TURN_INITIATOR_MARKER_FILENAME) : null;
35871
+ }
35872
+ function readTurnContext(opts = {}) {
35873
+ try {
35874
+ return readTurnContextUnguarded(opts);
35875
+ } catch {
35876
+ return { v: 1, kind: "unavailable" };
35877
+ }
35878
+ }
35879
+ function readTurnContextUnguarded(opts) {
35880
+ const markerFile = opts.markerFile === void 0 ? (opts.resolveFile ?? (() => resolveTurnInitiatorFile()))() : opts.markerFile;
35881
+ if (!markerFile) return { v: 1, kind: "unavailable" };
35882
+ const now = opts.now ?? Date.now();
35883
+ const maxAgeMs = opts.maxAgeMs ?? TURN_INITIATOR_MAX_AGE_MS;
35884
+ const ledger = readJson(join5(dirname3(markerFile), TURN_INITIATOR_LEDGER_FILENAME));
35885
+ const senders = freshSenders(markerFile, ledger, now, maxAgeMs);
35886
+ const scheduled = validateScheduledTurnMarker(
35887
+ readJson(join5(dirname3(markerFile), SCHEDULED_TURN_MARKER_FILENAME2)),
35888
+ now
35889
+ );
35890
+ if (senders.length === 0) return { v: 1, kind: "none" };
35891
+ if (scheduled || freshUnattributed(ledger, now, maxAgeMs)) return { v: 1, kind: "ambiguous" };
35892
+ const latest = [...senders].sort((a, b) => b.ts - a.ts)[0];
35893
+ const same = senders.every(
35894
+ (s) => s.channel === latest.channel && s.sender_id === latest.sender_id && s.chat_kind === latest.chat_kind && s.chat_id === latest.chat_id
35895
+ );
35896
+ if (!same) return { v: 1, kind: "ambiguous" };
35897
+ return {
35898
+ v: 1,
35899
+ kind: "turn",
35900
+ channel: latest.channel,
35901
+ sender_id: latest.sender_id,
35902
+ chat_kind: latest.chat_kind,
35903
+ ...latest.chat_id ? { chat_id: latest.chat_id } : {},
35904
+ // The newest thread: the one the person is replying in now.
35905
+ ...latest.thread_ref ? { thread_ref: latest.thread_ref } : {}
35906
+ };
35907
+ }
35908
+
35782
35909
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v4/core/core.js
35783
35910
  var NEVER2 = Object.freeze({
35784
35911
  status: "aborted"
@@ -46674,12 +46801,12 @@ function selectIntegrationsToRefresh(input) {
46674
46801
  }
46675
46802
 
46676
46803
  // src/self-restart.ts
46677
- import { existsSync as existsSync2, mkdirSync, renameSync, writeFileSync } from "fs";
46678
- import { homedir } from "os";
46679
- import { join as join3 } from "path";
46804
+ import { existsSync as existsSync2, mkdirSync as mkdirSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "fs";
46805
+ import { homedir as homedir2 } from "os";
46806
+ import { join as join6 } from "path";
46680
46807
  import { randomUUID } from "crypto";
46681
46808
  function restartFlagsDir() {
46682
- return join3(homedir(), ".augmented", "restart-flags");
46809
+ return join6(homedir2(), ".augmented", "restart-flags");
46683
46810
  }
46684
46811
  function isSelfRestartEnabled(env2) {
46685
46812
  const raw = (env2.AGT_AGENT_SELF_RESTART_ENABLED ?? "").trim().toLowerCase();
@@ -46690,37 +46817,37 @@ function buildAgentRestartFlag(codeName, reason, nowMs) {
46690
46817
  }
46691
46818
  function writeAgentRestartFlag(codeName, reason, nowMs) {
46692
46819
  const dir = restartFlagsDir();
46693
- if (!existsSync2(dir)) mkdirSync(dir, { recursive: true });
46694
- const path = join3(dir, `${codeName}.flag`);
46820
+ if (!existsSync2(dir)) mkdirSync3(dir, { recursive: true });
46821
+ const path = join6(dir, `${codeName}.flag`);
46695
46822
  const flag = buildAgentRestartFlag(codeName, reason, nowMs);
46696
46823
  const tmpPath = `${path}.${process.pid}.${randomUUID()}.tmp`;
46697
- writeFileSync(tmpPath, JSON.stringify(flag) + "\n", "utf8");
46698
- renameSync(tmpPath, path);
46824
+ writeFileSync2(tmpPath, JSON.stringify(flag) + "\n", "utf8");
46825
+ renameSync2(tmpPath, path);
46699
46826
  return path;
46700
46827
  }
46701
46828
 
46702
46829
  // src/self-restart-confirm.ts
46703
- import { existsSync as existsSync4, readdirSync, readFileSync as readFileSync2 } from "fs";
46704
- import { homedir as homedir2 } from "os";
46705
- import { join as join4 } from "path";
46830
+ import { existsSync as existsSync4, readdirSync, readFileSync as readFileSync5 } from "fs";
46831
+ import { homedir as homedir3 } from "os";
46832
+ import { join as join7 } from "path";
46706
46833
 
46707
46834
  // src/restart-confirm.ts
46708
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
46709
- import { dirname as dirname2 } from "path";
46835
+ import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync4, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "fs";
46836
+ import { dirname as dirname4 } from "path";
46710
46837
  import { randomUUID as randomUUID2 } from "crypto";
46711
46838
  var RESTART_CONFIRM_MAX_AGE_MS = 10 * 60 * 1e3;
46712
46839
  function writeRestartConfirmMarker(filePath, marker) {
46713
- const dir = dirname2(filePath);
46714
- if (!existsSync3(dir)) mkdirSync2(dir, { recursive: true, mode: 448 });
46840
+ const dir = dirname4(filePath);
46841
+ if (!existsSync3(dir)) mkdirSync4(dir, { recursive: true, mode: 448 });
46715
46842
  const tmpPath = `${filePath}.${process.pid}.${randomUUID2()}.tmp`;
46716
- writeFileSync2(tmpPath, JSON.stringify(marker) + "\n", { encoding: "utf8", mode: 384 });
46717
- renameSync2(tmpPath, filePath);
46843
+ writeFileSync3(tmpPath, JSON.stringify(marker) + "\n", { encoding: "utf8", mode: 384 });
46844
+ renameSync3(tmpPath, filePath);
46718
46845
  }
46719
46846
 
46720
46847
  // src/self-restart-confirm.ts
46721
46848
  var SELF_RESTART_PENDING_FRESHNESS_MS = 5 * 60 * 1e3;
46722
46849
  function selfRestartAgentDir(codeName) {
46723
- return join4(homedir2(), ".augmented", codeName);
46850
+ return join7(homedir3(), ".augmented", codeName);
46724
46851
  }
46725
46852
  function selectFreshestPending(candidates, nowMs, maxAgeMs) {
46726
46853
  let best = null;
@@ -46744,7 +46871,7 @@ function readMarkerDir(dir, toCandidate) {
46744
46871
  for (const entry of entries) {
46745
46872
  if (!entry.endsWith(".json") || entry.endsWith(".tmp")) continue;
46746
46873
  try {
46747
- const parsed = JSON.parse(readFileSync2(join4(dir, entry), "utf8"));
46874
+ const parsed = JSON.parse(readFileSync5(join7(dir, entry), "utf8"));
46748
46875
  if (!parsed || typeof parsed !== "object") continue;
46749
46876
  const candidate = toCandidate(parsed);
46750
46877
  if (candidate) out.push(candidate);
@@ -46754,7 +46881,7 @@ function readMarkerDir(dir, toCandidate) {
46754
46881
  return out;
46755
46882
  }
46756
46883
  function readPendingCandidates(agentDir) {
46757
- const slack = readMarkerDir(join4(agentDir, "slack-pending-inbound"), (p2) => {
46884
+ const slack = readMarkerDir(join7(agentDir, "slack-pending-inbound"), (p2) => {
46758
46885
  const channel = p2["channel"];
46759
46886
  if (typeof channel !== "string" || channel.length === 0) return null;
46760
46887
  const threadTs = p2["thread_ts"];
@@ -46762,7 +46889,7 @@ function readPendingCandidates(agentDir) {
46762
46889
  if (typeof threadTs === "string" && threadTs.length > 0) reply["thread_ts"] = threadTs;
46763
46890
  return { source: "slack", receivedAtMs: Date.parse(String(p2["received_at"])), reply };
46764
46891
  });
46765
- const telegram = readMarkerDir(join4(agentDir, "telegram-pending-inbound"), (p2) => {
46892
+ const telegram = readMarkerDir(join7(agentDir, "telegram-pending-inbound"), (p2) => {
46766
46893
  const chatId = p2["chat_id"];
46767
46894
  if (chatId == null || typeof chatId !== "string" && typeof chatId !== "number") return null;
46768
46895
  const reply = { chat_id: chatId };
@@ -46783,21 +46910,21 @@ function captureSelfRestartConfirm(opts) {
46783
46910
  // human, so buildBackOnlineText degrades to the generic copy.
46784
46911
  reply: best.reply
46785
46912
  };
46786
- const file = best.source === "slack" ? join4(opts.agentDir, "slack-restart-confirm.json") : join4(opts.agentDir, "telegram-restart-confirm.json");
46913
+ const file = best.source === "slack" ? join7(opts.agentDir, "slack-restart-confirm.json") : join7(opts.agentDir, "telegram-restart-confirm.json");
46787
46914
  writeRestartConfirmMarker(file, marker);
46788
46915
  return best.source;
46789
46916
  }
46790
46917
 
46791
46918
  // ../core/dist/integrations/forwarded-tools-report.js
46792
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
46793
- import { join as join5 } from "path";
46919
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
46920
+ import { join as join8 } from "path";
46794
46921
  var FORWARDED_TOOLS_REPORT_FILENAME = "forwarded-tools.json";
46795
46922
  function forwardedToolsReportPath(agentDir) {
46796
- return join5(agentDir, FORWARDED_TOOLS_REPORT_FILENAME);
46923
+ return join8(agentDir, FORWARDED_TOOLS_REPORT_FILENAME);
46797
46924
  }
46798
46925
  function writeForwardedToolsReport(agentDir, report) {
46799
46926
  try {
46800
- writeFileSync3(forwardedToolsReportPath(agentDir), JSON.stringify(report), "utf-8");
46927
+ writeFileSync4(forwardedToolsReportPath(agentDir), JSON.stringify(report), "utf-8");
46801
46928
  return true;
46802
46929
  } catch {
46803
46930
  return false;
@@ -50676,9 +50803,9 @@ async function forwardToolCall(toolName, args) {
50676
50803
  // root to its canonical form so both sides of the comparison are real
50677
50804
  // paths. Falls back to the unresolved join if the dir is missing, which
50678
50805
  // then simply refuses (there is nothing to read anyway).
50679
- agentDir: canonicalAgentDir(join6(homedir3(), ".augmented", AGT_AGENT_CODE_NAME)),
50806
+ agentDir: canonicalAgentDir(join9(homedir4(), ".augmented", AGT_AGENT_CODE_NAME)),
50680
50807
  // agent-dir-allow: immediately realpath-resolved to the ADR-0049 agent_id-keyed dir before use as a containment root
50681
- path: { isAbsolute: isAbsolute2, resolve: pathResolve, join: join6, sep: sep2 },
50808
+ path: { isAbsolute: isAbsolute2, resolve: pathResolve, join: join9, sep: sep2 },
50682
50809
  // O_NOFOLLOW is the whole point of opening by flags: the path is already
50683
50810
  // symlink-resolved, so a symlink at the final component means it was
50684
50811
  // swapped after the check, and this turns that into an ELOOP.
@@ -50737,7 +50864,12 @@ async function forwardToolCall(toolName, args) {
50737
50864
  agent_id: AGT_AGENT_ID,
50738
50865
  name: toolName,
50739
50866
  arguments: outgoing,
50740
- run_id: AGT_RUN_ID ?? null
50867
+ run_id: AGT_RUN_ID ?? null,
50868
+ // ENG-11348: who sent this turn, read from the host markers here, never
50869
+ // from the model's arguments. Ninja Lists caps the agent by that
50870
+ // person's access and refuses anything that is not one sender in a
50871
+ // one-to-one conversation; other tools ignore it.
50872
+ turn_context: readTurnContext()
50741
50873
  },
50742
50874
  false,
50743
50875
  FORWARD_TOOL_CALL_TIMEOUT_MS,
@@ -51093,7 +51225,7 @@ async function saveArtefactSourceToFile(artefactId) {
51093
51225
  codeName: AGT_AGENT_CODE_NAME,
51094
51226
  turnInitiatorFile: process.env.AGT_TURN_INITIATOR_FILE,
51095
51227
  agentId: AGT_AGENT_ID,
51096
- homeDir: homedir3()
51228
+ homeDir: homedir4()
51097
51229
  });
51098
51230
  const readOnce = async () => {
51099
51231
  const before = await fetchArtefactRevision(artefactId);
@@ -51108,7 +51240,7 @@ async function saveArtefactSourceToFile(artefactId) {
51108
51240
  };
51109
51241
  let result = await readOnce();
51110
51242
  if (result.revisionState !== "stable") result = await readOnce();
51111
- const filePath = join6(dir, safeDownloadName(`${artefactId}.html`, `${artefactId}.html`));
51243
+ const filePath = join9(dir, safeDownloadName(`${artefactId}.html`, `${artefactId}.html`));
51112
51244
  await writeFile(filePath, result.html, "utf8");
51113
51245
  return {
51114
51246
  path: filePath,
@@ -51188,7 +51320,7 @@ async function exportArtefactToFile(dir, artefactId, format, item) {
51188
51320
  return { kind: "pending", jobId: outcome.jobId, retryAfterMs: outcome.retryAfterMs };
51189
51321
  }
51190
51322
  const fallback = `${artefactId}${item !== void 0 ? `-item-${item + 1}` : ""}.${format}`;
51191
- const filePath = join6(dir, safeDownloadName(outcome.body.filename, fallback));
51323
+ const filePath = join9(dir, safeDownloadName(outcome.body.filename, fallback));
51192
51324
  const buf = Buffer.from(outcome.body.base64, "base64");
51193
51325
  await writeFile(filePath, buf);
51194
51326
  return {
@@ -51215,7 +51347,7 @@ async function downloadArtefactText(params) {
51215
51347
  codeName: AGT_AGENT_CODE_NAME,
51216
51348
  turnInitiatorFile: process.env.AGT_TURN_INITIATOR_FILE,
51217
51349
  agentId: AGT_AGENT_ID,
51218
- homeDir: homedir3()
51350
+ homeDir: homedir4()
51219
51351
  });
51220
51352
  let items;
51221
51353
  let truncatedFrom = null;