gpc-plugin-development
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) orgpc-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:
| Permission | Allows |
|---|---|
read:config |
Read .gpcrc.json |
write:config |
Modify config |
read:auth |
Access credentials |
api:read |
Make read API calls |
api:write |
Make write API calls |
commands:register |
Register new commands |
hooks:beforeCommand |
Hook before commands |
hooks:afterCommand |
Hook after commands |
hooks:onError |
Hook on errors |
hooks:beforeRequest |
Hook before API requests |
hooks:afterResponse |
Hook after API responses |
First-party plugins (@gpc-cli/*) are auto-trusted — no permissions needed.
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 listshows your plugin as loaded- Hooks fire at the expected lifecycle points
npx vitest runpasses all tests- Third-party permission errors show clear messages
- Plugin loads without blocking GPC startup
Failure modes / debugging
| Symptom | Likely Cause | Fix |
|---|---|---|
| Plugin not loading | Not in plugins config array |
Add to .gpcrc.json plugins list |
PLUGIN_INVALID_PERMISSION |
Unknown permission declared | Check valid permissions in references/permissions-system.md |
| Third-party plugin blocked | Not in approvedPlugins |
Add plugin name to approvedPlugins in config |
| Hook not firing | Wrong hook name or not registered | Verify hook registration in register() method |
| Hook error crashes GPC | Error in beforeCommand handler |
onError and API hooks swallow errors; beforeCommand does not |
| Plugin not found | Wrong package name or not installed | Check node_modules for gpc-plugin-* or @gpc-cli/plugin-* |
| Standalone binary ignores plugins | Plugins disabled in binary mode | Use npm-installed GPC for plugin support |
gpc doctor warns on plugin |
Plugin fails to load | Run 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
More from yasserstudio/gpc-skills
gpc-sdk-usage
Use when building applications that programmatically interact with the Google Play Developer API using GPC's TypeScript SDK packages. Make sure to use this skill whenever the user mentions @gpc-cli/api, @gpc-cli/auth, PlayApiClient, createApiClient, resolveAuth, Google Play API client, TypeScript SDK, programmatic access, API client, HTTP client, rate limiter, pagination, edit lifecycle in code, Node.js Google Play, server-side Play Store, backend integration — even if they don't explicitly say 'SDK.' Also trigger when someone wants to build a backend service, custom dashboard, automation script, or any TypeScript/JavaScript application that interacts with Google Play programmatically rather than through the CLI. For CLI usage, see other gpc-* skills. For building plugins, see gpc-plugin-development.
12gpc-release-flow
Use when uploading, releasing, promoting, or managing rollouts on Google Play. Make sure to use this skill whenever the user mentions gpc releases, upload AAB, upload APK, staged rollout, promote to production, halt rollout, gpc publish, release notes, track management, internal testing, beta release, production rollout, version code, rollout percentage, gpc bundles, bundle list, bundle wait, wait for bundle processing, in-app update priority, retain version codes, versioned changelogs, or wants to ship an Android app to any Play Store track. Also trigger when someone asks about the Google Play edit lifecycle, release validation, or how to do a phased rollout — even if they don't mention GPC by name. For metadata and listings, see gpc-metadata-sync. For CI/CD integration, see gpc-ci-integration.
12gpc-security
Use when dealing with GPC credential security, secret management, audit logging, or access control. Make sure to use this skill whenever the user mentions credentials, service account key, secret rotation, key rotation, credential storage, audit log, audit trail, security best practices, .gpcrc.json security, secrets in CI, GPC_SERVICE_ACCOUNT safety, keychain, token cache, credential leak, key compromise, secure deployment — even if they don't explicitly say 'security.' Also trigger when someone asks about where GPC stores credentials, how to rotate service account keys, how to audit who did what with GPC, how to securely pass credentials in CI/CD, or how to handle a compromised service account key. For auth setup, see gpc-setup. For CI configuration, see gpc-ci-integration.
12gpc-multi-app
Use when managing multiple Google Play apps with GPC. Make sure to use this skill whenever the user mentions multiple apps, multi-app, monorepo, white-label, batch operations, bulk upload, several apps, --app flag, app switching, profiles for different apps, fleet management, app portfolio, multiple package names — even if they don't explicitly say 'multi-app.' Also trigger when someone has more than one Android app and wants to manage them efficiently, when they need different configurations per app, when they're running the same command across multiple apps, or when they have a monorepo with multiple Android modules. For single-app setup, see gpc-setup. For CI automation, see gpc-ci-integration.
11gpc-setup
Use when setting up GPC (Google Play Console CLI): authentication with service accounts, OAuth, or Application Default Credentials; configuration files (.gpcrc.json, env vars, XDG paths); auth profiles; running gpc doctor; troubleshooting auth errors. Make sure to use this skill whenever the user mentions gpc auth, service account setup, gpc config, gpc doctor, GPC_SERVICE_ACCOUNT, gpc auth login, Google Play API credentials, Play Console authentication, gpc setup, gpc setup wizard, one-command onboarding, or wants to install/configure GPC — even if they don't explicitly say 'setup.' Also trigger when someone is troubleshooting auth failures, token expiration, keychain issues, or proxy/network configuration for GPC.
11gpc-monetization
Use when managing in-app purchases, subscriptions, pricing, or Real-Time Developer Notifications in Google Play. Make sure to use this skill whenever the user mentions gpc subscriptions, gpc iap, gpc purchases, gpc pricing, gpc rtdn, in-app products, base plans, subscription offers, one-time products, consumable products, purchase verification, purchase acknowledgement, purchase token, subscription cancellation, subscription deferral, voided purchases, refunds, regional pricing, currency conversion, price migration, SKU management, monetization, revenue, billing, subscription analytics, churn, trial conversion, subscriber count, RTDN, Real-Time Developer Notifications, Pub/Sub notifications, subscription events, purchase events — even if they don't explicitly say 'monetization.' Also trigger when someone wants to create or update subscriptions, manage base plan lifecycle (activate/deactivate), set up introductory offers, verify server-side purchases, handle refunds, convert prices across regions, sync IAP products from files, migrate subscribers to new prices, view subscription analytics, decode Pub/Sub notification payloads, or check RTDN topic configuration. For release management, see gpc-release-flow. For CI automation, see gpc-ci-integration.
11