This document describes how Forge plugins are defined, rendered, installed, and consumed by AI assistants.
- Define once, render to many. A plugin is defined as a single
ForgePlugin. Claude, Copilot, Gemini, and Codex each render that definition into their own native format. - Strictly read-only. Installed assets must never create, update, close, comment on, or mutate any GitHub resource.
- Direct
ghexecution. The installed assets tell the host assistant to use read-onlyghcommands directly. Forge no longer ships an assistant-side Node runtime. - Live-fetch-only. Every answer must come from a fresh GitHub fetch at execution time.
- Managed content with preserved customizations. Installed files use Forge-managed markers so reinstalls replace only the managed block while leaving user customizations intact.
- Legacy runtime cleanup. Reinstalls remove old
forge/bin,forge/dist,forge/node_modules,forge/VERSION,forge/package.json, andforge-file-manifest.jsonartifacts from earlier releases.
ForgePlugin (assistant-agnostic definition)
│
├── AssistantAdapter.render(entry) ──► Native format per assistant
│ ├── Claude: Markdown command + agent + workflow
│ ├── Copilot: Markdown agent + skill
│ ├── Gemini: TOML command + agent + workflow
│ └── Codex: Markdown skill + agent (md+toml) + workflow
│
└── AssistantInstallService
├── create needed directories
├── remove legacy bundled runtime artifacts
├── write primary + supplemental assets
└── preserve user customizations on reinstall
At execution time, the host assistant runs read-only GitHub CLI commands directly in the current repository:
- Discussions:
gh api graphql - Issues:
gh issue listandgh issue view --json - PR reviews:
gh pr view/gh pr list --json, plus read-onlygh api repos/{owner}/{repo}/pulls/<pr>/commentswhen inline review comments are needed
File: src/contracts/forge-plugin.ts
interface ForgePlugin {
id: string;
displayName: string;
purpose: string;
instructions: string;
capabilities: ForgePluginCapability[];
commands: ForgePluginCommand[];
principles: string[];
metadata?: Record<string, any>;
}idmust be prefixed withforge-.- The first segment becomes the Claude/Gemini namespace.
- Example:
forge-discussion-analyzerbecomesforge:discussion-analyzer.
Every plugin must include:
- Tool approval guidance for
Bash,Read,python3,node, andghCLI. - A strict read-only rule.
- A direct
ghdata path for its domain. - Guardrails against installing
ghextensions or mutating~/.config/gh. - Scope redirection when the user asks about a different domain.
metadata.analyzerDomain drives prompt wording in src/services/assistants/runtime-rendering.ts.
Current values are 'discussions', 'issues', 'pr-reviews', 'commit-craft', 'pr-architecture', and 'review-quality'.
The first three are data-surfacing analyzers (using gh CLI). The last three are coaching-oriented plugins that interpret patterns and guide developers:
commit-craft: Usesgit log/git diff --statto coach on commit quality and conventions.pr-architecture: Usesgh pr list --json/gh pr view --jsonto coach on PR structure and reviewability.review-quality: Usesgh apipulls endpoints to coach on code review depth and actionability.
| Assistant | Root | Primary Asset | Supplemental Assets |
|---|---|---|---|
| Claude | ~/.claude |
commands/{namespace}/{local}.md |
agents/{id}.md, forge/workflows/{local}.md |
| Copilot | ~/.copilot |
agents/{id}.agent.md |
skills/{id}/SKILL.md |
| Gemini | ~/.gemini |
commands/{namespace}/{local}.toml |
agents/{id}.md, forge/workflows/{local}.md |
| Codex | ~/.codex |
skills/{id}/SKILL.md |
agents/{id}.md, agents/{id}.toml, forge/workflows/{local}.md |
Only workflow reference files remain under ~/.{assistant}/forge/. The old executable runtime is intentionally gone.
File: src/services/assistants/runtime-rendering.ts
Key renderers:
renderClaudeCommandrenderClaudeAgentrenderClaudeWorkflowrenderGeminiCommandrenderGeminiAgentrenderGeminiWorkflowrenderCodexSkillrenderCodexAgentrenderCodexAgentToml
The shared renderer logic does two things:
- Builds domain-aware prompt copy.
- Injects the correct read-only
ghguidance for discussions, issues, or PR reviews.
File: src/services/assistants/install.ts
installAssistantsCommand(cwd)
→ resolve assistant selection
→ for each requested assistant:
→ resolve install layout
→ create missing asset directories
→ remove legacy bundled runtime artifacts
→ render primary + supplemental assets
→ merge Forge-managed content with preserved user customizations
→ remove obsolete legacy files
When writing an asset:
- New file: write rendered content.
- Existing managed file: replace only the managed block.
- Legacy file: migrate the content into the managed/user marker structure.
File: src/program.ts
The public forge command manages install and uninstall flows:
--assistants <targets>--verbose--cwd <path>--uninstall
There is no analyzer execution subcommand anymore.
When changing the install architecture:
npm run build
npm test
node dist/cli.js --assistants codex
node dist/cli.js --uninstall --assistants codexCheck that:
- assets mention direct
ghusage - no asset references
forge.mjsor--run - legacy bundled runtime files are removed on reinstall
- uninstall removes Forge-managed assets without touching unrelated assistant files
- user customization blocks stay intact