@integrity-labs/agt-cli 0.28.85 → 0.28.87

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.
@@ -28,7 +28,7 @@ import {
28
28
  requireHost,
29
29
  safeWriteJsonAtomic,
30
30
  setConfigHash
31
- } from "../chunk-4YHL5PJ5.js";
31
+ } from "../chunk-IRXTLOES.js";
32
32
  import {
33
33
  getProjectDir as getProjectDir2,
34
34
  getReadyTasks,
@@ -6886,7 +6886,7 @@ var cachedMaintenanceWindow = null;
6886
6886
  var lastVersionCheckAt = 0;
6887
6887
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
6888
6888
  var lastResponsivenessProbeAt = 0;
6889
- var agtCliVersion = true ? "0.28.85" : "dev";
6889
+ var agtCliVersion = true ? "0.28.87" : "dev";
6890
6890
  function resolveBrewPath(execFileSync4) {
6891
6891
  try {
6892
6892
  const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
package/dist/mcp/index.js CHANGED
@@ -21078,6 +21078,30 @@ function writeAgentRestartFlag(codeName, reason, nowMs) {
21078
21078
  return path;
21079
21079
  }
21080
21080
 
21081
+ // src/feature-request.ts
21082
+ var FEATURE_REQUEST_TYPES = [
21083
+ "integration",
21084
+ "tool",
21085
+ "channel",
21086
+ "capability",
21087
+ "bug",
21088
+ "other"
21089
+ ];
21090
+ function describeFeatureRequestResult(resp) {
21091
+ if (resp.status === "created") {
21092
+ const ref = resp.identifier ? ` (${resp.identifier})` : "";
21093
+ const link = resp.url ? ` ${resp.url}` : "";
21094
+ return {
21095
+ text: `Feature request submitted to Augmented Team support${ref}.${link}`,
21096
+ isError: false
21097
+ };
21098
+ }
21099
+ return {
21100
+ text: `Could not submit the feature request${resp.message ? `: ${resp.message}` : ""}. Tell your operator what you need and don't keep retrying.`,
21101
+ isError: true
21102
+ };
21103
+ }
21104
+
21081
21105
  // src/approval-tools.ts
21082
21106
  function statusToOutcome(status) {
21083
21107
  switch (status) {
@@ -21762,6 +21786,52 @@ server.tool(
21762
21786
  };
21763
21787
  }
21764
21788
  );
21789
+ server.tool(
21790
+ "request_feature",
21791
+ 'Send a feature request to Augmented Team support \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.',
21792
+ {
21793
+ feature_type: external_exports.enum(FEATURE_REQUEST_TYPES).describe(
21794
+ 'What kind of request this is. Use "integration" to ask for a new third-party integration/toolkit; otherwise: tool, channel, capability, bug, or other.'
21795
+ ),
21796
+ title: external_exports.string().min(1).max(200).describe('Short, specific summary of the request (e.g. "Add Notion integration").'),
21797
+ description: external_exports.string().min(1).max(4e3).describe(
21798
+ "What you need and why \u2014 the use case, what the user was trying to do, and any specifics. The more concrete, the faster support can act."
21799
+ ),
21800
+ provider: external_exports.string().max(120).optional().describe(
21801
+ 'For feature_type="integration": the name of the service/provider requested (e.g. "Notion", "QuickBooks"). Omit for other types.'
21802
+ )
21803
+ },
21804
+ async (params) => {
21805
+ if (!AGT_AGENT_CODE_NAME) {
21806
+ return {
21807
+ content: [{ type: "text", text: "Error: AGT_AGENT_CODE_NAME not configured." }],
21808
+ isError: true
21809
+ };
21810
+ }
21811
+ let resp;
21812
+ try {
21813
+ resp = await apiPost("/host/request-feature", {
21814
+ agent_code_name: AGT_AGENT_CODE_NAME,
21815
+ feature_type: params.feature_type,
21816
+ title: params.title,
21817
+ description: params.description,
21818
+ ...params.provider ? { provider: params.provider } : {}
21819
+ });
21820
+ } catch (err) {
21821
+ return {
21822
+ content: [
21823
+ {
21824
+ type: "text",
21825
+ text: `Could not reach the feature-request service (${err instanceof Error ? err.message : String(err)}). Tell your operator what you need.`
21826
+ }
21827
+ ],
21828
+ isError: true
21829
+ };
21830
+ }
21831
+ const { text, isError } = describeFeatureRequestResult(resp);
21832
+ return { content: [{ type: "text", text }], ...isError ? { isError: true } : {} };
21833
+ }
21834
+ );
21765
21835
  server.tool(
21766
21836
  "drift_report",
21767
21837
  "Report configuration drift detected in local agent files (CHARTER.md, TOOLS.md, etc.). Compares local file hashes against API-side versions and reports any differences.",
@@ -22651,7 +22721,11 @@ var LOCAL_TOOL_NAMES = /* @__PURE__ */ new Set([
22651
22721
  // AGT_AGENT_SELF_RESTART_ENABLED), but the lockstep guard parses the
22652
22722
  // server.tool('request_restart', …) call statically, so it lives here too.
22653
22723
  // No API tool shares this name, so the forwarding-skip effect is a no-op.
22654
- "request_restart"
22724
+ "request_restart",
22725
+ // ENG-6577: feature-request intake (always registered). No API tool shares
22726
+ // this name, so the forwarding-skip is a no-op; listed here to keep the
22727
+ // lockstep guard green.
22728
+ "request_feature"
22655
22729
  ]);
22656
22730
  async function registerForwardedApiTools() {
22657
22731
  const apiTools = await discoverApiTools();
@@ -14471,15 +14471,15 @@ import {
14471
14471
  createWriteStream,
14472
14472
  existsSync as existsSync6,
14473
14473
  ftruncateSync,
14474
- mkdirSync as mkdirSync6,
14474
+ mkdirSync as mkdirSync7,
14475
14475
  openSync,
14476
14476
  readFileSync as readFileSync9,
14477
14477
  readdirSync as readdirSync3,
14478
- renameSync as renameSync5,
14478
+ renameSync as renameSync6,
14479
14479
  statSync as statSync2,
14480
14480
  unlinkSync as unlinkSync6,
14481
14481
  watch,
14482
- writeFileSync as writeFileSync7,
14482
+ writeFileSync as writeFileSync8,
14483
14483
  writeSync
14484
14484
  } from "fs";
14485
14485
  import { homedir as homedir3 } from "os";
@@ -15083,6 +15083,22 @@ function isMaintenanceModeActive(opts) {
15083
15083
  });
15084
15084
  }
15085
15085
 
15086
+ // src/turn-initiator-marker.ts
15087
+ import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, renameSync as renameSync3 } from "fs";
15088
+ import { dirname as dirname3 } from "path";
15089
+ function writeTurnInitiatorMarker(input) {
15090
+ const file = process.env["AGT_TURN_INITIATOR_FILE"];
15091
+ if (!file || !input.sender_id) return;
15092
+ try {
15093
+ mkdirSync4(dirname3(file), { recursive: true });
15094
+ const marker = { ...input, ts: Date.now() };
15095
+ const tmp = `${file}.tmp`;
15096
+ writeFileSync4(tmp, JSON.stringify(marker), "utf8");
15097
+ renameSync3(tmp, file);
15098
+ } catch {
15099
+ }
15100
+ }
15101
+
15086
15102
  // src/watch-command.ts
15087
15103
  var WATCH_DEFAULT_DURATION_MS = 2 * 60 * 60 * 1e3;
15088
15104
  var WATCH_MAX_DURATION_MS = 7 * 24 * 60 * 60 * 1e3;
@@ -15696,11 +15712,11 @@ function buildCommandRegistrations() {
15696
15712
  // src/telegram-offset-store.ts
15697
15713
  import {
15698
15714
  existsSync as existsSync3,
15699
- mkdirSync as mkdirSync4,
15715
+ mkdirSync as mkdirSync5,
15700
15716
  readFileSync as readFileSync4,
15701
- renameSync as renameSync3,
15717
+ renameSync as renameSync4,
15702
15718
  unlinkSync as unlinkSync4,
15703
- writeFileSync as writeFileSync4
15719
+ writeFileSync as writeFileSync5
15704
15720
  } from "fs";
15705
15721
  import { randomUUID as randomUUID2 } from "crypto";
15706
15722
  function loadPersistedOffset(filePath) {
@@ -15729,9 +15745,9 @@ function persistOffset(opts) {
15729
15745
  };
15730
15746
  const tmpPath = `${filePath}.${process.pid}.${randomUUID2()}.tmp`;
15731
15747
  try {
15732
- mkdirSync4(dir, { recursive: true, mode: 448 });
15733
- writeFileSync4(tmpPath, JSON.stringify(marker), { mode: 384 });
15734
- renameSync3(tmpPath, filePath);
15748
+ mkdirSync5(dir, { recursive: true, mode: 448 });
15749
+ writeFileSync5(tmpPath, JSON.stringify(marker), { mode: 384 });
15750
+ renameSync4(tmpPath, filePath);
15735
15751
  } catch (err) {
15736
15752
  onError?.(`getUpdates offset persist failed: ${err.message}`);
15737
15753
  try {
@@ -16362,11 +16378,11 @@ function parseProgressHeartbeat(raw) {
16362
16378
  // src/mcp-spawn-lock.ts
16363
16379
  import {
16364
16380
  existsSync as existsSync5,
16365
- mkdirSync as mkdirSync5,
16381
+ mkdirSync as mkdirSync6,
16366
16382
  readFileSync as readFileSync7,
16367
- renameSync as renameSync4,
16383
+ renameSync as renameSync5,
16368
16384
  unlinkSync as unlinkSync5,
16369
- writeFileSync as writeFileSync5
16385
+ writeFileSync as writeFileSync6
16370
16386
  } from "fs";
16371
16387
  import { join as join5 } from "path";
16372
16388
  function defaultIsPidAlive(pid) {
@@ -16396,11 +16412,11 @@ function acquireMcpSpawnLock(args) {
16396
16412
  return { kind: "blocked", path, holder: existing };
16397
16413
  }
16398
16414
  }
16399
- mkdirSync5(agentDir, { recursive: true, mode: 448 });
16415
+ mkdirSync6(agentDir, { recursive: true, mode: 448 });
16400
16416
  const tmpPath = `${path}.${selfPid}.tmp`;
16401
16417
  const payload = { pid: selfPid, started_at: now() };
16402
- writeFileSync5(tmpPath, JSON.stringify(payload), { mode: 384 });
16403
- renameSync4(tmpPath, path);
16418
+ writeFileSync6(tmpPath, JSON.stringify(payload), { mode: 384 });
16419
+ renameSync5(tmpPath, path);
16404
16420
  return { kind: "acquired", path };
16405
16421
  }
16406
16422
  function releaseMcpSpawnLock(lockPath, opts = {}) {
@@ -16429,7 +16445,7 @@ function readLockHolder(path) {
16429
16445
  }
16430
16446
 
16431
16447
  // src/ack-reaction.ts
16432
- import { readdirSync as readdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "fs";
16448
+ import { readdirSync as readdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
16433
16449
  import { join as join6 } from "path";
16434
16450
  var REPLY_WEDGED_THRESHOLD_MS = 5 * 60 * 1e3;
16435
16451
  var ACK_STARTUP_GRACE_MS = 6e4;
@@ -16603,7 +16619,7 @@ function recordChannelDeflection(agentDir, channel, cause) {
16603
16619
  }
16604
16620
  counts[cause] = (counts[cause] ?? 0) + 1;
16605
16621
  try {
16606
- writeFileSync6(path, JSON.stringify(counts), { mode: 384 });
16622
+ writeFileSync7(path, JSON.stringify(counts), { mode: 384 });
16607
16623
  } catch {
16608
16624
  }
16609
16625
  }
@@ -16740,7 +16756,7 @@ var stderrLogStream = null;
16740
16756
  if (AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown") {
16741
16757
  try {
16742
16758
  const logDir = join7(homedir3(), ".augmented", AGENT_CODE_NAME);
16743
- mkdirSync6(logDir, { recursive: true });
16759
+ mkdirSync7(logDir, { recursive: true });
16744
16760
  stderrLogStream = createWriteStream(join7(logDir, "telegram-channel-stderr.log"), {
16745
16761
  flags: "a",
16746
16762
  mode: 384
@@ -17260,7 +17276,7 @@ async function handleOnboardingCommand(opts) {
17260
17276
  async function handleRestartCommand(opts) {
17261
17277
  try {
17262
17278
  if (!existsSync6(RESTART_FLAGS_DIR)) {
17263
- mkdirSync6(RESTART_FLAGS_DIR, { recursive: true });
17279
+ mkdirSync7(RESTART_FLAGS_DIR, { recursive: true });
17264
17280
  }
17265
17281
  const flagPath = join7(RESTART_FLAGS_DIR, `${AGENT_CODE_NAME}.flag`);
17266
17282
  writeTelegramRestartConfirm(
@@ -17274,8 +17290,8 @@ async function handleRestartCommand(opts) {
17274
17290
  reply: { chat_id: opts.chatId, message_id: opts.messageId }
17275
17291
  };
17276
17292
  const tmpPath = `${flagPath}.${process.pid}.${randomUUID3()}.tmp`;
17277
- writeFileSync7(tmpPath, JSON.stringify(flag) + "\n", "utf8");
17278
- renameSync5(tmpPath, flagPath);
17293
+ writeFileSync8(tmpPath, JSON.stringify(flag) + "\n", "utf8");
17294
+ renameSync6(tmpPath, flagPath);
17279
17295
  process.stderr.write(
17280
17296
  `telegram-channel(${AGENT_CODE_NAME}): /restart queued from chat ${redactId(opts.chatId)}
17281
17297
  `
@@ -17732,8 +17748,8 @@ function writePendingInboundMarker(chatId, messageId, chatType, undeliverable =
17732
17748
  ...payload ? { payload } : {}
17733
17749
  };
17734
17750
  try {
17735
- mkdirSync6(PENDING_INBOUND_DIR, { recursive: true, mode: 448 });
17736
- writeFileSync7(path, JSON.stringify(marker), { mode: 384 });
17751
+ mkdirSync7(PENDING_INBOUND_DIR, { recursive: true, mode: 448 });
17752
+ writeFileSync8(path, JSON.stringify(marker), { mode: 384 });
17737
17753
  } catch (err) {
17738
17754
  process.stderr.write(
17739
17755
  `telegram-channel(${AGENT_CODE_NAME}): pending-inbound marker write failed: ${err.message}
@@ -17837,7 +17853,7 @@ async function processRecoveryOutboxFile(filename) {
17837
17853
  `
17838
17854
  );
17839
17855
  try {
17840
- renameSync5(fullPath, `${fullPath}.parse-error.poison`);
17856
+ renameSync6(fullPath, `${fullPath}.parse-error.poison`);
17841
17857
  } catch {
17842
17858
  }
17843
17859
  return;
@@ -17848,7 +17864,7 @@ async function processRecoveryOutboxFile(filename) {
17848
17864
  `
17849
17865
  );
17850
17866
  try {
17851
- renameSync5(fullPath, `${fullPath}.malformed.poison`);
17867
+ renameSync6(fullPath, `${fullPath}.malformed.poison`);
17852
17868
  } catch {
17853
17869
  }
17854
17870
  return;
@@ -17895,7 +17911,7 @@ ${payload.text}`;
17895
17911
  const next = nextRetryName(filename);
17896
17912
  if (next) {
17897
17913
  try {
17898
- renameSync5(fullPath, join7(RECOVERY_OUTBOX_DIR, next.next));
17914
+ renameSync6(fullPath, join7(RECOVERY_OUTBOX_DIR, next.next));
17899
17915
  if (next.attempt >= MAX_RECOVERY_ATTEMPTS) {
17900
17916
  process.stderr.write(
17901
17917
  `telegram-channel(${AGENT_CODE_NAME}): ghost-reply recovery exhausted retries \u2014 moved to ${next.next}
@@ -17947,7 +17963,7 @@ function scanRecoveryRetries() {
17947
17963
  function startRecoveryOutboxWatcher() {
17948
17964
  if (!RECOVERY_OUTBOX_DIR) return;
17949
17965
  try {
17950
- mkdirSync6(RECOVERY_OUTBOX_DIR, { recursive: true, mode: 448 });
17966
+ mkdirSync7(RECOVERY_OUTBOX_DIR, { recursive: true, mode: 448 });
17951
17967
  } catch (err) {
17952
17968
  process.stderr.write(
17953
17969
  `telegram-channel(${AGENT_CODE_NAME}): recovery outbox mkdir failed: ${err.message}
@@ -19519,6 +19535,14 @@ async function pollLoop() {
19519
19535
  is_bot: isFromBot,
19520
19536
  is_peer_agent: !!peerAgentMeta
19521
19537
  });
19538
+ if (!isFromBot && !peerAgentMeta && userId && userId !== "unknown" && chatId) {
19539
+ writeTurnInitiatorMarker({
19540
+ channel: "telegram",
19541
+ sender_id: String(userId),
19542
+ sender_name: userName,
19543
+ channel_ref: String(chatId)
19544
+ });
19545
+ }
19522
19546
  if (!isFromBot && !peerAgentMeta) {
19523
19547
  inboundContextClient?.recordInbound({
19524
19548
  sourceIntegration: "telegram",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.85",
3
+ "version": "0.28.87",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {