@integrity-labs/agt-cli 0.10.1 → 0.10.3

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
@@ -32,7 +32,7 @@ import {
32
32
  resolveChannels,
33
33
  serializeManifestForSlackCli,
34
34
  setActiveTeam
35
- } from "../chunk-N7TRKQMT.js";
35
+ } from "../chunk-6YGOQRAR.js";
36
36
 
37
37
  // src/bin/agt.ts
38
38
  import { join as join11 } from "path";
@@ -3411,7 +3411,7 @@ 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.1" : "dev";
3414
+ var cliVersion = true ? "0.10.3" : "dev";
3415
3415
  async function fetchLatestVersion() {
3416
3416
  const host2 = getHost();
3417
3417
  if (!host2) return null;
@@ -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.1" : "dev";
3813
+ var cliVersion2 = true ? "0.10.3" : "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) {