@integrity-labs/agt-cli 0.10.0 → 0.10.2

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
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- AGT_HOST,
4
3
  ApiError,
5
4
  CHANNEL_REGISTRY,
6
5
  DEPLOYMENT_TEMPLATES,
@@ -21,6 +20,7 @@ import {
21
20
  getChannel,
22
21
  getDefaultSlackScopes,
23
22
  getFramework,
23
+ getHost,
24
24
  getHostId,
25
25
  getScopesByCategory,
26
26
  getTemplate,
@@ -32,7 +32,7 @@ import {
32
32
  resolveChannels,
33
33
  serializeManifestForSlackCli,
34
34
  setActiveTeam
35
- } from "../chunk-UWH2MMKY.js";
35
+ } from "../chunk-VCKY6MN2.js";
36
36
 
37
37
  // src/bin/agt.ts
38
38
  import { join as join11 } from "path";
@@ -107,7 +107,7 @@ async function whoamiCommand() {
107
107
  jsonOutput({
108
108
  ok: true,
109
109
  api_key_prefix: apiKey.slice(0, 8) + "****",
110
- host: AGT_HOST ?? null,
110
+ host: getHost() ?? null,
111
111
  host_id: exchange.hostId,
112
112
  team: exchange.teamSlug,
113
113
  team_id: exchange.teamId,
@@ -117,7 +117,7 @@ async function whoamiCommand() {
117
117
  }
118
118
  success("Authenticated via API key");
119
119
  info(`API Key: ${chalk3.bold(apiKey.slice(0, 8) + "****")}`);
120
- info(`Host: ${chalk3.bold(AGT_HOST ?? "not set")}`);
120
+ info(`Host: ${chalk3.bold(getHost() ?? "not set")}`);
121
121
  info(`Host ID: ${exchange.hostId}`);
122
122
  info(`Team: ${chalk3.bold(exchange.teamSlug ?? exchange.teamId)}`);
123
123
  info(`User: ${chalk3.bold(exchange.userEmail ?? "unknown")}`);
@@ -2172,7 +2172,7 @@ function getManagerStatus() {
2172
2172
  // src/commands/manager.ts
2173
2173
  function managerStartCommand(opts) {
2174
2174
  const json = isJsonMode();
2175
- if (!AGT_HOST) {
2175
+ if (!getHost()) {
2176
2176
  const msg = "AGT_HOST is not set. Export it to point at the Augmented API (e.g. export AGT_HOST=https://your-api.example.com)";
2177
2177
  if (json) {
2178
2178
  jsonOutput({ ok: false, error: msg });
@@ -3411,9 +3411,9 @@ async function acpxCloseCommand(agent2, _opts, cmd) {
3411
3411
  import { execSync } from "child_process";
3412
3412
  import chalk19 from "chalk";
3413
3413
  import ora15 from "ora";
3414
- var cliVersion = true ? "0.10.0" : "dev";
3414
+ var cliVersion = true ? "0.10.2" : "dev";
3415
3415
  async function fetchLatestVersion() {
3416
- const host2 = AGT_HOST;
3416
+ const host2 = getHost();
3417
3417
  if (!host2) return null;
3418
3418
  try {
3419
3419
  const controller = new AbortController();
@@ -3583,8 +3583,234 @@ async function checkForUpdateOnStartup() {
3583
3583
  }
3584
3584
  }
3585
3585
 
3586
+ // src/commands/plugin.ts
3587
+ import chalk20 from "chalk";
3588
+ import ora16 from "ora";
3589
+ async function pluginListCommand() {
3590
+ const json = isJsonMode();
3591
+ const spinner = ora16({ text: "Fetching plugins\u2026", isSilent: json }).start();
3592
+ try {
3593
+ const data = await api.get("/plugins");
3594
+ spinner.stop();
3595
+ if (json) {
3596
+ jsonOutput({ plugins: data });
3597
+ return;
3598
+ }
3599
+ if (!data.length) {
3600
+ info("No plugins found for this team.");
3601
+ return;
3602
+ }
3603
+ console.log(chalk20.bold("\nAvailable Plugins:\n"));
3604
+ for (const p of data) {
3605
+ const statusColor = p.status === "published" ? chalk20.green : p.status === "archived" ? chalk20.gray : chalk20.yellow;
3606
+ console.log(
3607
+ ` ${chalk20.bold(p.name)} ${chalk20.dim(`(${p.slug})`)} ${statusColor(p.status)} v${p.version} ${chalk20.dim(`${p.skills?.length ?? 0} skills, ${p.defined_scopes?.length ?? 0} scopes`)}`
3608
+ );
3609
+ }
3610
+ console.log();
3611
+ } catch (err) {
3612
+ spinner.stop();
3613
+ handleError(err);
3614
+ }
3615
+ }
3616
+ async function pluginShowCommand(slug) {
3617
+ const json = isJsonMode();
3618
+ const spinner = ora16({ text: "Fetching plugin\u2026", isSilent: json }).start();
3619
+ try {
3620
+ const all = await api.get("/plugins");
3621
+ const plugin2 = all.find((p) => p.slug === slug);
3622
+ if (!plugin2) {
3623
+ spinner.stop();
3624
+ error(`Plugin "${slug}" not found.`);
3625
+ process.exitCode = 1;
3626
+ return;
3627
+ }
3628
+ const scopes = await api.get(`/plugins/${plugin2.id}/scopes`);
3629
+ spinner.stop();
3630
+ if (json) {
3631
+ jsonOutput({ plugin: plugin2, scopes });
3632
+ return;
3633
+ }
3634
+ console.log(chalk20.bold(`
3635
+ ${plugin2.name}`), chalk20.dim(`(${plugin2.slug})`));
3636
+ if (plugin2.description) console.log(chalk20.dim(plugin2.description));
3637
+ console.log();
3638
+ console.log(` Status: ${plugin2.status} v${plugin2.version}`);
3639
+ console.log(` Category: ${plugin2.category}`);
3640
+ console.log(` Toolkits: ${plugin2.required_toolkits.join(", ") || "none"}`);
3641
+ console.log(` Skills: ${plugin2.skills?.length ?? 0}`);
3642
+ if (scopes.length > 0) {
3643
+ console.log(chalk20.bold("\n Permission Scopes:\n"));
3644
+ for (const s of scopes) {
3645
+ const roleColor = s.can_grant ? chalk20.green : chalk20.red;
3646
+ const overrideTag = s.is_overridden ? chalk20.cyan(" [team override]") : "";
3647
+ console.log(
3648
+ ` ${chalk20.bold(s.id)} ${s.name} min: ${roleColor(s.effective_min_role)}${overrideTag} ${s.can_grant ? chalk20.green("\u2713 grantable") : chalk20.red("\u2717 needs approval")}`
3649
+ );
3650
+ }
3651
+ }
3652
+ console.log();
3653
+ } catch (err) {
3654
+ spinner.stop();
3655
+ handleError(err);
3656
+ }
3657
+ }
3658
+ async function pluginInstallCommand(slug, options) {
3659
+ const json = isJsonMode();
3660
+ const spinner = ora16({ text: "Installing plugin\u2026", isSilent: json }).start();
3661
+ try {
3662
+ const all = await api.get("/plugins");
3663
+ const plugin2 = all.find((p) => p.slug === slug);
3664
+ if (!plugin2) {
3665
+ spinner.stop();
3666
+ error(`Plugin "${slug}" not found.`);
3667
+ process.exitCode = 1;
3668
+ return;
3669
+ }
3670
+ const agents = await api.get("/agents");
3671
+ const agent2 = agents.find((a) => a.code_name === options.agent);
3672
+ if (!agent2) {
3673
+ spinner.stop();
3674
+ error(`Agent "${options.agent}" not found.`);
3675
+ process.exitCode = 1;
3676
+ return;
3677
+ }
3678
+ const scopes = options.scopes?.split(",").map((s) => s.trim()).filter(Boolean) ?? [];
3679
+ const result = await api.post("/plugins/install", {
3680
+ agent_id: agent2.agent_id,
3681
+ plugin_id: plugin2.id,
3682
+ scopes
3683
+ });
3684
+ spinner.stop();
3685
+ if (json) {
3686
+ jsonOutput({ agent_plugin: result });
3687
+ return;
3688
+ }
3689
+ success(`Installed "${plugin2.name}" on agent "${options.agent}"`);
3690
+ if (scopes.length) {
3691
+ info(`Granted scopes: ${scopes.join(", ")}`);
3692
+ }
3693
+ } catch (err) {
3694
+ spinner.stop();
3695
+ if (err instanceof ApiError && err.status === 403 && err.body["needs_approval"]) {
3696
+ const needsApproval = err.body["needs_approval"];
3697
+ error("Some scopes exceed your role ceiling:");
3698
+ for (const s of needsApproval) {
3699
+ console.log(chalk20.yellow(` - ${s}`));
3700
+ }
3701
+ info("To request elevated scopes, use the web dashboard or contact your team admin.");
3702
+ process.exitCode = 1;
3703
+ return;
3704
+ }
3705
+ handleError(err);
3706
+ }
3707
+ }
3708
+ async function pluginUninstallCommand(slug, options) {
3709
+ const json = isJsonMode();
3710
+ const spinner = ora16({ text: "Uninstalling plugin\u2026", isSilent: json }).start();
3711
+ try {
3712
+ const all = await api.get("/plugins");
3713
+ const plugin2 = all.find((p) => p.slug === slug);
3714
+ if (!plugin2) {
3715
+ spinner.stop();
3716
+ error(`Plugin "${slug}" not found.`);
3717
+ process.exitCode = 1;
3718
+ return;
3719
+ }
3720
+ const agents = await api.get("/agents");
3721
+ const agent2 = agents.find((a) => a.code_name === options.agent);
3722
+ if (!agent2) {
3723
+ spinner.stop();
3724
+ error(`Agent "${options.agent}" not found.`);
3725
+ process.exitCode = 1;
3726
+ return;
3727
+ }
3728
+ await api.post("/plugins/uninstall", {
3729
+ agent_id: agent2.agent_id,
3730
+ plugin_id: plugin2.id
3731
+ });
3732
+ spinner.stop();
3733
+ success(`Uninstalled "${plugin2.name}" from agent "${options.agent}"`);
3734
+ } catch (err) {
3735
+ spinner.stop();
3736
+ handleError(err);
3737
+ }
3738
+ }
3739
+ async function pluginRequestsCommand() {
3740
+ const json = isJsonMode();
3741
+ const spinner = ora16({ text: "Fetching scope requests\u2026", isSilent: json }).start();
3742
+ try {
3743
+ const requests = await api.get("/plugins/scope-requests");
3744
+ spinner.stop();
3745
+ if (json) {
3746
+ jsonOutput({ requests });
3747
+ return;
3748
+ }
3749
+ if (!requests.length) {
3750
+ info("No pending scope requests.");
3751
+ return;
3752
+ }
3753
+ console.log(chalk20.bold("\nPending Scope Requests:\n"));
3754
+ for (const r of requests) {
3755
+ console.log(` ${chalk20.bold(r.id)} scopes: ${r.requested_scopes.join(", ")}`);
3756
+ if (r.reason) console.log(` reason: ${chalk20.dim(r.reason)}`);
3757
+ console.log(` status: ${r.status} requested: ${r.created_at}`);
3758
+ console.log();
3759
+ }
3760
+ } catch (err) {
3761
+ spinner.stop();
3762
+ handleError(err);
3763
+ }
3764
+ }
3765
+ async function pluginApproveCommand(requestId, options) {
3766
+ const json = isJsonMode();
3767
+ const spinner = ora16({ text: "Approving request\u2026", isSilent: json }).start();
3768
+ try {
3769
+ const result = await api.put(`/plugins/scope-requests/${requestId}`, {
3770
+ status: "approved",
3771
+ review_notes: options.notes
3772
+ });
3773
+ spinner.stop();
3774
+ if (json) {
3775
+ jsonOutput(result);
3776
+ return;
3777
+ }
3778
+ success(`Scope request ${requestId} approved. Scopes have been granted.`);
3779
+ } catch (err) {
3780
+ spinner.stop();
3781
+ handleError(err);
3782
+ }
3783
+ }
3784
+ async function pluginDenyCommand(requestId, options) {
3785
+ const json = isJsonMode();
3786
+ const spinner = ora16({ text: "Denying request\u2026", isSilent: json }).start();
3787
+ try {
3788
+ const result = await api.put(`/plugins/scope-requests/${requestId}`, {
3789
+ status: "denied",
3790
+ review_notes: options.reason
3791
+ });
3792
+ spinner.stop();
3793
+ if (json) {
3794
+ jsonOutput(result);
3795
+ return;
3796
+ }
3797
+ success(`Scope request ${requestId} denied.`);
3798
+ } catch (err) {
3799
+ spinner.stop();
3800
+ handleError(err);
3801
+ }
3802
+ }
3803
+ function handleError(err) {
3804
+ if (err instanceof ApiError) {
3805
+ error(`API error (${err.status}): ${err.message}`);
3806
+ } else {
3807
+ error(err.message);
3808
+ }
3809
+ process.exitCode = 1;
3810
+ }
3811
+
3586
3812
  // src/bin/agt.ts
3587
- var cliVersion2 = true ? "0.10.0" : "dev";
3813
+ var cliVersion2 = true ? "0.10.2" : "dev";
3588
3814
  var program = new Command();
3589
3815
  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");
3590
3816
  program.hook("preAction", (thisCommand) => {
@@ -3647,6 +3873,14 @@ acpx.command("exec <agent> <prompt>").description("One-shot execution (no sessio
3647
3873
  acpx.command("list-sessions <agent>").description("List active ACP sessions for an agent").action(acpxListSessionsCommand);
3648
3874
  acpx.command("cancel <agent>").description("Send cooperative cancel to the running ACP session").action(acpxCancelCommand);
3649
3875
  acpx.command("close <agent>").description("Soft-close an ACP session (preserves history)").action(acpxCloseCommand);
3876
+ var plugin = program.command("plugin").description("Manage plugins \u2014 install, configure, and control permission scopes");
3877
+ plugin.command("list").description("List available plugins for the active team").action(pluginListCommand);
3878
+ plugin.command("show <slug>").description("Show plugin details including permission scopes").action(pluginShowCommand);
3879
+ plugin.command("install <slug>").description("Install a plugin on an agent").requiredOption("--agent <code-name>", "Agent code name").option("--scopes <scopes>", "Comma-separated scope IDs to grant").action(pluginInstallCommand);
3880
+ plugin.command("uninstall <slug>").description("Remove a plugin from an agent").requiredOption("--agent <code-name>", "Agent code name").action(pluginUninstallCommand);
3881
+ plugin.command("requests").description("List pending scope approval requests for the team").action(pluginRequestsCommand);
3882
+ plugin.command("approve <request-id>").description("Approve a scope request").option("--notes <text>", "Review notes").action(pluginApproveCommand);
3883
+ plugin.command("deny <request-id>").description("Deny a scope request").option("--reason <text>", "Denial reason").action(pluginDenyCommand);
3650
3884
  program.command("update").description("Check for and install CLI updates").option("--force", "Update even if manager or agent sessions are running").action(updateCommand);
3651
3885
  var skipUpdateCheck = process.argv.includes("--skip-update-check") || process.argv.includes("--json") || process.argv[2] === "update";
3652
3886
  if (!skipUpdateCheck) {