@integrity-labs/agt-cli 0.28.336 → 0.28.338

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
@@ -20,6 +20,7 @@ import {
20
20
  getManagerPaths,
21
21
  info,
22
22
  isJsonMode,
23
+ isValidPinVersion,
23
24
  jsonOutput,
24
25
  managerInstallCommand,
25
26
  managerInstallSystemUnitCommand,
@@ -28,6 +29,7 @@ import {
28
29
  managerStopCommand,
29
30
  managerUninstallCommand,
30
31
  managerUninstallSystemUnitCommand,
32
+ normalizePinVersion,
31
33
  provision,
32
34
  readFlagsCache,
33
35
  resolveAllFlags,
@@ -38,7 +40,7 @@ import {
38
40
  success,
39
41
  table,
40
42
  warn
41
- } from "../chunk-VIYSMPXD.js";
43
+ } from "../chunk-S2JJ532Q.js";
42
44
  import {
43
45
  AnchorSessionClient,
44
46
  CHANNEL_REGISTRY,
@@ -68,7 +70,7 @@ import {
68
70
  renderTemplate,
69
71
  resolveChannels,
70
72
  serializeManifestForSlackCli
71
- } from "../chunk-J2WYEOBH.js";
73
+ } from "../chunk-O4V3TMUI.js";
72
74
  import "../chunk-XWVM4KPK.js";
73
75
 
74
76
  // src/bin/agt.ts
@@ -4827,7 +4829,7 @@ import { execFileSync, execSync } from "child_process";
4827
4829
  import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
4828
4830
  import chalk18 from "chalk";
4829
4831
  import ora16 from "ora";
4830
- var cliVersion = true ? "0.28.336" : "dev";
4832
+ var cliVersion = true ? "0.28.338" : "dev";
4831
4833
  async function fetchLatestVersion() {
4832
4834
  const host2 = getHost();
4833
4835
  if (!host2) return null;
@@ -4939,86 +4941,53 @@ function detectBrewOwner() {
4939
4941
  }
4940
4942
  return null;
4941
4943
  }
4942
- async function updateCommand(opts = {}) {
4943
- const json = isJsonMode();
4944
- const spinner = ora16({ text: "Checking for updates\u2026", isSilent: json });
4945
- spinner.start();
4946
- const versionInfo = await fetchLatestVersion();
4947
- if (!versionInfo) {
4948
- spinner.stop();
4949
- if (json) {
4950
- jsonOutput({ ok: false, error: "Could not reach API to check for updates" });
4951
- } else {
4952
- warn("Could not reach the API to check for updates. Check AGT_HOST is set and the API is reachable.");
4953
- }
4954
- process.exitCode = 1;
4955
- return;
4956
- }
4957
- const updateAvailable = isNewerVersion(cliVersion, versionInfo.latest);
4958
- if (!updateAvailable) {
4959
- spinner.stop();
4960
- if (json) {
4961
- jsonOutput({ ok: true, current: cliVersion, latest: versionInfo.latest, update_available: false });
4962
- } else {
4963
- success(`You're on the latest version (${chalk18.bold(cliVersion)})`);
4964
- }
4965
- return;
4966
- }
4967
- spinner.stop();
4944
+ function reportActiveSessionsBlocked(json, current, target) {
4945
+ const { managerPid, tmuxSessions } = detectActiveSessions();
4946
+ if (!managerPid && tmuxSessions.length === 0) return false;
4968
4947
  if (!json) {
4969
- info(`Update available: ${chalk18.dim(cliVersion)} \u2192 ${chalk18.bold.green(versionInfo.latest)}`);
4970
- if (versionInfo.changelog_url) {
4971
- info(`Changelog: ${versionInfo.changelog_url}`);
4972
- }
4973
- }
4974
- if (!opts.force) {
4975
- const { managerPid, tmuxSessions } = detectActiveSessions();
4976
- if (managerPid || tmuxSessions.length > 0) {
4977
- if (!json) {
4978
- warn("Active processes detected:");
4979
- if (managerPid) {
4980
- console.error(chalk18.yellow(` \u2022 Manager process running (PID ${managerPid})`));
4981
- }
4982
- if (tmuxSessions.length > 0) {
4983
- console.error(chalk18.yellow(` \u2022 ${tmuxSessions.length} active agent session(s): ${tmuxSessions.join(", ")}`));
4984
- }
4985
- console.error();
4986
- warn("Updating while the manager is running will leave it on the old version until restarted.");
4987
- warn("Active agent sessions will continue with stale MCP servers.");
4988
- console.error();
4989
- info(`Run ${chalk18.bold("agt update --force")} to update anyway, then restart the manager.`);
4990
- } else {
4991
- jsonOutput({
4992
- ok: false,
4993
- current: cliVersion,
4994
- latest: versionInfo.latest,
4995
- update_available: true,
4996
- updated: false,
4997
- blocked: true,
4998
- manager_running: !!managerPid,
4999
- active_sessions: tmuxSessions,
5000
- error: "Active manager or agent sessions detected. Use --force to override."
5001
- });
5002
- }
5003
- process.exitCode = 1;
5004
- return;
5005
- }
4948
+ warn("Active processes detected:");
4949
+ if (managerPid) {
4950
+ console.error(chalk18.yellow(` \u2022 Manager process running (PID ${managerPid})`));
4951
+ }
4952
+ if (tmuxSessions.length > 0) {
4953
+ console.error(chalk18.yellow(` \u2022 ${tmuxSessions.length} active agent session(s): ${tmuxSessions.join(", ")}`));
4954
+ }
4955
+ console.error();
4956
+ warn("Updating while the manager is running will leave it on the old version until restarted.");
4957
+ warn("Active agent sessions will continue with stale MCP servers.");
4958
+ console.error();
4959
+ info(`Run ${chalk18.bold("agt update --force")} to update anyway, then restart the manager.`);
4960
+ } else {
4961
+ jsonOutput({
4962
+ ok: false,
4963
+ current,
4964
+ latest: target,
4965
+ update_available: true,
4966
+ updated: false,
4967
+ blocked: true,
4968
+ manager_running: !!managerPid,
4969
+ active_sessions: tmuxSessions,
4970
+ error: "Active manager or agent sessions detected. Use --force to override."
4971
+ });
5006
4972
  }
4973
+ return true;
4974
+ }
4975
+ function runInstall(target, json, current) {
5007
4976
  const updateSpinner = ora16({ text: "Installing update\u2026", isSilent: json });
5008
4977
  updateSpinner.start();
5009
4978
  try {
5010
- performUpdate(versionInfo.latest);
4979
+ performUpdate(target);
5011
4980
  updateSpinner.stop();
5012
4981
  if (json) {
5013
4982
  jsonOutput({
5014
4983
  ok: true,
5015
- current: cliVersion,
5016
- latest: versionInfo.latest,
4984
+ current,
4985
+ latest: target,
5017
4986
  update_available: true,
5018
4987
  updated: true
5019
4988
  });
5020
4989
  } else {
5021
- success(`Updated to ${chalk18.bold(versionInfo.latest)}`);
4990
+ success(`Updated to ${chalk18.bold(target)}`);
5022
4991
  info(`If you have a running manager, restart it: ${chalk18.bold("agt manager stop && agt manager start")}`);
5023
4992
  }
5024
4993
  } catch (err) {
@@ -5026,8 +4995,8 @@ async function updateCommand(opts = {}) {
5026
4995
  if (json) {
5027
4996
  jsonOutput({
5028
4997
  ok: false,
5029
- current: cliVersion,
5030
- latest: versionInfo.latest,
4998
+ current,
4999
+ latest: target,
5031
5000
  update_available: true,
5032
5001
  updated: false,
5033
5002
  error: err.message
@@ -5038,12 +5007,113 @@ async function updateCommand(opts = {}) {
5038
5007
  if (source === "brew") {
5039
5008
  info(`You can manually update with: brew upgrade integrity-labs/tap/agt`);
5040
5009
  } else {
5041
- info(`You can manually update with: sudo npm install -g @integrity-labs/agt-cli@${versionInfo.latest}`);
5010
+ info(`You can manually update with: sudo npm install -g @integrity-labs/agt-cli@${target}`);
5042
5011
  }
5043
5012
  }
5044
5013
  process.exitCode = 1;
5045
5014
  }
5046
5015
  }
5016
+ async function updateCommand(opts = {}) {
5017
+ const json = isJsonMode();
5018
+ const pinned = normalizePinVersion(process.env.AGT_CLI_PIN_VERSION);
5019
+ if (opts.version) {
5020
+ const target = opts.version.trim().replace(/^v/, "");
5021
+ if (!isValidPinVersion(target)) {
5022
+ if (json) {
5023
+ jsonOutput({ ok: false, error: `Invalid --version "${opts.version}" (expected a concrete version like 0.28.330)` });
5024
+ } else {
5025
+ error(`Invalid --version "${opts.version}". Expected a concrete version like 0.28.330.`);
5026
+ }
5027
+ process.exitCode = 1;
5028
+ return;
5029
+ }
5030
+ if (target === cliVersion) {
5031
+ if (json) {
5032
+ jsonOutput({ ok: true, current: cliVersion, latest: target, update_available: false });
5033
+ } else {
5034
+ success(`Already on ${chalk18.bold(cliVersion)}.`);
5035
+ }
5036
+ return;
5037
+ }
5038
+ if (detectInstallSource() === "brew") {
5039
+ if (json) {
5040
+ jsonOutput({
5041
+ ok: false,
5042
+ current: cliVersion,
5043
+ error: "agt update --version is not supported on a Homebrew install (brew upgrades only to the latest formula). Use the npm-global install to pin an exact version."
5044
+ });
5045
+ } else {
5046
+ error("`agt update --version` is not supported on a Homebrew install.");
5047
+ info("Homebrew can only upgrade to the tap's latest formula. Use the npm-global install to pin an exact version.");
5048
+ }
5049
+ process.exitCode = 1;
5050
+ return;
5051
+ }
5052
+ if (!json) {
5053
+ info(`Installing ${chalk18.bold(target)} (was ${chalk18.dim(cliVersion)}).`);
5054
+ if (pinned && pinned !== target) {
5055
+ warn(`This host is pinned to ${pinned} via AGT_CLI_PIN_VERSION; the manager will reconcile back to the pin on its next poll unless you also update the pin.`);
5056
+ }
5057
+ }
5058
+ if (!opts.force && reportActiveSessionsBlocked(json, cliVersion, target)) {
5059
+ process.exitCode = 1;
5060
+ return;
5061
+ }
5062
+ runInstall(target, json, cliVersion);
5063
+ return;
5064
+ }
5065
+ if (pinned && !opts.force) {
5066
+ if (json) {
5067
+ jsonOutput({
5068
+ ok: true,
5069
+ current: cliVersion,
5070
+ pinned,
5071
+ update_available: false,
5072
+ blocked: true,
5073
+ error: "Host is pinned via AGT_CLI_PIN_VERSION. Use `agt update --version <v>` to change it, or `agt update --force` to update to latest."
5074
+ });
5075
+ } else {
5076
+ warn(`This host is pinned to ${chalk18.bold(pinned)} via AGT_CLI_PIN_VERSION.`);
5077
+ info(`To change it deliberately, run ${chalk18.bold("agt update --version <version>")}; to update to latest anyway, run ${chalk18.bold("agt update --force")}.`);
5078
+ }
5079
+ return;
5080
+ }
5081
+ const spinner = ora16({ text: "Checking for updates\u2026", isSilent: json });
5082
+ spinner.start();
5083
+ const versionInfo = await fetchLatestVersion();
5084
+ if (!versionInfo) {
5085
+ spinner.stop();
5086
+ if (json) {
5087
+ jsonOutput({ ok: false, error: "Could not reach API to check for updates" });
5088
+ } else {
5089
+ warn("Could not reach the API to check for updates. Check AGT_HOST is set and the API is reachable.");
5090
+ }
5091
+ process.exitCode = 1;
5092
+ return;
5093
+ }
5094
+ const updateAvailable = isNewerVersion(cliVersion, versionInfo.latest);
5095
+ if (!updateAvailable) {
5096
+ spinner.stop();
5097
+ if (json) {
5098
+ jsonOutput({ ok: true, current: cliVersion, latest: versionInfo.latest, update_available: false });
5099
+ } else {
5100
+ success(`You're on the latest version (${chalk18.bold(cliVersion)})`);
5101
+ }
5102
+ return;
5103
+ }
5104
+ spinner.stop();
5105
+ if (!json) {
5106
+ info(`Update available: ${chalk18.dim(cliVersion)} \u2192 ${chalk18.bold.green(versionInfo.latest)}`);
5107
+ if (versionInfo.changelog_url) {
5108
+ info(`Changelog: ${versionInfo.changelog_url}`);
5109
+ }
5110
+ }
5111
+ if (!opts.force && reportActiveSessionsBlocked(json, cliVersion, versionInfo.latest)) {
5112
+ process.exitCode = 1;
5113
+ return;
5114
+ }
5115
+ runInstall(versionInfo.latest, json, cliVersion);
5116
+ }
5047
5117
  async function checkForUpdateOnStartup() {
5048
5118
  try {
5049
5119
  const versionInfo = await fetchLatestVersion();
@@ -5931,7 +6001,7 @@ function handleError(err) {
5931
6001
  }
5932
6002
 
5933
6003
  // src/bin/agt.ts
5934
- var cliVersion2 = true ? "0.28.336" : "dev";
6004
+ var cliVersion2 = true ? "0.28.338" : "dev";
5935
6005
  var program = new Command();
5936
6006
  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");
5937
6007
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -6065,7 +6135,7 @@ integration.command("requests").description("List pending scope approval request
6065
6135
  integration.command("approve <request-id>").description("Approve a scope request").option("--notes <text>", "Review notes").action(integrationApproveCommand);
6066
6136
  integration.command("deny <request-id>").description("Deny a scope request").option("--reason <text>", "Denial reason").action(integrationDenyCommand);
6067
6137
  integration.command("enrol").description("Enrol an integration with an API key or webhook secret (no OAuth flow)").requiredOption("--def <code-name>", "Integration definition code_name (e.g. resend, xero)").requiredOption("--scope <org|team|agent>", "Install scope").option("--api-key <value>", "API key (sets auth_type=api_key)").option("--access-token <value>", "Bearer access token (sets auth_type=oauth2)").option("--webhook-secret <value>", "Webhook signing secret (sets auth_type=webhook)").option("--display-name <name>", "Override display name (defaults to the definition\u2019s display_name)").option("--agent <code-name>", "Agent code name (required for agent scope)").action(integrationEnrolCommand);
6068
- program.command("update").description("Check for and install CLI updates").option("--force", "Update even if manager or agent sessions are running").action(updateCommand);
6138
+ program.command("update").description("Check for and install CLI updates").option("--force", "Update even if manager or agent sessions are running (also overrides a version pin)").option("--version <version>", "Install an exact version (may be a downgrade), bypassing the latest check").action(updateCommand);
6069
6139
  var audit = program.command("audit").description("Operator audits \u2014 sub-agent MCP bindings, etc.");
6070
6140
  audit.command("subagents").description("Find sub-agents whose tools allowlist would block mcp__* calls on dispatch (ENG-5897)").option("--strict", "Exit with code 2 if any findings (suitable for CI gating)").option("--json", "Emit findings as JSON to stdout").action(auditSubagentsCommand);
6071
6141
  audit.command("mcp-render").description("Find managed agents whose subagent .md tools allowlist is stale vs .mcp.json (ENG-5922)").option("--strict", "Exit with code 2 if any findings (suitable for CI gating)").option("--json", "Emit findings as JSON to stdout").action(auditMcpRenderCommand);