skills/constructive-io/constructive-skills/constructive-boilerplate-authoring

constructive-boilerplate-authoring

SKILL.md

Create and customize boilerplate templates for pgpm init.

Overview

PGPM uses the genomic library to scaffold projects from templates. Templates are stored in a boilerplate repository (default: constructive-io/pgpm-boilerplates) and use placeholder substitution for customization.

Template Repository Structure

my-boilerplates/
  .boilerplates.json       # Root config (points to default directory)
  pgpm/                    # Default template variant (PGPM)
    module/
      .boilerplate.json    # Module template config
      package.json         # Template files with placeholders
      pgpm.plan
      ...
    workspace/
      .boilerplate.json    # Workspace template config
      package.json
      pgpm.json
      ...
  pnpm/                    # Alternative variant (pure PNPM, no pgpm files)
    module/
      .boilerplate.json
      ...
    workspace/
      .boilerplate.json
      ...

Root Configuration

The .boilerplates.json file at the repository root specifies the default template directory:

{
  "dir": "pgpm"
}

Template Configuration

Each template has a .boilerplate.json file defining its type, workspace requirements, and questions.

Basic Structure

{
  "type": "workspace",
  "questions": [
    {
      "name": "____repoName____",
      "message": "Enter the repository name",
      "required": true
    }
  ]
}

Template Types

Type Description
workspace Creates a new monorepo workspace
module Creates a package within a workspace
generic Standalone template (no workspace context)

Workspace Requirements

The requiresWorkspace field controls what type of workspace the template needs:

{
  "type": "module",
  "requiresWorkspace": "pgpm"
}
Value Description
"pgpm" Requires PGPM workspace (pgpm.json), creates pgpm.plan/.control files
"pnpm" Requires PNPM workspace (pnpm-workspace.yaml)
"lerna" Requires Lerna workspace (lerna.json)
"npm" Requires npm workspace (package.json with workspaces)
false No workspace required

Placeholder System

Templates use the ____placeholder____ pattern (4 underscores on each side) for variable substitution:

{
  "name": "@____username____/____moduleName____",
  "version": "0.0.1",
  "description": "____moduleDesc____",
  "author": "____fullName____ <____email____>"
}

Question Configuration

Question Fields

Field Type Description
name string Placeholder name (e.g., ____fullName____)
message string Prompt shown to user
required boolean Whether the field is required
type string Input type: text, list, checkbox
options string[] Static options for list/checkbox
default any Static default value
defaultFrom string Resolver for dynamic default
setFrom string Auto-set value (skips prompt)
optionsFrom string Resolver for dynamic options

Question Types

Text Input (default):

{
  "name": "____moduleName____",
  "message": "Enter the module name",
  "required": true
}

List Selection:

{
  "name": "____access____",
  "message": "Module access?",
  "type": "list",
  "options": ["public", "restricted"],
  "default": "public"
}

Checkbox (multi-select):

{
  "name": "____extensions____",
  "message": "Select PostgreSQL extensions",
  "type": "checkbox",
  "options": ["plpgsql", "uuid-ossp", "citext", "pgcrypto"]
}

Resolvers

Resolvers dynamically populate values from the environment or workspace context.

defaultFrom Resolvers:

Resolver Description
git.user.name Git config user.name
git.user.email Git config user.email
npm.whoami npm whoami result
workspace.dirname Current directory name

setFrom Resolvers (auto-set, skips prompt):

Resolver Description
workspace.name Workspace name from pgpm.json/package.json
workspace.author.name Workspace author name
workspace.author.email Workspace author email
workspace.license Workspace license
workspace.organization.name Workspace organization

optionsFrom Resolvers:

Resolver Description
licenses List of SPDX license identifiers

Example: Complete Module Template

{
  "type": "module",
  "requiresWorkspace": "pgpm",
  "questions": [
    {
      "name": "____fullName____",
      "message": "Enter author full name",
      "setFrom": "workspace.author.name",
      "defaultFrom": "git.user.name",
      "required": true
    },
    {
      "name": "____email____",
      "message": "Enter author email",
      "setFrom": "workspace.author.email",
      "defaultFrom": "git.user.email",
      "required": true
    },
    {
      "name": "____moduleName____",
      "message": "Enter the module name",
      "required": true
    },
    {
      "name": "____moduleDesc____",
      "message": "Enter the module description",
      "required": true
    },
    {
      "name": "____repoName____",
      "message": "Enter the repository name",
      "setFrom": "workspace.name",
      "required": true
    },
    {
      "name": "____username____",
      "message": "Enter your github username",
      "setFrom": "workspace.organization.name",
      "defaultFrom": "npm.whoami",
      "required": true
    },
    {
      "name": "____access____",
      "message": "Module access?",
      "type": "list",
      "options": ["public", "restricted"],
      "default": "public",
      "required": true
    },
    {
      "name": "____license____",
      "message": "Choose a license",
      "type": "list",
      "optionsFrom": "licenses",
      "setFrom": "workspace.license",
      "required": true
    }
  ]
}

Creating a Custom Boilerplate Repository

  1. Create a new repository with the structure above
  2. Add .boilerplates.json pointing to your default directory
  3. Create template directories with .boilerplate.json configs
  4. Add template files with ____placeholder____ patterns
  5. Use with pgpm init --repo owner/your-boilerplates

Using Custom Templates

# Use your own boilerplate repository
pgpm init workspace --repo myorg/my-boilerplates

# Use a specific branch
pgpm init workspace --repo myorg/my-boilerplates --from-branch develop

# Use a variant directory
pgpm init workspace --repo myorg/my-boilerplates --dir custom-variant

# Use the --template flag (recommended)
pgpm init --template pnpm/module --repo myorg/my-boilerplates
pgpm init -t custom-variant/module --repo myorg/my-boilerplates

# Create workspace + module in one command
pgpm init -t pnpm/module -w --repo myorg/my-boilerplates

Best Practices

  1. Use setFrom for values that should inherit from workspace context
  2. Use defaultFrom for sensible defaults that users can override
  3. Keep placeholder names descriptive and consistent
  4. Document custom templates in your repository README
  5. Test templates with --no-tty to ensure all required fields are defined
Weekly Installs
10
First Seen
Feb 27, 2026
Installed on
opencode10
gemini-cli10
claude-code10
github-copilot10
codex10
kimi-cli10