@integrity-labs/agt-cli 0.28.293 → 0.28.295

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 CHANGED
@@ -38,7 +38,7 @@ import {
38
38
  success,
39
39
  table,
40
40
  warn
41
- } from "../chunk-D6SMNBPT.js";
41
+ } from "../chunk-VT2HBF2H.js";
42
42
  import {
43
43
  CHANNEL_REGISTRY,
44
44
  DEFAULT_FRAMEWORK,
@@ -4826,7 +4826,7 @@ import { execFileSync, execSync } from "child_process";
4826
4826
  import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
4827
4827
  import chalk18 from "chalk";
4828
4828
  import ora16 from "ora";
4829
- var cliVersion = true ? "0.28.293" : "dev";
4829
+ var cliVersion = true ? "0.28.295" : "dev";
4830
4830
  async function fetchLatestVersion() {
4831
4831
  const host2 = getHost();
4832
4832
  if (!host2) return null;
@@ -5843,7 +5843,7 @@ function handleError(err) {
5843
5843
  }
5844
5844
 
5845
5845
  // src/bin/agt.ts
5846
- var cliVersion2 = true ? "0.28.293" : "dev";
5846
+ var cliVersion2 = true ? "0.28.295" : "dev";
5847
5847
  var program = new Command();
5848
5848
  program.name("agt").description("Augmented CLI \u2014 agent provisioning and management").version(cliVersion2).option("--json", "Emit machine-readable JSON output (suppress spinners and colors)").option("--skip-update-check", "Skip the automatic update check on startup");
5849
5849
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -5882,7 +5882,7 @@ function requireHost() {
5882
5882
  }
5883
5883
 
5884
5884
  // src/lib/api-client.ts
5885
- var agtCliVersion = true ? "0.28.293" : "dev";
5885
+ var agtCliVersion = true ? "0.28.295" : "dev";
5886
5886
  var lastConfigHash = null;
5887
5887
  function setConfigHash(hash) {
5888
5888
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -8181,4 +8181,4 @@ export {
8181
8181
  managerInstallSystemUnitCommand,
8182
8182
  managerUninstallSystemUnitCommand
8183
8183
  };
8184
- //# sourceMappingURL=chunk-D6SMNBPT.js.map
8184
+ //# sourceMappingURL=chunk-VT2HBF2H.js.map
@@ -39,7 +39,7 @@ import {
39
39
  requireHost,
40
40
  safeWriteJsonAtomic,
41
41
  setConfigHash
42
- } from "../chunk-D6SMNBPT.js";
42
+ } from "../chunk-VT2HBF2H.js";
43
43
  import {
44
44
  getProjectDir as getProjectDir2,
45
45
  getReadyTasks,
@@ -3442,6 +3442,63 @@ function killAgentChannelProcesses(codeName, opts) {
3442
3442
  return pids;
3443
3443
  }
3444
3444
 
3445
+ // src/lib/delivery-schedule-link.ts
3446
+ function envSuffixFor(codeName) {
3447
+ return codeName.replace(/[^A-Za-z0-9]+/g, "_").toUpperCase();
3448
+ }
3449
+ function scheduleLinkFooterEnabled(codeName, env = process.env) {
3450
+ if (codeName) {
3451
+ const perAgent = env[`AGT_SCHEDULE_LINK_FOOTER_DISABLED__${envSuffixFor(codeName)}`];
3452
+ if (perAgent === "1") return false;
3453
+ }
3454
+ if (env["AGT_SCHEDULE_LINK_FOOTER_DISABLED"] === "1") return false;
3455
+ return true;
3456
+ }
3457
+ function getConsoleUrl(env = process.env) {
3458
+ const canonical = env["AGT_CONSOLE_URL"]?.trim();
3459
+ if (canonical) return canonical.replace(/\/+$/, "");
3460
+ const fallback = env["NEXT_PUBLIC_APP_URL"]?.trim();
3461
+ if (fallback) return fallback.replace(/\/+$/, "");
3462
+ return null;
3463
+ }
3464
+ function buildScheduleEditLink(consoleUrl, agentId, taskId) {
3465
+ const base = consoleUrl.replace(/\/+$/, "");
3466
+ return `${base}/agents/${encodeURIComponent(agentId)}/schedules/${encodeURIComponent(taskId)}`;
3467
+ }
3468
+ function formatScheduleLinkFooter(url, medium) {
3469
+ if (medium === "slack") return `<${url}|Edit schedule>`;
3470
+ if (medium === "telegram") return `Edit schedule: ${url}`;
3471
+ return url;
3472
+ }
3473
+ function appendScheduleLinkFooter(body, url, medium) {
3474
+ const footer = formatScheduleLinkFooter(url, medium);
3475
+ const trimmed = body.replace(/\s+$/, "");
3476
+ if (trimmed.endsWith(footer)) return trimmed;
3477
+ return `${trimmed}
3478
+
3479
+ ${footer}`;
3480
+ }
3481
+ var warnedNullConsoleUrl = false;
3482
+ function withScheduleLinkFooter(opts) {
3483
+ if (!opts.taskId) return opts.body;
3484
+ if (!scheduleLinkFooterEnabled(opts.codeName, opts.env)) return opts.body;
3485
+ const consoleUrl = getConsoleUrl(opts.env);
3486
+ if (!consoleUrl) {
3487
+ if (!warnedNullConsoleUrl && opts.log) {
3488
+ warnedNullConsoleUrl = true;
3489
+ try {
3490
+ opts.log(
3491
+ "[schedule-link] AGT_CONSOLE_URL unset and NEXT_PUBLIC_APP_URL unset \u2014 schedule-edit deep-link footer disabled. Run `agt setup` again or export AGT_CONSOLE_URL (e.g. https://app.augmented.team) to restore it."
3492
+ );
3493
+ } catch {
3494
+ }
3495
+ }
3496
+ return opts.body;
3497
+ }
3498
+ const url = buildScheduleEditLink(consoleUrl, opts.agentId, opts.taskId);
3499
+ return appendScheduleLinkFooter(opts.body, url, opts.medium);
3500
+ }
3501
+
3445
3502
  // src/lib/manager/agent-state.ts
3446
3503
  var agentState = {
3447
3504
  // ---------------------------------------------------------------------------
@@ -4164,11 +4221,11 @@ function setAlertSlackWebhook(value) {
4164
4221
 
4165
4222
  // src/lib/delivery-hint.ts
4166
4223
  var DEFAULT_PROBABILITY = 0.1;
4167
- function envSuffixFor(codeName) {
4224
+ function envSuffixFor2(codeName) {
4168
4225
  return codeName.replace(/[^A-Za-z0-9]+/g, "_").toUpperCase();
4169
4226
  }
4170
4227
  function hintProbability(codeName, env = process.env) {
4171
- const suffix = codeName ? `__${envSuffixFor(codeName)}` : "";
4228
+ const suffix = codeName ? `__${envSuffixFor2(codeName)}` : "";
4172
4229
  if (suffix && env[`AGT_DELIVERY_HINT_DISABLED${suffix}`] === "1") return 0;
4173
4230
  const perAgent = suffix ? env[`AGT_DELIVERY_HINT_PROBABILITY${suffix}`] : void 0;
4174
4231
  if (perAgent != null) return clampProbability(perAgent);
@@ -4436,6 +4493,29 @@ ${isFailed ? "Reason" : "Result"}: ${resultBody.slice(0, NOTIFY_RESULT_MAX_CHARS
4436
4493
  return `${emoji} ${isFailed ? "Task Failed" : "Task Complete"} \u2014 ${displayName}
4437
4494
  ${item.title}${resultLine}`;
4438
4495
  }
4496
+ function resolveRequesterDmTarget(requester) {
4497
+ if (requester.channel === "slack" && requester.sender_id) {
4498
+ return { channel: "slack", to: requester.sender_id };
4499
+ }
4500
+ if (requester.channel === "telegram" && requester.external_id) {
4501
+ return { channel: "telegram", to: requester.external_id };
4502
+ }
4503
+ return null;
4504
+ }
4505
+ function buildWaitingHumanNotification(args) {
4506
+ const esc = (s) => args.medium === "slack" ? s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") : s;
4507
+ const lines = [`\u{1F514} ${esc(args.displayName)} needs your input on "${esc(args.title)}".`];
4508
+ const ask = args.waitingOn?.trim();
4509
+ if (ask) lines.push(esc(ask));
4510
+ const choiceLabels = (args.choices ?? []).map((c) => c.label?.trim()).filter((l) => !!l).map(esc);
4511
+ if (choiceLabels.length > 0) lines.push(`Options: ${choiceLabels.join(" \xB7 ")}`);
4512
+ if (args.consoleUrl) {
4513
+ const base = args.consoleUrl.replace(/\/+$/, "");
4514
+ const url = `${base}/agents/${encodeURIComponent(args.agentId)}?item=${encodeURIComponent(args.itemId)}`;
4515
+ lines.push(args.medium === "slack" ? `<${url}|Respond>` : `Respond: ${url}`);
4516
+ }
4517
+ return lines.join("\n");
4518
+ }
4439
4519
  async function sendTaskNotification(agentCodeName, channel, to, text) {
4440
4520
  const tokens = agentChannelTokens.get(agentCodeName);
4441
4521
  if (channel === "slack") {
@@ -4613,63 +4693,6 @@ function closeScheduledRunsForCode(codeName, outcome, reason) {
4613
4693
  // src/lib/manager/scheduler/kanban-route.ts
4614
4694
  import { createHash as createHash9 } from "crypto";
4615
4695
 
4616
- // src/lib/delivery-schedule-link.ts
4617
- function envSuffixFor2(codeName) {
4618
- return codeName.replace(/[^A-Za-z0-9]+/g, "_").toUpperCase();
4619
- }
4620
- function scheduleLinkFooterEnabled(codeName, env = process.env) {
4621
- if (codeName) {
4622
- const perAgent = env[`AGT_SCHEDULE_LINK_FOOTER_DISABLED__${envSuffixFor2(codeName)}`];
4623
- if (perAgent === "1") return false;
4624
- }
4625
- if (env["AGT_SCHEDULE_LINK_FOOTER_DISABLED"] === "1") return false;
4626
- return true;
4627
- }
4628
- function getConsoleUrl(env = process.env) {
4629
- const canonical = env["AGT_CONSOLE_URL"]?.trim();
4630
- if (canonical) return canonical.replace(/\/+$/, "");
4631
- const fallback = env["NEXT_PUBLIC_APP_URL"]?.trim();
4632
- if (fallback) return fallback.replace(/\/+$/, "");
4633
- return null;
4634
- }
4635
- function buildScheduleEditLink(consoleUrl, agentId, taskId) {
4636
- const base = consoleUrl.replace(/\/+$/, "");
4637
- return `${base}/agents/${encodeURIComponent(agentId)}/schedules/${encodeURIComponent(taskId)}`;
4638
- }
4639
- function formatScheduleLinkFooter(url, medium) {
4640
- if (medium === "slack") return `<${url}|Edit schedule>`;
4641
- if (medium === "telegram") return `Edit schedule: ${url}`;
4642
- return url;
4643
- }
4644
- function appendScheduleLinkFooter(body, url, medium) {
4645
- const footer = formatScheduleLinkFooter(url, medium);
4646
- const trimmed = body.replace(/\s+$/, "");
4647
- if (trimmed.endsWith(footer)) return trimmed;
4648
- return `${trimmed}
4649
-
4650
- ${footer}`;
4651
- }
4652
- var warnedNullConsoleUrl = false;
4653
- function withScheduleLinkFooter(opts) {
4654
- if (!opts.taskId) return opts.body;
4655
- if (!scheduleLinkFooterEnabled(opts.codeName, opts.env)) return opts.body;
4656
- const consoleUrl = getConsoleUrl(opts.env);
4657
- if (!consoleUrl) {
4658
- if (!warnedNullConsoleUrl && opts.log) {
4659
- warnedNullConsoleUrl = true;
4660
- try {
4661
- opts.log(
4662
- "[schedule-link] AGT_CONSOLE_URL unset and NEXT_PUBLIC_APP_URL unset \u2014 schedule-edit deep-link footer disabled. Run `agt setup` again or export AGT_CONSOLE_URL (e.g. https://app.augmented.team) to restore it."
4663
- );
4664
- } catch {
4665
- }
4666
- }
4667
- return opts.body;
4668
- }
4669
- const url = buildScheduleEditLink(consoleUrl, opts.agentId, opts.taskId);
4670
- return appendScheduleLinkFooter(opts.body, url, opts.medium);
4671
- }
4672
-
4673
4696
  // src/lib/manager/delivery/scheduled-output.ts
4674
4697
  async function deliverScheduledTaskOutput(agentCodeName, agentId, rawTarget, body, taskId) {
4675
4698
  const withLink = (b, medium) => withScheduleLinkFooter({ body: b, medium, codeName: agentCodeName, agentId, taskId, log });
@@ -6901,6 +6924,8 @@ function clearAgentCaches(agentId, codeName) {
6901
6924
  agentChannelTokens.delete(codeName);
6902
6925
  agentFrameworkCache.delete(codeName);
6903
6926
  kanbanBoardCache.delete(codeName);
6927
+ notifyBoardCache.delete(codeName);
6928
+ notifiedWaitingHumanIds.delete(codeName);
6904
6929
  lastHarvestAt.delete(codeName);
6905
6930
  claudeSchedulerStates.delete(codeName);
6906
6931
  claudeTaskConcurrency.delete(codeName);
@@ -6922,7 +6947,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
6922
6947
  var lastVersionCheckAt = 0;
6923
6948
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
6924
6949
  var lastResponsivenessProbeAt = 0;
6925
- var agtCliVersion = true ? "0.28.293" : "dev";
6950
+ var agtCliVersion = true ? "0.28.295" : "dev";
6926
6951
  function resolveBrewPath(execFileSync2) {
6927
6952
  try {
6928
6953
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -10299,6 +10324,45 @@ async function processAgent(agent, agentStates) {
10299
10324
  }
10300
10325
  }
10301
10326
  }
10327
+ {
10328
+ const freshWaitingHumanIds = new Set(
10329
+ freshBoard.filter((b) => b.status === "waiting" && b.waiting_kind === "human" && b.metadata?.requester).map((b) => b.id)
10330
+ );
10331
+ const prevWaitingHumanIds = notifiedWaitingHumanIds.get(agent.code_name);
10332
+ notifiedWaitingHumanIds.set(agent.code_name, freshWaitingHumanIds);
10333
+ if (prevWaitingHumanIds) {
10334
+ const newlyWaiting = freshBoard.filter(
10335
+ (b) => b.status === "waiting" && b.waiting_kind === "human" && !prevWaitingHumanIds.has(b.id) && b.metadata?.requester
10336
+ );
10337
+ if (newlyWaiting.length > 0) {
10338
+ const waitingDisplayName = agentState.agentDisplayNames.get(agent.code_name) ?? agent.code_name;
10339
+ const consoleUrl = getConsoleUrl();
10340
+ for (const item of newlyWaiting) {
10341
+ const requester = item.metadata.requester;
10342
+ const target = resolveRequesterDmTarget(requester);
10343
+ if (!target) {
10344
+ log(
10345
+ `[${agent.code_name}] waiting-human notify skipped for '${item.id}': no DM target for channel=${requester.channel}`
10346
+ );
10347
+ continue;
10348
+ }
10349
+ const message = buildWaitingHumanNotification({
10350
+ displayName: waitingDisplayName,
10351
+ agentId,
10352
+ itemId: item.id,
10353
+ title: item.title,
10354
+ waitingOn: item.waiting_on,
10355
+ choices: item.waiting_context?.choices,
10356
+ medium: target.channel,
10357
+ consoleUrl
10358
+ });
10359
+ sendTaskNotification(agent.code_name, target.channel, target.to, message).catch((err) => {
10360
+ log(`waiting-human notify failed for '${agent.code_name}': ${err.message}`);
10361
+ });
10362
+ }
10363
+ }
10364
+ }
10365
+ }
10302
10366
  const staleItems = freshBoard.filter((b) => {
10303
10367
  if (b.status !== "in_progress" || !b.updated_at) return false;
10304
10368
  const age = Date.now() - new Date(b.updated_at).getTime();
@@ -11419,6 +11483,7 @@ var lastHarvestAt = /* @__PURE__ */ new Map();
11419
11483
  var HARVEST_INTERVAL_MS = 3 * 60 * 1e3;
11420
11484
  var kanbanBoardCache = /* @__PURE__ */ new Map();
11421
11485
  var notifyBoardCache = /* @__PURE__ */ new Map();
11486
+ var notifiedWaitingHumanIds = /* @__PURE__ */ new Map();
11422
11487
  var spawnedPairIds = /* @__PURE__ */ new Set();
11423
11488
  async function processClaudePairSessions(agents) {
11424
11489
  if (agents.length === 0 && spawnedPairIds.size === 0) return;