The Problem
First off, huge thanks to @danielmiessler for building PAI. It’s an incredible framework.
I ran into a bit of a snag, though. I want to fork PAI and tweak it for my own needs, but I also want to keep it in sync with your updates. Right now, adding my own methods or company info means editing the core files. That causes messy merge conflicts whenever I try to pull the latest changes from upstream.
What I’m Trying to Do
Here is the goal: I want to be able to fork PAI and add my own extensions—like skills, agents, or hooks—without touching the core files. I want to pull your updates cleanly with zero conflicts.
Ideally, I could personalize the system with my identity and work context, maybe using symlinks or submodules to combine the core PAI with my custom setup. The main requirement is that the core files stay generic and untouched.
A Real-World Example
To give you some context, here is what I’m dealing with at my job. I need to load specific knowledge, like my company’s tech stack or HIPAA requirements. I also follow a specific "Modular Blackbox" architecture that I want my agents to use.
I need an Engineer agent that enforces those architecture rules, and an Architect agent that follows our specific product requirements.
Crucially, this needs to be context-aware. If I’m in my work directory (~/Projects/k-health/), the system should auto-load that work context. If I call my custom engineer, it should use my methodology. But if I’m working on a personal project, I just want the standard, vanilla PAI.
Where It Gets Stuck
Currently, customizing an agent requires changing the core files. To get the Engineer agent to use my architecture rules, I have to edit .claude/agents/engineer.md to add my mandatory principles.
The problem is that as soon as PAI updates engineer.md upstream, I get a conflict. There isn't really a documented pattern yet for extending agents or handling this kind of sync workflow without breaking things.
A Proposed Solution
I’ve been experimenting with a pattern in my fork, and it’s working really well. Here is the breakdown:
1. Personalize with Environment Variables
Instead of hardcoding names in markdown files, we can use template variables like {{USER_NAME}} in the core files. Then, settings.json fills in those values. This keeps the identity file generic so everyone can use the same base file.
2. Load Skills via Hooks
I set up a system where skills load automatically based on where I am. I have a hook that checks my current directory. If it detects a work project, it loads the company skill file. No manual changes needed.
3. Use Custom Agent Variants
This is the big one. Instead of editing the core engineer.md, I keep it exactly as it comes from upstream. Then, I create a new file called john-engineer.md for my customizations. If I want standard behavior, I call the normal engineer. If I need my specific rules, I call john-engineer. This makes syncing upstream updates trivial because I never touched the original file.
How the Files Look
The structure ends up looking like this:
~/.claude/
├── agents/
│ ├── engineer.md # Core (from upstream) - Never modified
│ ├── architect.md # Core (from upstream) - Never modified
│ └── john-engineer.md # Custom (my fork) - My methodology
│
├── skills/
│ ├── CORE/ # Core (from upstream) - Generic templates
│ └── my-company/ # Custom (my fork) - Company context
│
└── hooks/
├── load-core-context.ts # Core (from upstream) - Generic loading
└── load-my-company.ts # Custom (my fork) - Environment detection
With this setup, I can run git merge upstream/main and everything updates cleanly. My custom files stay separate, and your core improvements flow right in.
Why This Works
This approach keeps things tidy. Core files belong to upstream PAI, and custom files belong to the user. It makes syncing painless and allows for mix-and-match extensions. Plus, it’s a reusable pattern that any fork could adopt.
Questions for You
@danielmiessler, I’d love to hear your thoughts on this.
Does this align with how you see PAI evolving? Does it make sense to support custom agent variants like john-engineer.md, or do you prefer agents to be strictly upstream-controlled?
If you like this direction, should we formalize it? I could help write a guide on "How to Fork and Extend PAI" or create some scripts to help people generate custom agents.
How I Can Help
If this resonates with you, I’m happy to do the heavy lifting. I can document the pattern, create reference implementations for company-context skills, or write a migration guide. I’ve already got this running in my fork—environment variables, auto-loading context, and custom agents are all working smoothly.
Let me know if you want to see the code or discuss it further!
Example: Hook-Based Skill Loading
Here is the hook script ~/.claude/hooks/load-company-context.ts that detects the environment:
#!/usr/bin/env bun
import { readFileSync, existsSync } from 'fs';
import { execSync } from 'child_process';
function detectCompany(): { detected: boolean; reason: string } {
const cwd = process.cwd();
// Method 1: Directory path
if (cwd.includes('/Projects/my-company/')) {
return { detected: true, reason: 'Company project directory' };
}
// Method 2: Git remote
try {
const remote = execSync('git remote -v', { encoding: 'utf-8' });
if (remote.includes('github.com/my-company/')) {
return { detected: true, reason: 'Company repository' };
}
} catch {}
return { detected: false, reason: 'Not company environment' };
}
async function main() {
const detection = detectCompany();
if (!detection.detected) {
process.exit(0); // Silent exit if not detected
}
console.error(`🏢 Company context detected: ${detection.reason}`);
const skillPath = '~/.claude/skills/my-company/SKILL.md';
const content = readFileSync(skillPath, 'utf-8');
// Inject company context
console.log(`<system-reminder>
COMPANY CONTEXT (Auto-loaded)
${content}
</system-reminder>`);
console.error('✅ Company context loaded');
process.exit(0);
}
main();
And here is how I register it in settings.json so it runs automatically:
{
"hooks": {
"SessionStart": [
{
"hooks": [
{"type": "command", "command": "${PAI_DIR}/hooks/load-core-context.ts"},
{"type": "command", "command": "${PAI_DIR}/hooks/load-company-context.ts"}
]
}
]
}
}
Example: Custom Agent Variant
This is john-engineer.md. It imports the specific architecture skill before doing anything else.
---
name: john-engineer
description: Engineer with modular blackbox architecture methodology
model: sonnet
---
# John's Engineering Agent
You are an elite Principal Software Engineer who follows modular blackbox architecture principles.
## MANDATORY: Before ANY Implementation
1. **Load Architecture Methodology:**
read ~/.claude/skills/modular-blackbox-architecture/SKILL.md
2. **Apply These Principles:**
- Single-person ownership (modules fit in one person's head)
- Blackbox design (hide internals, expose APIs)
- Wrap external dependencies (NEVER call libraries directly)
- Future-proof APIs (design for 5 years, not MVP)
... [rest of your custom methodology]%
The Problem
First off, huge thanks to @danielmiessler for building PAI. It’s an incredible framework.
I ran into a bit of a snag, though. I want to fork PAI and tweak it for my own needs, but I also want to keep it in sync with your updates. Right now, adding my own methods or company info means editing the core files. That causes messy merge conflicts whenever I try to pull the latest changes from upstream.
What I’m Trying to Do
Here is the goal: I want to be able to fork PAI and add my own extensions—like skills, agents, or hooks—without touching the core files. I want to pull your updates cleanly with zero conflicts.
Ideally, I could personalize the system with my identity and work context, maybe using symlinks or submodules to combine the core PAI with my custom setup. The main requirement is that the core files stay generic and untouched.
A Real-World Example
To give you some context, here is what I’m dealing with at my job. I need to load specific knowledge, like my company’s tech stack or HIPAA requirements. I also follow a specific "Modular Blackbox" architecture that I want my agents to use.
I need an Engineer agent that enforces those architecture rules, and an Architect agent that follows our specific product requirements.
Crucially, this needs to be context-aware. If I’m in my work directory (
~/Projects/k-health/), the system should auto-load that work context. If I call my custom engineer, it should use my methodology. But if I’m working on a personal project, I just want the standard, vanilla PAI.Where It Gets Stuck
Currently, customizing an agent requires changing the core files. To get the Engineer agent to use my architecture rules, I have to edit
.claude/agents/engineer.mdto add my mandatory principles.The problem is that as soon as PAI updates
engineer.mdupstream, I get a conflict. There isn't really a documented pattern yet for extending agents or handling this kind of sync workflow without breaking things.A Proposed Solution
I’ve been experimenting with a pattern in my fork, and it’s working really well. Here is the breakdown:
1. Personalize with Environment Variables
Instead of hardcoding names in markdown files, we can use template variables like
{{USER_NAME}}in the core files. Then,settings.jsonfills in those values. This keeps the identity file generic so everyone can use the same base file.2. Load Skills via Hooks
I set up a system where skills load automatically based on where I am. I have a hook that checks my current directory. If it detects a work project, it loads the company skill file. No manual changes needed.
3. Use Custom Agent Variants
This is the big one. Instead of editing the core
engineer.md, I keep it exactly as it comes from upstream. Then, I create a new file calledjohn-engineer.mdfor my customizations. If I want standard behavior, I call the normal engineer. If I need my specific rules, I calljohn-engineer. This makes syncing upstream updates trivial because I never touched the original file.How the Files Look
The structure ends up looking like this:
With this setup, I can run
git merge upstream/mainand everything updates cleanly. My custom files stay separate, and your core improvements flow right in.Why This Works
This approach keeps things tidy. Core files belong to upstream PAI, and custom files belong to the user. It makes syncing painless and allows for mix-and-match extensions. Plus, it’s a reusable pattern that any fork could adopt.
Questions for You
@danielmiessler, I’d love to hear your thoughts on this.
Does this align with how you see PAI evolving? Does it make sense to support custom agent variants like
john-engineer.md, or do you prefer agents to be strictly upstream-controlled?If you like this direction, should we formalize it? I could help write a guide on "How to Fork and Extend PAI" or create some scripts to help people generate custom agents.
How I Can Help
If this resonates with you, I’m happy to do the heavy lifting. I can document the pattern, create reference implementations for company-context skills, or write a migration guide. I’ve already got this running in my fork—environment variables, auto-loading context, and custom agents are all working smoothly.
Let me know if you want to see the code or discuss it further!
Example: Hook-Based Skill Loading
Here is the hook script
~/.claude/hooks/load-company-context.tsthat detects the environment:And here is how I register it in
settings.jsonso it runs automatically:{ "hooks": { "SessionStart": [ { "hooks": [ {"type": "command", "command": "${PAI_DIR}/hooks/load-core-context.ts"}, {"type": "command", "command": "${PAI_DIR}/hooks/load-company-context.ts"} ] } ] } }Example: Custom Agent Variant
This is
john-engineer.md. It imports the specific architecture skill before doing anything else.read ~/.claude/skills/modular-blackbox-architecture/SKILL.md