agentsclimarketplace

Gpc plugin development

Skill yasserstudio/gpc-skills/gpc-plugin-development

Agent skills for the GPC CLI. 19 skills that teach Claude Code how to use GPC for Google Play workflows: releases, metadata, vitals, monetization, CI/CD.

Install
npx -y skills add yasserstudio/gpc-skills --skill gpc-plugin-development

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when building, extending, or debugging GPC plugins. Make sure to use this skill whenever the user mentions gpc plugins, plugin SDK, @gpc-cli/plugin-sdk, plugin hooks, plugin development, plugin scaffolding, gpc plugins init, beforeCommand, afterCommand, onError, beforeRequest, afterResponse, registerCommands, plugin permissions, plugin manifest, custom commands, plugin-ci, extend GPC, GPC addon — even if they don't explicitly say 'plugin.' Also trigger when someone wants to add custom behavior to GPC, integrate GPC with Slack or other services, build CI/CD extensions, hook into the command lifecycle, or register new CLI commands. For using the built-in CI plugin, see gpc-ci-integration.

SKILL.md

8.3 KB, as published. Nobody here has run it

gpc-plugin-development

Build and publish GPC plugins using the @gpc-cli/plugin-sdk.

When to use

  • Building a new GPC plugin
  • Adding custom hooks (notifications, logging, metrics)
  • Registering custom CLI commands
  • Understanding the plugin lifecycle and permission system
  • Debugging plugin loading or hook execution
  • Publishing a plugin to npm

Inputs required

  • Node.js 20+ and TypeScript 5+
  • @gpc-cli/plugin-sdk package (peer dependency)
  • Plugin name@gpc-cli/plugin-* (first-party) or gpc-plugin-* (third-party)

Procedure

0. Scaffold a new plugin

# Generate plugin boilerplate
gpc plugins init my-notifier --description "Send Slack notifications on release"

# This creates:
# gpc-plugin-my-notifier/
# ├── package.json
# ├── tsconfig.json
# ├── src/index.ts
# └── tests/plugin.test.ts

Or manually:

mkdir gpc-plugin-my-notifier && cd gpc-plugin-my-notifier
npm init -y
npm install --save-peer @gpc-cli/plugin-sdk
npm install --save-dev typescript vitest

1. Implement the plugin interface

Every plugin exports a GpcPlugin object:

import type { GpcPlugin, PluginHooks } from "@gpc-cli/plugin-sdk";

export const plugin: GpcPlugin = {
  name: "gpc-plugin-my-notifier",
  version: "1.0.0",
  register(hooks: PluginHooks) {
    // Register your hooks here
    hooks.afterCommand(async (event, result) => {
      if (event.command === "releases upload" && result.success) {
        console.log(`✓ Upload complete in ${result.durationMs}ms`);
      }
    });
  },
};

export default plugin;

Read: references/hooks-reference.md for all 6 hook types with full type signatures.

2. Available lifecycle hooks

Register hooks inside the register() method:

register(hooks: PluginHooks) {
  // Before any command runs
  hooks.beforeCommand(async (event) => {
    console.log(`Running: gpc ${event.command}`);
  });

  // After successful command
  hooks.afterCommand(async (event, result) => {
    console.log(`Done: ${result.durationMs}ms, exit ${result.exitCode}`);
  });

  // On command failure
  hooks.onError(async (event, error) => {
    console.error(`Failed: ${error.code} — ${error.message}`);
  });

  // Before each API request
  hooks.beforeRequest(async (event) => {
    console.log(`API: ${event.method} ${event.path}`);
  });

  // After each API response
  hooks.afterResponse(async (event, response) => {
    console.log(`API: ${response.status} in ${response.durationMs}ms`);
  });

  // Register custom CLI commands
  hooks.registerCommands((registry) => {
    registry.add({
      name: "notify",
      description: "Send a test notification",
      action: async () => {
        console.log("Notification sent!");
      },
    });
  });
}

3. Declare permissions (third-party plugins)

Third-party plugins (gpc-plugin-*) must declare permissions:

{
  "gpc": {
    "permissions": [
      "hooks:afterCommand",
      "hooks:onError",
      "api:read"
    ]
  }
}

Read: references/permissions-system.md for the full permission list and trust model.

Available permissions:

PermissionAllows
read:configRead .gpcrc.json
write:configModify config
read:authAccess credentials
api:readMake read API calls
api:writeMake write API calls
commands:registerRegister new commands
hooks:beforeCommandHook before commands
hooks:afterCommandHook after commands
hooks:onErrorHook on errors
hooks:beforeRequestHook before API requests
hooks:afterResponseHook after API responses

First-party plugins (@gpc-cli/*) are auto-trusted — no permissions needed.

Trust check order (v0.9.74+): discoverPlugins() calls isPluginTrusted() before calling import() on any plugin specifier. Untrusted plugins are silently skipped without their module code ever running. Previously, GPC imported first and checked approval afterward, which allowed top-level module side-effects to execute before the trust decision was made.

Permission enforcement (v0.9.80+): Permissions are now enforced at hook registration time, not just validated. A third-party plugin without hooks:beforeRequest permission that calls hooks.beforeRequest() will see a warning instead of the hook being silently registered. If register() throws, the error is caught and the plugin is skipped with a warning -- it cannot crash the CLI. Project .gpcrc.json can no longer set approvedPlugins -- only user config (~/.config/gpc/config.json) is trusted for plugin approval.

4. Test your plugin

// tests/plugin.test.ts
import { describe, it, expect, vi } from "vitest";
import { plugin } from "../src/index.js";

describe("my-notifier plugin", () => {
  it("has required fields", () => {
    expect(plugin.name).toBe("gpc-plugin-my-notifier");
    expect(plugin.version).toBeDefined();
    expect(typeof plugin.register).toBe("function");
  });

  it("registers afterCommand hook", () => {
    const hooks = {
      beforeCommand: vi.fn(),
      afterCommand: vi.fn(),
      onError: vi.fn(),
      beforeRequest: vi.fn(),
      afterResponse: vi.fn(),
      registerCommands: vi.fn(),
    };
    plugin.register(hooks);
    expect(hooks.afterCommand).toHaveBeenCalled();
  });
});
npx vitest run

5. Install and configure

# Install locally
npm install ./gpc-plugin-my-notifier

# Or from npm
npm install -g @gpc-cli/cli-plugin-my-notifier

Add to .gpcrc.json:

{
  "plugins": ["gpc-plugin-my-notifier"],
  "approvedPlugins": ["gpc-plugin-my-notifier"]
}

Third-party plugins must be listed in approvedPlugins to load.

6. Publish to npm

# Build
npx tsc

# Test
npx vitest run

# Publish
npm publish

Naming convention:

  • First-party: @gpc-cli/plugin-<name> (reserved for official plugins)
  • Third-party: gpc-plugin-<name>

Verification

  • gpc plugins list shows your plugin as loaded
  • Hooks fire at the expected lifecycle points
  • npx vitest run passes all tests
  • Third-party permission errors show clear messages
  • Plugin loads without blocking GPC startup

Failure modes / debugging

SymptomLikely CauseFix
Plugin not loadingNot in plugins config arrayAdd to .gpcrc.json plugins list
PLUGIN_INVALID_PERMISSIONUnknown permission declaredCheck valid permissions in references/permissions-system.md
Third-party plugin silently missingNot in approvedPluginsAdd plugin name to approvedPlugins in config — unapproved plugins are skipped without error
Hook not firingWrong hook name or not registeredVerify hook registration in register() method
Hook error crashes GPCError in beforeCommand handleronError and API hooks swallow errors; beforeCommand does not
Plugin not foundWrong package name or not installedCheck node_modules for gpc-plugin-* or @gpc-cli/plugin-*
Standalone binary ignores pluginsPlugins disabled in binary modeUse npm-installed GPC for plugin support
gpc doctor warns on pluginPlugin fails to loadRun gpc doctor to see which plugin failed, then reinstall it (v0.9.71+)

Related skills

  • gpc-ci-integration — uses @gpc-cli/plugin-ci as an example of a first-party plugin
  • gpc-setup — configuration file where plugins are registered
  • gpc-troubleshooting — debugging plugin loading issues

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.