Compare commits
2 Commits
448d1cdcd9
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 0b308ed8be | |||
|
|
f2f90abf13 |
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
|
||||
## What This Is
|
||||
|
||||
A platform-agnostic system prompt library for LLM agents. 29 personas across 10 domains, 111 variants, 59,712 words. Includes 795 shared skills, 58 brand design systems, 23 company agents, and auto-install to 7 platforms (Claude, Antigravity, Gemini, OpenClaw, OpenCode, Paperclip, raw).
|
||||
A platform-agnostic system prompt library for LLM agents. 29 personas across 10 domains, 111 variants, 59,712 words. Includes 796 shared skills, 58 brand design systems, 23 company agents, 168 AD/red team attack docs (InternalAllTheThings), and auto-install to 7 platforms (Claude, Antigravity, Gemini, OpenClaw, OpenCode, Paperclip, raw).
|
||||
|
||||
## Build
|
||||
|
||||
@@ -36,7 +36,7 @@ Optional: `cp config.example.yaml config.yaml` for dynamic variable injection. B
|
||||
**Shared library** (`personas/_shared/`): Reusable knowledge bases (skipped during persona build, indexed into outputs):
|
||||
- `skills/` — 42 shared skills from OpenClaw/kali-claw (SKILL.md + references per skill)
|
||||
- `paperclip-skills/` — 52 skills from paperclip-docs (ceo-advisor, coding-agent, security-review, etc.)
|
||||
- `community-skills/` — 701 skills from skills.sh marketplace (shadcn, vercel, marketing, expo, obsidian, impeccable, browser-use, stitch, firecrawl, github, neon, azure, etc.)
|
||||
- `community-skills/` — 703 skills from skills.sh marketplace (shadcn, vercel, olla, expo, etc.) (shadcn, vercel, marketing, expo, obsidian, impeccable, browser-use, stitch, firecrawl, github, neon, azure, etc.)
|
||||
- `design-md/` — 58 brand DESIGN.md files (Stripe, Claude, Linear, Apple, Vercel, etc.)
|
||||
- `ui-ux-pro-max/` — BM25 search engine + 14 CSV data files (67 styles, 161 products, 57 fonts)
|
||||
- `paperclip-agents/` — 23 company agents (Odin/CEO, Thor/CTO, Freya/CMO, Frigg/COO + 19 team members)
|
||||
@@ -44,6 +44,7 @@ Optional: `cp config.example.yaml config.yaml` for dynamic variable injection. B
|
||||
- `openclaw-personas/` — Original 6 OpenClaw persona definitions + SOUL.md + IDENTITY.md + TOOLS.md
|
||||
- `osint-sources/` — OSINT master reference and investigation templates
|
||||
- `ad-attack-tools/` — Active Directory attack chain references
|
||||
- `internal-allthethings/` — 168 InternalAllTheThings docs (swisskyrepo): AD attacks (ADCS ESC1-15, Kerberos, NTLM relay, coerce, delegation), red team (access, escalation, evasion, persistence, pivoting), cloud (AWS/Azure/IBM), C2 (Cobalt Strike, Metasploit, Mythic), containers, databases, DevOps CI/CD
|
||||
|
||||
**Build outputs** (`generated/_index/`):
|
||||
- `escalation_graph.json` — cross-persona handoff map extracted from Boundaries sections
|
||||
|
||||
37
README.md
37
README.md
@@ -2,7 +2,7 @@
|
||||
|
||||
> Platform-agnostic system prompt library for LLM agents.
|
||||
> 29 personas. 10 domains. 111 variants. 60,000+ words of production-grade prompts.
|
||||
> 795 skills. 58 brand design systems. 16 Kali tool references. Multi-platform auto-install.
|
||||
> 796 skills. 58 brand design systems. 16 Kali tool references. 168 AD/red team attack docs. Multi-platform auto-install.
|
||||
|
||||
```
|
||||
┌─ Neo ─── Phantom ─── Cipher ─── Specter ─── Bastion ─── Vortex ─── Sentinel
|
||||
@@ -47,8 +47,8 @@
|
||||
│ └─ Heimd (Product Manager)
|
||||
│
|
||||
└──── SHARED LIBRARY ────────────────────────────────────
|
||||
795 skills │ 58 brand designs │ 16 kali-tools
|
||||
Auto-install: Claude · Antigravity · Gemini · OpenClaw · Paperclip
|
||||
796 skills │ 58 brand designs │ 16 kali-tools │ 168 AD/redteam docs
|
||||
Auto-install: Claude · Antigravity · Gemini · OpenClaw · OpenCode · Paperclip
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
@@ -190,7 +190,8 @@ personas/
|
||||
├── _shared/ # Shared knowledge bases (skipped in persona build)
|
||||
│ ├── skills/ (42) # OpenClaw + kali-claw shared skills
|
||||
│ ├── paperclip-skills/(52) # Paperclip company skills (CEO, coding, devops...)
|
||||
│ ├── community-skills/(701)# skills.sh marketplace (shadcn, vercel, marketing...)
|
||||
│ ├── community-skills/(703)# skills.sh marketplace (shadcn, vercel, olla, marketing...)
|
||||
│ ├── internal-allthethings/ # InternalAllTheThings — 168 AD/red team attack docs (swisskyrepo)
|
||||
│ ├── design-md/ (58) # Brand DESIGN.md files (Stripe, Claude, Linear...)
|
||||
│ ├── ui-ux-pro-max/ # BM25 search engine + 14 CSV data files
|
||||
│ ├── paperclip-agents/(23) # Company agents (Odin/CEO, Thor/CTO, Freya/CMO...)
|
||||
@@ -276,10 +277,12 @@ Escalation paths to other personas
|
||||
|
||||
```bash
|
||||
python3 build.py # build all → generated/
|
||||
python3 build.py --install claude # deploy as Claude Code slash commands
|
||||
python3 build.py --install claude # deploy as Claude Code slash commands + agents
|
||||
python3 build.py --install claude-skills # deploy shared skills to ~/.claude/skills/
|
||||
python3 build.py --install antigravity # deploy to Antigravity IDE
|
||||
python3 build.py --install gemini # deploy as Gemini Gems
|
||||
python3 build.py --install openclaw # deploy to OpenClaw format
|
||||
python3 build.py --install opencode # deploy 29 agents + 1011 skills to OpenCode
|
||||
python3 build.py --install paperclip # deploy to Paperclip (52 agents + 73 skills)
|
||||
python3 build.py --install all # deploy to all platforms
|
||||
```
|
||||
@@ -303,6 +306,8 @@ Reads `config.yaml` (if present) and generates three formats per variant:
|
||||
| Gemini Gems | `generated/_gems/` | Google AI Studio format |
|
||||
| OpenClaw | `generated/_openclaw/` | IDENTITY.md + individual personas |
|
||||
| Paperclip | `generated/_paperclip/` | 52 agents + 73 skills (Hermes format) |
|
||||
| OpenCode agents | `~/.config/opencode/agents/` | 29 native subagents (md + YAML frontmatter) |
|
||||
| OpenCode skills | `~/.config/opencode/skills/` | 1011 skills (topic-filtered, no marketing/biz) |
|
||||
|
||||
### Config-Driven Customization
|
||||
|
||||
@@ -329,6 +334,20 @@ Persona files can reference config values:
|
||||
|
||||
Without `config.yaml`, personas build with their static content — no config required.
|
||||
|
||||
### OpenCode Integration
|
||||
|
||||
OpenCode (`opencode-ai`) gets 29 agents and 1011 topic-filtered skills:
|
||||
|
||||
```bash
|
||||
python3 build.py --install opencode # default: security + dev + AI + ops
|
||||
python3 build.py --install opencode --opencode-topics all # everything (1530)
|
||||
python3 build.py --install opencode --opencode-topics security-offensive,security-defensive,ai-llm-dev
|
||||
```
|
||||
|
||||
**Topics**: security-offensive, security-defensive, security-cloud, security-specialized, security-iam, security-network, security-general, ai-llm-dev, coding-backend, coding-frontend, coding-tools, cloud-infra, database, browser-scrape, ops-sysadmin, osint-intel, marketing-content, business-pm, uncategorized.
|
||||
|
||||
Default drops marketing/business-pm/uncategorized (~514 skills). Agents use OpenCode's markdown+YAML format with `mode: primary|subagent` and `permission:` blocks. OpenCode also reads `~/.claude/skills/` natively.
|
||||
|
||||
## Integration
|
||||
|
||||
### Raw System Prompt
|
||||
@@ -435,7 +454,8 @@ The `_shared/` directory contains reusable knowledge bases from multiple sources
|
||||
|--------|---------|-------|
|
||||
| **OpenClaw + kali-claw** | Security/intelligence skills (pentest, OSINT, CTI) | 42 skills |
|
||||
| **Paperclip (Born2beRoot)** | Company management skills (CEO, coding, devops) | 52 skills |
|
||||
| **skills.sh marketplace** | Community skills (shadcn, vercel, marketing, expo) | 701 skills |
|
||||
| **skills.sh marketplace** | Community skills (shadcn, vercel, olla, expo) | 703 skills |
|
||||
| **InternalAllTheThings** | AD attacks, red team, ADCS, Kerberos, NTLM relay (swisskyrepo) | 168 docs |
|
||||
| **awesome-design-md** | Brand design systems (Stripe, Claude, Linear, Apple) | 58 brands |
|
||||
| **ui-ux-pro-max** | BM25 search engine for UI/UX decisions | 14 data files |
|
||||
| **Kali Linux** | Tool reference docs (nmap, hashcat, AD, wireless) | 16 docs |
|
||||
@@ -449,11 +469,12 @@ Skills are auto-mapped to personas during build. Each persona's JSON/YAML output
|
||||
| Personas | 29 |
|
||||
| Total variants | 111 |
|
||||
| Prompt content | 59,712 words |
|
||||
| Shared skills | 795 |
|
||||
| Shared skills | 796 |
|
||||
| Design brands | 58 |
|
||||
| Kali tool docs | 16 |
|
||||
| AD/Red team docs | 168 (InternalAllTheThings) |
|
||||
| Paperclip agents | 23 |
|
||||
| Target platforms | 6 (Claude, Antigravity, Gemini, OpenClaw, Paperclip, raw) |
|
||||
| Target platforms | 7 (Claude, Antigravity, Gemini, OpenClaw, OpenCode, Paperclip, raw) |
|
||||
| Output formats | 3 (.prompt.md, .yaml, .json) + platform-specific |
|
||||
|
||||
## License
|
||||
|
||||
97
build.py
97
build.py
@@ -1394,16 +1394,26 @@ def install_opencode(
|
||||
}
|
||||
|
||||
agent_count = 0
|
||||
emitted_agents: set[str] = set()
|
||||
ident_re = re.compile(r"^[a-z0-9]+(-[a-z0-9]+)*$")
|
||||
|
||||
# Emit one agent file per variant. General → <codename>.md (picker-visible).
|
||||
# Non-general → <codename>-<variant>.md with hidden:true so it's
|
||||
# task-dispatchable by name without cluttering the picker.
|
||||
for persona_dir in sorted(output_dir.iterdir()):
|
||||
if not persona_dir.is_dir() or persona_dir.name.startswith("_"):
|
||||
continue
|
||||
general_json = persona_dir / "general.json"
|
||||
if not general_json.exists():
|
||||
|
||||
for variant_json in sorted(persona_dir.glob("*.json")):
|
||||
try:
|
||||
data = json.loads(variant_json.read_text(encoding="utf-8"))
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
if not data.get("codename"):
|
||||
continue
|
||||
|
||||
data = json.loads(general_json.read_text(encoding="utf-8"))
|
||||
codename = data.get("codename", persona_dir.name)
|
||||
codename = data["codename"]
|
||||
variant = data.get("variant") or "general"
|
||||
name = data.get("name", codename.title())
|
||||
role = data.get("role", "Specialist")
|
||||
domain = data.get("domain", "")
|
||||
@@ -1412,11 +1422,24 @@ def install_opencode(
|
||||
quote = data.get("quote", "")
|
||||
skills = data.get("skills", [])
|
||||
|
||||
# opencode agent identifier: ^[a-z0-9]+(-[a-z0-9]+)*$
|
||||
agent_ident = codename if variant == "general" else f"{codename}-{variant}"
|
||||
agent_ident = agent_ident.lower()
|
||||
if not ident_re.match(agent_ident):
|
||||
sanitized = re.sub(r"[^a-z0-9]+", "-", agent_ident).strip("-")
|
||||
if not ident_re.match(sanitized):
|
||||
print(f" WARN skipping {codename}/{variant}: cannot sanitize identifier")
|
||||
continue
|
||||
agent_ident = sanitized
|
||||
|
||||
soul = data.get("sections", {}).get("soul", "")
|
||||
methodology = data.get("sections", {}).get("methodology", "")
|
||||
behavior = data.get("sections", {}).get("behavior_rules", "")
|
||||
|
||||
body = f"You are **{name}** ({address_to}) — {role}.\n\n"
|
||||
header = f"You are **{name}** ({address_to}) — {role}"
|
||||
if variant != "general":
|
||||
header += f" [{variant}]"
|
||||
body = header + ".\n\n"
|
||||
body += f"Domain: {domain} | Tone: {tone}\n\n"
|
||||
if quote:
|
||||
body += f'> "{quote}"\n\n'
|
||||
@@ -1430,10 +1453,18 @@ def install_opencode(
|
||||
body += "## Mapped Skills\n" + ", ".join(skills) + "\n"
|
||||
|
||||
is_offensive = domain in OFFENSIVE_DOMAINS
|
||||
mode = "primary" if is_offensive else "subagent"
|
||||
# Only general variants can be primary (Tab-cycled, top-level).
|
||||
# All non-general variants are subagents so hidden:true is defined
|
||||
# per opencode spec ("only applies to mode: subagent") and the Tab
|
||||
# cycle stays restricted to canonical personas.
|
||||
if variant == "general" and is_offensive:
|
||||
mode = "primary"
|
||||
else:
|
||||
mode = "subagent"
|
||||
color = DOMAIN_COLOR.get(domain, "primary")
|
||||
|
||||
# Permission block differs for offensive vs analytical personas.
|
||||
# Tier-based permissions. task:"*" gates subagent dispatch so a
|
||||
# compromised subagent can't silently escalate into another.
|
||||
if is_offensive:
|
||||
permission_block = (
|
||||
"permission:\n"
|
||||
@@ -1441,6 +1472,8 @@ def install_opencode(
|
||||
" bash:\n"
|
||||
' "*": allow\n'
|
||||
" webfetch: allow\n"
|
||||
" task:\n"
|
||||
' "*": allow\n'
|
||||
)
|
||||
else:
|
||||
permission_block = (
|
||||
@@ -1449,25 +1482,65 @@ def install_opencode(
|
||||
" bash:\n"
|
||||
' "*": ask\n'
|
||||
" webfetch: allow\n"
|
||||
" task:\n"
|
||||
' "*": ask\n'
|
||||
)
|
||||
|
||||
desc = f"{name} ({address_to}) — {role}. Domain: {domain}.".replace(
|
||||
"\n", " "
|
||||
if variant == "general":
|
||||
desc_raw = f"{name} ({address_to}) — {role}. Domain: {domain}."
|
||||
else:
|
||||
desc_raw = (
|
||||
f"{name} ({address_to}) — {role}. "
|
||||
f"Variant: {variant}. Domain: {domain}."
|
||||
)
|
||||
desc_safe = desc_raw.replace("\n", " ").replace("\r", " ")
|
||||
desc_escaped = desc_safe.replace("\\", "\\\\").replace('"', '\\"')
|
||||
|
||||
hidden_line = "hidden: true\n" if variant != "general" else ""
|
||||
|
||||
frontmatter = (
|
||||
"---\n"
|
||||
f"description: {desc}\n"
|
||||
f'description: "{desc_escaped}"\n'
|
||||
f"mode: {mode}\n"
|
||||
f"{hidden_line}"
|
||||
"temperature: 0.3\n"
|
||||
f"color: {color}\n"
|
||||
f"{permission_block}"
|
||||
"---\n\n"
|
||||
)
|
||||
agent_file = agents_dir / f"{codename}.md"
|
||||
agent_file.write_text(frontmatter + body, encoding="utf-8")
|
||||
|
||||
agent_filename = f"{agent_ident}.md"
|
||||
(agents_dir / agent_filename).write_text(
|
||||
frontmatter + body, encoding="utf-8"
|
||||
)
|
||||
emitted_agents.add(agent_filename)
|
||||
agent_count += 1
|
||||
|
||||
# Remove stale agents we emitted on a previous run but not this one. Track
|
||||
# via sidecar manifest so hand-authored files in agents/ are never touched.
|
||||
manifest_path = agents_dir / ".personas-manifest.json"
|
||||
previously_emitted: set[str] = set()
|
||||
if manifest_path.exists():
|
||||
try:
|
||||
previously_emitted = set(
|
||||
json.loads(manifest_path.read_text(encoding="utf-8")).get("agents", [])
|
||||
)
|
||||
except Exception:
|
||||
previously_emitted = set()
|
||||
stale = sorted(previously_emitted - emitted_agents)
|
||||
for name_ in stale:
|
||||
stale_path = agents_dir / name_
|
||||
if stale_path.exists():
|
||||
stale_path.unlink()
|
||||
manifest_path.write_text(
|
||||
json.dumps(
|
||||
{"agents": sorted(emitted_agents)}, indent=2, ensure_ascii=False
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
if stale:
|
||||
print(f" OpenCode: pruned {len(stale)} stale agent file(s)")
|
||||
|
||||
# Install shared skills with topic filter. OpenCode reads SKILL.md with
|
||||
# name+description frontmatter (same as Claude).
|
||||
skill_count = 0
|
||||
|
||||
Reference in New Issue
Block a user