返回 Skill 列表
extension
分类: 开发与工程无需 API Key

rpg-ruleset-cli

使用受范畴论启发的分类架构,通过rpg-ruleset-cli工具管理和查询桌面RPG规则集。当用户想要创建、组织、搜索或验证RPG规则,或处理理论、解释、世界、实体和传输函子时,请使用此工具。

person作者: jakexiaohubgithub

RPG Ruleset CLI

Use this skill when users want to work with tabletop RPG rulesets, including:

  • Creating new systems with categorical architecture (theories → interpretations → worlds)
  • Adding and managing rules with validation
  • Querying rules with provenance tracking
  • Transporting entities between worlds using functors
  • Managing characters, objects, events, and locations

CRITICAL: Always Use Absolute Paths

IMPORTANT: Always use absolute paths for all file and directory arguments. Relative paths may not work correctly with bazel run.

CORRECT: /home/xsaw/haskell-monorepo-dnd-rules/rpg/crossed-swordsWRONG: rpg/crossed-swords or ./rpg/crossed-swords

This applies to:

  • init <PATH> - Use absolute path for the directory to create
  • --data-dir <DIR> - Use absolute path for the data directory
  • validate <FILE> - Use absolute path for the file to validate

Quick Command Reference

Running the CLI

# All commands use this pattern:
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- [COMMAND] [OPTIONS]

Available Commands

init - Initialize a new ruleset

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  init <PATH> --id <SYSTEM_ID> --name "System Name"

add - Add a new rule (auto-suggests ID)

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- add \
  -d <DATA_DIR> \
  --category <CATEGORY> \
  --title "Rule Title" \
  [--id RULE-ID] \
  [--visibility public|gm-only] \
  [--tag TAG1] [--tag TAG2]

query - Search for rules

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- query \
  -d <DATA_DIR> \
  [KEYWORDS...] \
  [--category CATEGORY] \
  [--system SYSTEM] \
  [--tag TAG] \
  [--limit N] \
  [--show-related]

validate - Validate rule files

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- validate \
  <FILE> \
  [--strict] \
  [--all]

list - List systems, categories, or rules

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- list \
  systems|categories|rules \
  [--system SYSTEM]

info - Show detailed rule information

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- info \
  <RULE_ID> \
  [--changelog]

Categorical Commands (NEW)

The tool now supports a categorical architecture with three layers:

Layer 1: Theories - Abstract rule schemas Layer 2: Interpretations - Concrete realizations of theories Layer 3: Worlds - Playable game instances

Theory Commands

theory init - Create a new base theory

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  theory init <THEORY_ID> --name "Theory Name"

theory extend - Extend an existing theory

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  theory extend <BASE_THEORY> <EXT_ID> --name "Extension Name"

theory list - List all theories

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  theory list [--show-extensions]

theory info - Show theory details

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  theory info <THEORY_ID>

Interpretation Commands

interp create - Create a new interpretation

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  interp create <INTERP_ID> --name "Name" --theory <THEORY1> [--theory <THEORY2>...]

interp realize - Map abstract rule to concrete

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  interp realize <INTERP_ID> <ABSTRACT_ID> \
  --concrete <CONCRETE_ID> --title "Title" [--content <FILE>]

interp list - List all interpretations

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  interp list [--theory <THEORY>] [--show-completeness]

interp validate - Check interpretation completeness

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  interp validate <INTERP_ID> [--strict]

interp info - Show interpretation details

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  interp info <INTERP_ID>

World Commands

world create - Create a new world

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  world create <WORLD_ID> --name "World Name" --interp <INTERP_ID>

world list - List all worlds

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  world list [--interp <INTERP_ID>]

world info - Show world details

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  world info <WORLD_ID> [--show-entities] [--show-transport]

Entity Commands

entity create - Create a new entity

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  entity create <TYPE> <ENTITY_ID> \
  --world <WORLD_ID> --name "Name" [--file <YAML_FILE>]

Types: character, object, event, location

entity list - List entities in a world

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  entity list <TYPE> --world <WORLD_ID>

entity show - Show entity details

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  entity show <TYPE> <ENTITY_ID> --world <WORLD_ID>

Transport Commands

transport create-functor - Create a transport functor

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  transport create-functor <FUNCTOR_ID> --name "Name" \
  --from <SOURCE_WORLD> --to <TARGET_WORLD> \
  --type <TYPE> [--map-file <FILE>]

Functor types: FreeFunctor, ForgetfulFunctor, Projection, Embedding

transport entity - Transport an entity between worlds

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  transport entity <TYPE> <ENTITY_ID> \
  --from <SOURCE_WORLD> --to <TARGET_WORLD> \
  --functor <FUNCTOR_ID> [--validate] [--dry-run]

transport validate - Validate a transport functor

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  transport validate <FUNCTOR_ID> [--check-adjunction]

transport functor - List transport functors

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  transport functor [--from <WORLD>] [--to <WORLD>]

Global Options

  • --data-dir, -d DIR - Root directory containing rulesets (default: ".")
  • --role, -r ROLE - User role: player or gm (default: player)
  • --format, -f FORMAT - Output format: text, json, markdown (default: text)
  • --verbose, -v - Enable verbose output

Common Workflows

Workflow 0: Complete Categorical Workflow (NEW)

This demonstrates the full categorical architecture:

# Layer 1: Create Theory (Abstract Rules)
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  theory init fantasy-core --name "Fantasy Core Theory" -d /absolute/path

# Layer 2: Create Interpretation (Concrete Rules)
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  interp create crossed-swords --name "Crossed Swords" \
  --theory fantasy-core -d /absolute/path

# Realize abstract rules to concrete
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  interp realize crossed-swords THEORY-COMBAT-001 \
  --concrete CORE-001 --title "Attack Resolution" -d /absolute/path

# Validate interpretation completeness
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  interp validate crossed-swords -d /absolute/path

# Layer 3: Create World (Playable Instance)
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  world create my-campaign --name "Northern Realms" \
  --interp crossed-swords -d /absolute/path

# Add Entities
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  entity create character sir-aldric \
  --world my-campaign --name "Sir Aldric" -d /absolute/path

# Create second world
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  world create shadow-realm --name "Shadow Realm" \
  --interp shadow-interp -d /absolute/path

# Create transport functor
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  transport create-functor light-to-shadow \
  --name "Corruption Functor" \
  --from my-campaign --to shadow-realm \
  --type ForgetfulFunctor -d /absolute/path

# Transport entity (dry-run preview)
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  transport entity character sir-aldric \
  --from my-campaign --to shadow-realm \
  --functor light-to-shadow --dry-run -d /absolute/path

Workflow 1: Create New Ruleset System

# 1. Initialize the system (MUST use absolute path)
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- \
  init /home/xsaw/haskell-monorepo-dnd-rules/rpg/my-fantasy-rpg \
  --id my-rpg --name "My Fantasy RPG"

# Creates:
# /home/xsaw/haskell-monorepo-dnd-rules/rpg/my-fantasy-rpg/
# ├── system.yaml
# ├── README.md
# ├── character-creation/
# ├── world-building/
# └── interactions/

# 2. Add first rule (ID auto-suggested) - use absolute path for --data-dir
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- add \
  -d /home/xsaw/haskell-monorepo-dnd-rules/rpg/my-fantasy-rpg \
  --category character-creation \
  --title "Ability Scores" \
  --tag core-mechanics

# 3. Edit the generated file to add content
# File created at: /home/xsaw/.../rpg/my-fantasy-rpg/character-creation/<rule-id>.md

# 4. Validate the rule (use absolute path)
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- validate \
  /home/xsaw/haskell-monorepo-dnd-rules/rpg/my-fantasy-rpg/character-creation/<rule-id>.md

Workflow 2: Query Rules

# Search for combat rules (use absolute path)
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- query \
  -d /home/xsaw/haskell-monorepo-dnd-rules/rpg/my-fantasy-rpg combat

# Filter by category and tag
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- query \
  -d /home/xsaw/haskell-monorepo-dnd-rules/rpg/my-fantasy-rpg \
  --category character-creation \
  --tag combat \
  --limit 10

# Get JSON output for scripting
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- query \
  -d /home/xsaw/haskell-monorepo-dnd-rules/rpg/my-fantasy-rpg \
  magic --format json | jq

# GM-only rules
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- query \
  -d /home/xsaw/haskell-monorepo-dnd-rules/rpg/my-fantasy-rpg \
  secret --role gm

Workflow 3: Add Rules with Specific IDs

# Add combat rule with explicit ID (use absolute path)
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- add \
  -d /home/xsaw/haskell-monorepo-dnd-rules/rpg/my-fantasy-rpg \
  --category character-creation \
  --id COMBAT-1.0 \
  --title "Melee Attacks" \
  --tag combat --tag melee \
  --visibility public

# Add GM-only secret
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- add \
  -d /home/xsaw/haskell-monorepo-dnd-rules/rpg/my-fantasy-rpg \
  --category world-building \
  --title "Campaign Secrets" \
  --visibility gm-only \
  --tag plot --tag secrets

File Structure

Directory Organization

my-ruleset/
├── system.yaml                 # System metadata
├── character-creation/         # Required category
│   ├── ability-scores.md
│   ├── classes.md
│   └── combat/                 # Subcategories allowed
│       └── melee-combat.md
├── world-building/             # Required category
│   ├── geography.md
│   └── magic-system.md
└── interactions/               # Required category
    └── social-rules.md

Rule File Format

Every rule file uses Markdown with YAML frontmatter:

---
category: character-creation
system: my-rpg
rules:
  - id: CHAR-001
    version: 1.0.0
    changelog:
      - version: 1.0.0
        date: 2025-11-16T10:00:00Z
        changes: "Initial version"
    tags: [core-mechanics, attributes]
    visibility: public
    title: "Ability Scores"
    # Optional fields:
    related: [CHAR-002, COMBAT-1.0]
    conditions: ["character.level >= 5"]
    formulas:
      attribute_modifier: "(score - 10) / 2"
    crossSystemRefs:
      - targetSystem: base-rpg
        targetRule: CORE-1.0
        refType: extends
---

## Character Creation

### [CHAR-001] Ability Scores

Every character has six core attributes:
- **Strength (STR)**: Physical power
- **Dexterity (DEX)**: Agility and reflexes
...

Rule ID Conventions

Format Rules

  • Pattern: PREFIX-X.Y or PREFIX-XYZ
  • PREFIX: Uppercase category abbreviation
  • Numbers: Version or sequence

Valid Examples

  • CHAR-001 - Character rule #1
  • COMBAT-1.0 - Combat rule v1.0
  • MAGIC-100 - Magic rule #100
  • STEALTH-2.5 - Stealth rule v2.5

Invalid Examples

  • char-001 - Lowercase prefix
  • Combat_1 - Underscore separator
  • magic.100 - Dot separator without prefix

Suggested Prefixes by Category

  • CHAR- - character-creation
  • COMBAT- - character-creation/combat
  • CLASS- - character-creation/classes
  • MAGIC- - world-building/magic
  • GEO- - world-building/geography
  • SOCIAL- - interactions/social
  • EXPLORE- - interactions/exploration

Validation

Common Validation Errors

Invalid Rule ID Format

ERROR: Rule ID must match pattern: UPPERCASE-NUMBER

Fix: Use format like CHAR-001 or COMBAT-1.0

Duplicate Rule ID

ERROR: Rule ID already exists in system

Fix: Use a different ID or let the tool auto-suggest one

Missing Required Fields

ERROR: Missing required field: tags

Fix: Add at least one tag to the rule

Prefix Convention Warning

WARNING: Expected prefix CHAR- for character-creation category

Fix: Use suggested prefix or ignore if intentional

Validation Workflow

# Validate single file
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- validate \
  my-rpg/character-creation/abilities.md

# Strict mode (warnings = errors)
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- validate \
  my-rpg/character-creation/abilities.md --strict

# Validate all files in directory
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- validate \
  my-rpg/character-creation/abilities.md --all

Best Practices

1. Let the Tool Suggest IDs

When adding rules, omit --id to get auto-suggested IDs:

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- add \
  -d my-rpg --category character-creation --title "New Rule"
# Output: Using suggested rule ID: CHAR-002

2. Use Consistent Tags

  • Use lowercase-with-dashes: core-mechanics, magic-system
  • Be specific: melee-combat not just combat
  • Tag for searchability: dice-rolls, character-advancement

3. Organize with Subcategories

character-creation/
├── core-mechanics.md
├── classes/
│   ├── fighter.md
│   ├── wizard.md
│   └── rogue.md
└── combat/
    ├── melee.md
    └── ranged.md

4. Use Visibility Appropriately

  • public (default): Visible to all players
  • gm-only: Hidden from players, visible to GMs
# Query as GM to see all rules
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- query \
  -d my-rpg --role gm

5. Version Your Rules

Use semantic versioning in rule IDs for major changes:

  • COMBAT-1.0 - Original combat rules
  • COMBAT-2.0 - Major revision of combat rules

Reference old versions in changelog:

changelog:
  - version: 2.0.0
    date: 2025-12-01T10:00:00Z
    changes: "Replaced COMBAT-1.0 with streamlined system"

6. Link Related Rules

rules:
  - id: COMBAT-2.0
    related: [CHAR-001, MAGIC-3.0]
    # Use --show-related when querying

7. Validate Before Committing

# In git pre-commit hook:
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- validate \
  changed-file.md --strict

Troubleshooting

Issue: "Error loading system"

Cause: Not in a valid ruleset directory or missing system.yaml Solution: Use --data-dir to specify the ruleset directory

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- query \
  --data-dir /path/to/my-rpg combat

Issue: "Rule not found"

Cause: Rule ID doesn't exist or visibility mismatch Solution:

  1. List all rules: list rules --system my-rpg
  2. Check with GM role: --role gm

Issue: "File already exists"

Cause: add command won't overwrite existing files Solution: Edit the existing file manually or use a different rule ID

Issue: Validation fails with prefix warning

Cause: Rule ID prefix doesn't match category convention Solution: Either:

  1. Change ID to use suggested prefix
  2. Accept the warning if prefix is intentional
  3. Use --strict flag to treat as error if needed

CRITICAL Format Requirements

System.yaml Format

WRONG:

system_id: my-rpg
name: My RPG
type: base                 # ✗ Wrong - must be "BaseSystem"
version: 1.0.0             # ✗ Wrong - must be object

CORRECT:

system_id: my-rpg
name: My RPG
type: BaseSystem           # ✓ Correct
version:                   # ✓ Correct - object format
  vMajor: 1
  vMinor: 0
  vPatch: 0
categories:
  - character-creation
  - world-building
  - interactions

Rule Frontmatter Format

WRONG:

---
id: CORE-001              # ✗ Wrong - must be "rule_id"
system: my-rpg            # ✗ Wrong - must be "system_id"
category: interactions
title: "My Rule"
tags: [core]
related: []               # ✗ Wrong - must be "related_rules"
---

CORRECT:

---
rule_id: CORE-001         # ✓ Correct
system_id: my-rpg         # ✓ Correct
category: interactions
title: "My Rule"
visibility: public
version: 1.0.0
tags: [core]
related_rules: []         # ✓ Correct
---

Rule ID Format Restrictions

Rule IDs MUST:

  • Use UPPERCASE prefix (2-6 letters)
  • Use dash separator
  • Use DIGITS ONLY after dash (no dots, no letters)

Valid:

  • CORE-001 - Simple number
  • COMBAT-100 - Three digits
  • CHAR-042 - Leading zeros OK
  • MAGIC-1 - Single digit OK

Invalid:

  • CORE-1.0 - Dots not allowed
  • core-001 - Lowercase not allowed
  • CORE_001 - Underscore not allowed
  • CORE-1A - Letters after dash not allowed

Common Init Command Bug

The init command may create system.yaml with incorrect format. After running init, you MUST fix:

# After: bazel run //...rpg-ruleset-cli -- init /path/to/system ...

# Fix system.yaml:
# 1. Change "type: base" → "type: BaseSystem"
# 2. Change "version: 1.0.0" → version object format
# 3. Delete README.md files (they conflict with rule parsing)

README.md Files

CRITICAL: The init command creates README.md files, but the loader tries to parse ALL .md files as rules. This causes "MissingFrontmatter" errors.

Solution: Delete README.md files after init:

rm /path/to/system/README.md
rm /path/to/system/*/README.md

Output Formats

Text (default)

Human-readable output for terminal use

JSON

For scripting and integration:

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- query \
  combat --format json | jq '.results[].rule.title'

Markdown

For documentation generation:

bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- query \
  --category character-creation --format markdown > rules.md

When to Use This Skill

Use rpg-ruleset-cli when the user wants to:

  • Create a new RPG system or ruleset
  • Add rules to an existing system
  • Search for specific rules by keyword, category, or tag
  • Validate rule files for correct format
  • List available systems, categories, or rules
  • Get detailed information about a specific rule
  • Organize game rules in a structured, queryable format
  • Manage player vs GM visibility of rules
  • Version and track changes to rules over time

Integration with Git

The tool is designed to work with version control:

cd my-rpg
git init
git add .
git commit -m "Initial ruleset"

# After adding rules
bazel run //haskell/app/rpg-ruleset-cli:rpg-ruleset-cli -- add ...
git add character-creation/new-rule.md
git commit -m "Add new character rule"

Quick Tips

  1. Start simple: Use initaddvalidate workflow
  2. Let tool suggest IDs: Omit --id for automatic suggestions
  3. Use tags liberally: Makes querying easier later
  4. Validate often: Catch errors early with validate --strict
  5. Query with filters: Narrow results with --category, --tag, --system
  6. JSON for scripts: Use --format json for automation
  7. GM role for secrets: Use --role gm to see hidden rules
  8. Related rules: Use --show-related to see rule connections