Claude Skill

riglet-creator

Imported from ypares/rigup.nix/riglets/riglet-creator.

LLM Mart · 0 points · 7 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download ypares-rigup.nix-riglets_riglet-creator-d48c9c3.zip · 20 KB
Part of ypares/rigup.nix — 4 skills

Install

skills CLI npx skills add https://github.com/YPares/rigup.nix/tree/main/riglets/riglet-creator
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install ypares-rigup-nix@llmmart
Git git clone https://github.com/YPares/rigup.nix.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole ypares/rigup.nix collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Riglet Creator

Creating effective riglets means writing knowledge (SKILL.md) that agents will rely on. This guide focuses on how to write high-quality documentation for riglets, organized efficiently.

For the structural/technical side of riglets (what goes in the Nix module, metadata fields, schema), see the riglet agent-rig-system's SKILL.md and references/metadata-guide.md.

Core Principles

Define the Main Intent

Ask yourself: what is the end goal here? What should this riglet teach? The intent metadata is there to help you here. It should guide how you approach the writing of a riglet. As a reminder, the possible intents are:

  • base: "abstract" riglet (e.g. to define options) solely meant to be imported by others to factorize configuration. Cannot be disclosed in a manifest
  • sourcebook: compendium of knowledge, glossary, useful domain knowledge
  • toolbox: open-ended set of tools related together
  • cookbook: operational know-how, heuristics, tricks and techniques that are useful to apprehend an otherwise complex toolset or domain
  • playbook: specific procedure or workflow to follow in a rigorous manner

A riglet should fall under one of these categories. If several apply, then it might be a better idea to split it into several. Discuss that with your user. Several riglets, each one with a clear focus, are better than one unorganized riglet that tries to cover everything without a real goal. Remember riglets can depend on each other via imports, so for example a very specialized "playbook" can depend on tools explained and documented in a more general "toolbox".

Concise is Key

Agents share context windows with conversation history, system instructions, and other riglets in the rig. Context is a shared resource.

Default assumption: Agents are already very capable. Only include knowledge agents don't already have. Challenge each piece of information: "Does the agent really need this explanation?" and "Does this paragraph justify its token cost?"

Prefer concrete examples over verbose explanations. Prefer links to references over embedding everything in SKILL.md.

Set Appropriate Degrees of Freedom

Match documentation specificity to the task's fragility and variability:

High freedom (general guidance): Use when multiple approaches are valid, decisions depend on context, or heuristics guide the process. Example: "Organizing commits in JJ" — many strategies work.

Medium freedom (documented patterns with options): Use when a preferred pattern exists but some variation is acceptable. Example: "Creating PDFs with Typst" — follow the basic template but customize styling.

Low freedom (specific procedures, few choices): Use when operations are fragile and error-prone, consistency is critical, or a specific sequence must be followed. Example: "Setting up encrypted credentials" — must follow exact steps.

Think of it as a path: a narrow bridge with cliffs needs specific guardrails (low freedom, detailed steps), while an open field allows many routes (high freedom, general principles).

Structure: Know What Goes Where

Riglets have different components for different purposes:

SKILL.md - Primary workflows and procedures

  • What: Core knowledge agents load first
  • When: Procedures, common workflows, decision trees
  • Length: ~100-150 lines ideally
  • Load cost: Loaded for every interaction

references/ - Deep knowledge, advanced topics

  • What: Advanced patterns, troubleshooting, detailed specifications
  • When: Complex scenarios, edge cases, detailed reference material
  • Length: 50-200 lines each, with TOC if >100
  • Load cost: Only loaded when agent determines it's needed

tools in Nix - Executable packages

  • What: CLI tools, compilers, interpreters needed by the riglet
  • When: When the riglet teaches workflows that use specific tools
  • Load cost: Built into rig environment, always available

Keep information in one place: SKILL.md or references, not both. Prefer references for detailed material unless it's core to the riglet—this keeps SKILL.md lean and makes information discoverable without hogging context.

Understanding the Riglet with Concrete Examples

Skip this step only when the riglet's patterns are already clearly understood.

Before writing a riglet, deeply understand what it will teach. Concrete examples drive effective documentation.

To create an effective riglet, clarify the scope with concrete examples:

  • "What workflows does this riglet enable?"
  • "What are realistic use cases?"
  • "What problems does it solve?"
  • "What would agents ask for that this riglet answers?"

For example, when building a riglet about version control with JJ:

  • What functionality should it cover? (Creating changes, managing history, collaboration?)
  • Can you give concrete examples? ("I need to reorganize my commits" or "I'm collaborating with git users")
  • What would an agent say that should trigger this riglet?

To avoid overwhelming agents later, ask progressively—start with the most important questions. Conclude when the riglet's scope is clear and you have concrete examples.

Planning the Reusable Documentation Contents

Transform concrete examples into effective documentation by analyzing what knowledge is needed.

For each concrete example/workflow:

  1. What knowledge is needed to execute it? (procedures, patterns, concepts)
  2. What details are essential vs. advanced? (core flow vs. edge cases)
  3. What reference materials would help? (checklists, templates, troubleshooting)

Example: For a JJ riglet handling "reorganizing commits":

  1. Agents need to understand: revsets, rebasing, interactive rebase workflows
  2. Essential: Basic rebase commands; Advanced: complex revset patterns
  3. Reference materials: Revset syntax guide, troubleshooting merge conflicts

Example: For a PDF riglet handling "extracting tables from PDFs":

  1. Agents need: Understanding of PDF structure, table detection, format conversion
  2. Essential: Simple table extraction; Advanced: handling complex nested tables
  3. Reference materials: Format specifications, edge cases, tool limitations

Example: For a Typst riglet handling "generating documents":

  1. Agents need: Typst syntax, layout patterns, styling fundamentals
  2. Essential: Basic template structure; Advanced: custom layouts and functions
  3. Tools needed: typst compiler, pandoc for format conversion
  4. Configuration: Templates for common document types
  5. Reference materials: Syntax reference, styling guide, troubleshooting layout issues

From this analysis, create a list of:

  • Main sections for SKILL.md (primary workflows)
  • Reference files needed (advanced patterns, troubleshooting, checklists)
  • Tools to include (what agents will need to execute workflows)
  • Configuration (templates, pre-configured settings)

Writing Effective SKILL.md

SKILL.md is the core knowledge. Write for agent efficiency:

Content Organization

Start with overview:

# My Riglet

This riglet teaches [what it covers].

Primary use cases:
- Use case 1
- Use case 2
- Use case 3

See references/advanced.md for deeper patterns.

Remain concise in this section, DO NOT duplicate info that is already in the meta.description and meta.whenToUse.

For documentation patterns, see patterns.md.

Documentation Patterns

For proven patterns to organize riglet documentation, see patterns.md. It covers:

  • Sequential workflows
  • Domain-specific organization
  • Conditional details with progressive disclosure
  • Troubleshooting-driven structures
  • Converting Skills to riglets

Writing Guidelines

Avoid deeply nested references - Keep reference links one level deep. All reference files should link directly from SKILL.md, not from other references.

Use imperative/infinitive form:

  • Good: "Use jj to manage changes"
  • Avoid: "This riglet manages changes" or "JJ is a version control system"

Avoid using bold text as pseudo section headers: You can go up to level 4 headers (####). The Rig manifest may show a table of contents of the riglets' SKILL.md files, and it detects headers starting at level 2 (##). Therefore, structuring with proper Markdown headers helps making this table of contents meaningful and evocative of what the SKILL.md will contain. For the same reason, do not go deeper than level 4, this would make the ToC more cluttered that it needs to.

Include concrete examples:

Bad: You can create commits with jj.

Good: To create a new commit:
  jj new -m "Add feature X"

Show expected output when relevant:

$ jj log
@  ckd6n8pf 2025-12-15 alice (empty) Add feature X
○  xzrxt9al 2025-12-15 alice Add docs

Link to references when context is available:

For complex scenarios, see [patterns.md](references/patterns.md) or [metadata-guide.md](references/metadata-guide.md).

Don't link proactively—mention references only when the agent is in a situation where they'd be relevant.

Avoid overwhelming context - Keep SKILL.md to ~100 lines. Extended explanations belong in reference files.

Use relative paths for references - All paths are relative to the file mentioning them: [patterns.md](references/patterns.md)

What Goes Where: SKILL.md vs References

Keep in SKILL.md:

  • Primary workflows and procedures agents will use most
  • Common decision trees ("If X, then do Y")
  • Essential concepts agents need to understand the workflows
  • Links to reference files (but not the detailed content itself)

Move to references:

  • Advanced patterns and edge cases
  • Detailed specifications and schemas
  • Troubleshooting guides
  • Code examples longer than 10 lines
  • Domain knowledge only needed for specific scenarios
  • Detailed API or command documentation

Rule of thumb: Information should live in SKILL.md OR references, not both. Information repetition wastes token budget.

When you find yourself writing "For more details, see..." you've found something that belongs in a reference file.

Organizing Reference Files

Reference files provide depth without bloating SKILL.md.

Design Principle: One Level Deep

Keep all references one level deep from SKILL.md. References should not link to other references.

Good:

SKILL.md → references/advanced.md
SKILL.md → references/troubleshooting.md

Avoid:

SKILL.md → references/patterns.md → references/patterns-detailed.md

Why? Agents need to understand the full scope of what's available. If references link to other references, the structure becomes opaque and agents might miss information.

Structure Longer References

For reference files longer than ~100 lines, include a table of contents so agents can see the full scope when previewing:

# Advanced JJ Patterns

## Table of Contents

- Revset Syntax (line 10)
- Interactive Rebase (line 45)
- Conflict Resolution (line 80)
- Undoing Changes (line 120)

## Revset Syntax

...

This lets agents understand the file's full scope without reading all of it, helping them decide if they need to load it.

Naming conventions

Use clear, specific names:

  • advanced.md - Advanced patterns in the main topic
  • troubleshooting.md - Common problems and solutions
  • checklists.md - Reusable checklists
  • domain-name.md - Domain-specific knowledge (for multi-domain riglets)
  • syntax-reference.md - Detailed syntax specifications

Packaging Custom Tools or Scripts with Riglets

Operations that are expected to be commonly performed when using the riglet can and probably SHOULD be provided as helper scripts. It's Nix, so tools can be created on the fly and properly packaged with the usual builders like writeShellScriptBin, writeShellApplication or even stdenv.mkDerivation, but riglets have a simple option for simple cases.

Simple cases: write local scripts and list paths in tools

The tools field supports direct file paths to scripts, which are automatically wrapped as executable packages:

How it works:

  • Script paths (e.g., ./scripts/helper[.sh]) are detected and wrapped using writeShellScriptBin
  • Final executable name is derived from filename (with extension if it has any, so prefer without extensions)
  • Scripts become available in the rig's bin/ directory alongside other tools

This is intended ONLY for SIMPLE sh or bash scripts which have NO DEPENDENCIES besides what is already listed in tools (as they will be together in $PATH once the rig is built).

Example directory-based riglet with scripts:

_:
{ pkgs, riglib, ... }: {
  config.riglets.my-riglet = {
    tools = [
      pkgs.jujutsu
      ./scripts/jj-desc-read  # → executable "jj-desc-read"
      ./scripts/jj-desc-edit  # → executable "jj-desc-edit"
    ];

    docs = riglib.writeFileTree {
      "SKILL.md" = ''
        # My Riglet

        ## Utility Scripts

        **Read a revision:**
        ```bash
        jj-desc-read @
        ```

        **Edit description programmatically:**
        ```bash
        jj-desc-edit sed 's/foo/bar/g'
        ```
      '';
    };

    meta = {
      name = "My Riglet";
      description = "JJ utilities with helper scripts";
      # ... other metadata
    };
  };
}

Directory structure:

riglets/my-riglet/
├── default.nix
└── scripts/
    ├── jj-desc-read
    └── jj-desc-edit

Advanced cases: make a custom tool via a custom derivation

For cases when you need more control over the packaging of the tools, consider the usual Nix builders from nixpkgs.

writeShellApplication e.g. can package an inlined script with its dependencies:

writeShellApplication {
  name = "show-nixos-org";

  runtimeInputs = [
    curl
    w3m
  ];

  text = ''
    curl -s 'https://nixos.org' | w3m -dump -T text/html
  '';
}

For instance, if you want to include a Python script to the riglet, package it properly with buildPythonApplication so ALL its dependencies are present.

Language-specific packaging guides

See the references directory for detailed guides on packaging tools in specific languages:

  • Python - buildPythonApplication and modern pyproject.toml support
  • Node.js/JavaScript - buildNpmPackage for npm-based projects
  • Rust - buildRustPackage with cargoHash or Cargo.lock
  • Go - buildGoModule with vendorHash
  • Haskell - haskellPackages.developPackage and callCabal2nix
  • Ruby - bundlerApp and bundlerEnv for gems
  • Java/Kotlin - buildMavenPackage and Gradle approaches

About external package-managers (uv, npm...)

If the riglet assumes that Python scripting will have to be done manually as part of executing the riglet's instructions, then prefer relying on uvx (provided through tools = [ pkgs.uv ... ]) and including usage instructions in the riglet's docs. Same goes for JS/TS with npx, etc.

But in such case DO:

  • include a proper pyproject.toml/package.json/etc. as an asset file (<riglet-folder>/assets/<foo>/pyproject.toml)
  • refer to it in the main riglet's doc
  • MAKE SURE it is packaged via the docs of the riglet (either as part of a path to a folder, or as an arg to riglib.writeFileTree)

The GOLDEN RULE is: users of a riglet must NEVER have to install ANYTHING globally on their system to use this riglet!!. This is why use of uvx, npx, etc (i.e. anything installing packages in a project-scoped fashion) is tolerated, but pip install IS NOT.

However whenever you can, proper packaging of ALL dependencies, packages etc. through Nix is always preferable to enable easy one-command installation of the whole rig.

The Riglet Creation Process

Putting it all together:

  1. Understand with concrete examples (5-10 min)

    • What workflows? What problems? What would agents ask for?
  2. Plan the documentation structure (5-10 min)

    • Which sections for SKILL.md?
    • Which topics need reference files?
    • Any assets or templates?
  3. Write SKILL.md with primary workflows (20-30 min)

    • Overview
    • 3-5 core workflows with concrete examples
    • Links to reference files
  4. Write reference files for advanced topics (10-20 min per reference)

    • Advanced patterns
    • Troubleshooting
    • Detailed specifications
  5. Test with real tasks (10+ min)

    • Use the riglet for actual work
    • Notice gaps or confusion
    • Update SKILL.md or references
  6. Iterate based on usage

    • Clarify confusing sections
    • Add missing workflows
    • Reorganize if structure isn't working

Quality Checklist

Before considering documentation complete:

  • SKILL.md exists and covers primary workflows
  • Concrete examples throughout (commands, output, use cases)
  • No jargon without explanation - define domain terms
  • Links to references mentioned naturally (not exhaustively)
  • Reference files structured with TOC if >100 lines
  • Relative paths all correct (tested from the docs directory)
  • No unreferenced tools - everything mentioned has a link or exists in the rig
  • Tested in practice - actually used for real workflows
Files (rigup.nix)
  • references
    • metadata-guide.md 2 KB
      # Documentation Quality Checklist
      
      Before publishing a riglet's documentation:
      
      ## Content Coverage
      
      - [ ] **SKILL.md exists** with clear overview
      - [ ] **Primary workflows documented** (3-5 core use cases)
      - [ ] **Concrete examples throughout** - actual commands and output
      - [ ] **No unexplained jargon** - domain terms are defined or linked
      - [ ] **Links to references natural** (not exhaustive listing)
      
      ## Organization & Structure
      
      - [ ] **SKILL.md is concise** (~100-150 lines max)
      - [ ] **Complex topics in references** (not in SKILL.md)
      - [ ] **Reference files have TOC** if longer than 100 lines
      - [ ] **Clear file names** (advanced.md, troubleshooting.md, etc.)
      - [ ] **One level deep references** - all links from SKILL.md, not between references
      
      ## Writing Quality
      
      - [ ] **Imperative/infinitive form** ("Use tool X" not "This riglet uses")
      - [ ] **Step-by-step when procedural** (numbered lists with expected output)
      - [ ] **Examples show real output** where helpful
      - [ ] **Tool warnings/limitations mentioned** if relevant
      - [ ] **Related workflows cross-linked** (e.g., "For bulk ops, see...")
      
      ## Technical Accuracy
      
      - [ ] **No tool errors in examples** (actually tested)
      - [ ] **All mentioned tools exist in the rig** (in `tools = [ ]`)
      - [ ] **All reference links valid** (files exist, paths relative)
      - [ ] **Configuration examples correct** (if any provided)
      
      ## Reference Design
      
      - [ ] **Troubleshooting reference** (if users commonly hit problems)
      - [ ] **Advanced patterns reference** (if basics + advanced split makes sense)
      - [ ] **Checklists/templates** (if helpful for the workflow)
      - [ ] **Each reference focuses** on one topic (not kitchen-sink)
      
      ## Before Declaring Complete
      
      Test the riglet in a real rig:
      
      ```bash
      # Add to rigup.toml
      [rigs.default.riglets]
      self = ["my-riglet"]
      
      # Build
      nix build .#rigs.x86_64-linux.default.home
      
      # Read documentation
      cat result/docs/my-riglet/SKILL.md
      cat result/docs/my-riglet/references/*.md
      
      # Try workflows from SKILL.md
      ```
      
      Ask: "If I were an agent, would I understand how to do the workflows described?"
      
      
    • packaging-go.md 2.9 KB
      # Packaging Go Tools with Nix
      
      Quick reference for packaging Go applications as Nix derivations.
      
      ## Basic Application Packaging: buildGoModule
      
      Standard approach for Go modules (most common in 2025):
      
      ```nix
      { lib, buildGoModule, fetchFromGitHub }:
      
      buildGoModule rec {
        pname = "my-go-tool";
        version = "1.0.0";
      
        src = fetchFromGitHub {
          owner = "example";
          repo = "my-tool";
          rev = "v${version}";
          hash = "sha256-...";
        };
      
        # Hash of vendored Go dependencies
        vendorHash = "sha256-...";
      
        meta = with lib; {
          description = "My Go tool";
          homepage = "https://example.com";
          license = licenses.mit;
          mainProgram = "my-tool";
        };
      }
      ```
      
      ## Getting the vendorHash
      
      To obtain the vendor hash, use a fake hash:
      
      ```nix
      vendorHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
      ```
      
      Build the package and Nix will report the correct hash. Alternatively, use:
      
      ```nix
      vendorHash = lib.fakeHash;
      ```
      
      ## Using Vendored Dependencies
      
      If your project already vendors dependencies (has a `vendor/` directory), skip fetching:
      
      ```nix
      buildGoModule {
        pname = "my-tool";
        version = "1.0.0";
        src = ./.;
      
        # Use existing vendor directory
        vendorHash = null;
      }
      ```
      
      ## Two-Phase Build Process
      
      `buildGoModule` works in two phases:
      
      1. **Fetcher derivation**: Downloads and vendors all Go module dependencies (produces the `vendorHash`)
      2. **Final derivation**: Builds the binary using the vendored dependencies
      
      This ensures reproducibility by locking all transitive dependencies.
      
      ## Local Go Projects
      
      For Go tools included in your riglet:
      
      ```nix
      { pkgs, ... }:
      
      {
        config.riglets.my-riglet = {
          tools = [
            (pkgs.buildGoModule {
              pname = "my-local-tool";
              version = "0.1.0";
              src = ./scripts/my-tool;  # Contains go.mod
              vendorHash = "sha256-...";
            })
          ];
        };
      }
      ```
      
      ## Specifying Go Version
      
      Different Go versions are available:
      
      ```nix
      buildGoModule.override { go = pkgs.go_1_22; }
      ```
      
      Common versions: `go` (latest stable), `go_1_22`, `go_1_21`, etc.
      
      ## Building Without go.mod
      
      For older projects not using modules, use `buildGoPackage` (deprecated but still available):
      
      ```nix
      buildGoPackage {
        pname = "old-tool";
        goPackagePath = "github.com/example/old-tool";
        # ...
      }
      ```
      
      However, `buildGoModule` is strongly preferred for all new projects.
      
      ## Alternative: gomod2nix
      
      For more control over dependency management:
      
      ```bash
      # Generate nix expressions from go.mod
      gomod2nix
      ```
      
      This creates `gomod2nix.toml` which can be used instead of `vendorHash`.
      
      ## Further Reading
      
      - **Official NixOS Wiki - Go**: https://nixos.wiki/wiki/Go
      - **nixpkgs Go documentation**: https://ryantm.github.io/nixpkgs/languages-frameworks/go/
      - **buildGoModule source**: https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/go/module.nix
      - **Packaging a Go app tutorial**: https://blog.ktz.me/packaging-a-go-app-for-nixos/
      - **gomod2nix announcement**: https://www.tweag.io/blog/2021-03-04-gomod2nix/
      
    • packaging-haskell.md 3.3 KB
      # Packaging Haskell Tools with Nix
      
      Quick reference for packaging Haskell applications as Nix derivations.
      
      ## Basic Concepts
      
      **haskellPackages**: A large set containing Haskell packages from Hackage and Stackage. It's a synonym for `haskell.packages.ghcXYZ` where XYZ is the current default GHC version.
      
      **Version selection**:
      - Stackage packages: Use versions from current Stackage LTS snapshot
      - Other packages: Use latest version from Hackage
      
      ## Simple Development Shell
      
      For quick Haskell development in a riglet:
      
      ```nix
      { pkgs, ... }:
      
      pkgs.mkShell {
        packages = with pkgs.haskellPackages; [
          (ghcWithPackages (hpkgs: with hpkgs; [
            aeson
            text
            bytestring
          ]))
          cabal-install
        ];
      }
      ```
      
      ## Using developPackage
      
      For projects with a `.cabal` file, use `developPackage`:
      
      ```nix
      { pkgs, ... }:
      
      {
        config.riglets.my-riglet = {
          tools = [
            (pkgs.haskellPackages.developPackage {
              root = ./scripts/my-tool;  # Directory containing .cabal file
              name = "my-tool";
            })
          ];
        };
      }
      ```
      
      `developPackage` is a wrapper around `callCabal2nixWithOptions` that automatically converts a Cabal file to a Nix expression.
      
      ## Manual Package Definition
      
      For more control, define a Haskell package manually:
      
      ```nix
      { lib, haskellPackages, fetchFromGitHub }:
      
      haskellPackages.mkDerivation {
        pname = "my-haskell-tool";
        version = "1.0.0";
      
        src = fetchFromGitHub {
          owner = "example";
          repo = "my-tool";
          rev = "v1.0.0";
          hash = "sha256-...";
        };
      
        libraryHaskellDepends = with haskellPackages; [
          aeson
          text
        ];
      
        executableHaskellDepends = with haskellPackages; [
          optparse-applicative
        ];
      
        license = lib.licenses.mit;
      }
      ```
      
      ## Using callCabal2nix
      
      Convert a Cabal file to Nix expression on-the-fly:
      
      ```nix
      { haskellPackages }:
      
      haskellPackages.callCabal2nix "my-tool" ./path/to/cabal/project { }
      ```
      
      The third argument is for overriding dependencies if needed.
      
      ## Specifying GHC Version
      
      Use a specific GHC version:
      
      ```nix
      { pkgs }:
      
      pkgs.haskell.packages.ghc965.developPackage {
        root = ./.;
      }
      ```
      
      Available: `ghc98`, `ghc965`, `ghc947`, `ghc928`, etc.
      
      ## Known Limitations (2025)
      
      - About 50% of packages in `haskellPackages` are marked as broken (deprecated/unmaintained)
      - GHCJS support removed; use `pkgsCross.ghcjs` instead
      - GHC versions with integer-simple removed (as of Sept 2025)
      
      ## Quick Tool Packaging Example
      
      Packaging a Haskell CLI tool in a riglet:
      
      ```nix
      _:
      { pkgs, riglib, ... }: {
        config.riglets.my-riglet = {
          tools = [
            (pkgs.haskellPackages.callCabal2nix "my-tool" ./scripts/my-tool { })
            pkgs.haskellPackages.cabal-install
          ];
      
          docs = riglib.writeFileTree {
            "SKILL.md" = ''
              # My Riglet
      
              Use `my-tool` for...
            '';
          };
      
          meta = {
            name = "My Haskell Riglet";
            description = "Provides my-tool for X";
          };
        };
      }
      ```
      
      ## Further Reading
      
      - **Official NixOS Wiki - Haskell**: https://wiki.nixos.org/wiki/Haskell
      - **nixpkgs Haskell documentation**: https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/haskell.section.md
      - **Haskell package user's guide**: https://haskell4nix.readthedocs.io/nixpkgs-users-guide.html
      - **Incremental packaging guide**: https://www.haskellforall.com/2022/08/incrementally-package-haskell-program.html
      - **Gabriella439's Haskell-Nix guide**: https://github.com/Gabriella439/haskell-nix
      
    • packaging-java-kotlin.md 4.3 KB
      # Packaging Java/Kotlin Tools with Nix
      
      Quick reference for packaging Java and Kotlin applications as Nix derivations.
      
      ## Maven Projects: buildMavenPackage
      
      For Maven-based projects (works for Java, Kotlin, Scala, and other JVM languages):
      
      ```nix
      { lib, maven, fetchFromGitHub }:
      
      maven.buildMavenPackage rec {
        pname = "my-java-tool";
        version = "1.0.0";
      
        src = fetchFromGitHub {
          owner = "example";
          repo = "my-tool";
          rev = "v${version}";
          hash = "sha256-...";
        };
      
        # Hash of Maven dependencies
        mvnHash = "sha256-...";
      
        # Optional: specify which artifact to install
        installPhase = ''
          runHook preInstall
          install -Dm644 target/my-tool-${version}.jar $out/share/java/my-tool.jar
          runHook postInstall
        '';
      
        meta = with lib; {
          description = "My Java/Kotlin tool";
          homepage = "https://example.com";
          license = licenses.asl20;
        };
      }
      ```
      
      ## Getting the mvnHash
      
      Use a fake hash initially:
      
      ```nix
      mvnHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
      ```
      
      Build and Nix will provide the correct hash.
      
      ## Standard Installation
      
      After building, `buildMavenPackage` automatically:
      - Saves `.jar` to `$out/share/java`
      - Creates a wrapper script for execution (if there's a main class)
      
      ## Gradle Projects
      
      **Status (2025)**: Gradle support is improving but remains challenging compared to Maven.
      
      For Gradle projects, consider these approaches:
      
      ### 1. Pre-built Binary Wrapping
      
      Package the pre-built JAR/binary with proper Java runtime:
      
      ```nix
      { lib, stdenv, makeWrapper, jre, fetchurl }:
      
      stdenv.mkDerivation rec {
        pname = "my-kotlin-tool";
        version = "1.0.0";
      
        src = fetchurl {
          url = "https://example.com/releases/my-tool-${version}.jar";
          hash = "sha256-...";
        };
      
        nativeBuildInputs = [ makeWrapper ];
      
        dontUnpack = true;
      
        installPhase = ''
          runHook preInstall
      
          mkdir -p $out/share/java
          cp $src $out/share/java/my-tool.jar
      
          mkdir -p $out/bin
          makeWrapper ${jre}/bin/java $out/bin/my-tool \
            --add-flags "-jar $out/share/java/my-tool.jar"
      
          runHook postInstall
        '';
      
        meta = with lib; {
          description = "My Kotlin tool";
          license = licenses.mit;
          mainProgram = "my-tool";
        };
      }
      ```
      
      ### 2. Manual Gradle Build
      
      For simpler Gradle projects, build manually:
      
      ```nix
      { lib, stdenv, gradle, jdk, makeWrapper }:
      
      stdenv.mkDerivation {
        pname = "my-gradle-app";
        version = "1.0.0";
        src = ./.;
      
        nativeBuildInputs = [ gradle jdk makeWrapper ];
      
        buildPhase = ''
          gradle build --no-daemon
        '';
      
        installPhase = ''
          mkdir -p $out/share/java $out/bin
          cp build/libs/*.jar $out/share/java/
          makeWrapper ${jdk}/bin/java $out/bin/my-app \
            --add-flags "-jar $out/share/java/my-app.jar"
        '';
      }
      ```
      
      **Note**: This approach isn't fully reproducible as Gradle may download dependencies at build time.
      
      ## Using makeWrapper for JAVA_HOME
      
      When packaging Java/Kotlin tools, use `makeWrapper` to set `JAVA_HOME`:
      
      ```nix
      makeWrapper ${jre}/bin/java $out/bin/my-tool \
        --set JAVA_HOME ${jre} \
        --add-flags "-jar $out/share/java/my-tool.jar"
      ```
      
      This ensures the correct Java version without requiring `patchelf` or FHS environments.
      
      ## Java Versions
      
      Specify Java version by choosing the appropriate JDK/JRE:
      
      ```nix
      buildMavenPackage.override { jdk = pkgs.jdk21; }
      ```
      
      Available: `jdk` (latest LTS), `jdk21`, `jdk17`, `jdk11`, `jre`, etc.
      
      ## Kotlin-Specific Considerations
      
      Kotlin projects work the same as Java:
      - **Maven**: Use `buildMavenPackage` (recommended)
      - **Gradle**: Pre-built binary wrapping or manual build
      
      Kotlin Language Server example (2025): Packaged using pre-built binary approach with `makeWrapper`.
      
      ## Alternative: mvn2nix
      
      For complex Maven projects:
      
      ```bash
      # Generate Nix expression from pom.xml
      mvn2nix
      ```
      
      This can help handle complex dependency trees.
      
      ## Further Reading
      
      - **nixpkgs Maven documentation**: https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/maven.section.md
      - **Maven language guide**: https://ryantm.github.io/nixpkgs/languages-frameworks/maven/
      - **Packaging Kotlin LSP (2025)**: https://britter.dev/blog/2025/11/15/kotlin-lsp-nixvim/
      - **NixOS + Enterprise Java (2025)**: https://britter.dev/blog/2025/02/27/nix-java-enterprise/
      - **Packaging Gradle software**: https://rafael.ovh/posts/packaging-gradle-software-with-nix/
      - **mvn2nix tool**: https://discourse.nixos.org/t/mvn2nix-packaging-maven-application-made-easy/8751
      
    • packaging-nodejs.md 2.8 KB
      # Packaging Node.js/JavaScript Tools with Nix
      
      Quick reference for packaging Node.js applications and npm packages as Nix derivations.
      
      ## Basic Application Packaging: buildNpmPackage
      
      The modern approach for npm-based projects (2025):
      
      ```nix
      { lib, buildNpmPackage, fetchFromGitHub }:
      
      buildNpmPackage rec {
        pname = "my-node-tool";
        version = "1.0.0";
      
        src = fetchFromGitHub {
          owner = "example";
          repo = "my-tool";
          rev = "v${version}";
          hash = "sha256-...";
        };
      
        # Hash of npm dependencies cache
        npmDepsHash = "sha256-...";
      
        # Optional: run custom build script
        npmBuildScript = "build";
      
        meta = with lib; {
          description = "My Node.js tool";
          homepage = "https://example.com";
          license = licenses.mit;
          mainProgram = "my-tool";
        };
      }
      ```
      
      ## Getting the npmDepsHash
      
      To obtain the hash, use a fake hash initially:
      
      ```nix
      npmDepsHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
      ```
      
      Build the package and Nix will report the correct hash in the error message. Replace with the correct hash.
      
      ## Key Points
      
      **Modern approach**: `buildNpmPackage` creates a reproducible npm cache of dependencies without requiring auto-generated lock files.
      
      **npm vs yarn vs pnpm**:
      - For npm projects: use `buildNpmPackage` (recommended)
      - For yarn projects: consider `yarn2nix` or `buildNpmPackage` with yarn support
      - For pnpm projects: experimental support available
      
      **Build scripts**: Specify custom build script with `npmBuildScript = "build"` (defaults to "build" if it exists in package.json).
      
      ## Local Project Packaging
      
      For a local Node.js project in your riglet:
      
      ```nix
      { pkgs, ... }:
      
      {
        config.riglets.my-riglet = {
          tools = [
            (pkgs.buildNpmPackage {
              pname = "my-local-tool";
              version = "0.1.0";
              src = ./scripts/my-tool;  # Contains package.json
              npmDepsHash = "sha256-...";
            })
          ];
        };
      }
      ```
      
      ## Alternative: node2nix
      
      For projects requiring more control, `node2nix` generates Nix expressions from `package.json`:
      
      ```bash
      # Generate nix expressions
      node2nix -i package.json
      
      # This creates node-packages.nix, node-env.nix, default.nix
      ```
      
      Then reference the generated `default.nix` in your riglet.
      
      ## Node.js Versions
      
      Multiple Node.js versions available in nixpkgs:
      - `nodejs`: Latest LTS (alias)
      - `nodejs_22`: Node.js 22.x
      - `nodejs_20`: Node.js 20.x
      
      Specify version explicitly if needed:
      ```nix
      buildNpmPackage.override { nodejs = pkgs.nodejs_20; }
      ```
      
      ## Further Reading
      
      - **Official NixOS Wiki - Node.js**: https://wiki.nixos.org/w/index.php?title=Node.js
      - **nixpkgs JavaScript documentation**: https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/javascript.section.md
      - **node2nix repository**: https://github.com/svanderburg/node2nix
      - **Managing Node.js on NixOS guide**: https://medium.com/thelinux/managing-node-js-versions-on-nixos-a-comprehensive-guide-0b452e194a1b
      
    • packaging-python.md 2.7 KB
      # Packaging Python Tools with Nix
      
      Quick reference for packaging Python applications and scripts as Nix derivations.
      
      ## Basic Application Packaging: buildPythonApplication
      
      For standalone Python applications (not libraries), use `buildPythonApplication`:
      
      ```nix
      { lib, python3, fetchPypi }:
      
      python3.pkgs.buildPythonApplication rec {
        pname = "my-tool";
        version = "1.0.0";
      
        # Modern pyproject.toml-based projects
        pyproject = true;
      
        src = fetchPypi {
          inherit pname version;
          hash = "sha256-...";
        };
      
        # Runtime dependencies
        propagatedBuildInputs = with python3.pkgs; [
          requests
          click
        ];
      
        # Build-time dependencies (for pyproject builds)
        build-system = with python3.pkgs; [
          setuptools
          wheel
        ];
      
        meta = with lib; {
          description = "My Python tool";
          homepage = "https://example.com";
          license = licenses.mit;
        };
      }
      ```
      
      ## Key Points
      
      **Applications vs Libraries**: `buildPythonApplication` is for end-user tools. Use `buildPythonPackage` for libraries that will be dependencies of other Python packages.
      
      **Modern build systems (2025)**: Set `pyproject = true` for projects using `pyproject.toml`. Specify the build backend in `build-system` (commonly `setuptools`, `hatchling`, `poetry-core`, or `flit-core`).
      
      **Legacy projects**: For older `setup.py`-based projects, use `format = "setuptools"` instead of `pyproject = true`.
      
      **Dependencies**:
      - `propagatedBuildInputs`: Runtime Python dependencies
      - `build-system`: Build tools (setuptools, wheel, etc.)
      - `nativeBuildInputs`: Build-time non-Python tools
      
      ## Local Scripts
      
      For simple local scripts included in a riglet:
      
      ```nix
      { pkgs, python3, ... }:
      
      let
        myScript = python3.pkgs.buildPythonApplication {
          pname = "my-script";
          version = "0.1.0";
      
          pyproject = true;
      
          src = ./scripts/my-script;  # Directory with pyproject.toml
      
          propagatedBuildInputs = with python3.pkgs; [
            requests
          ];
      
          build-system = with python3.pkgs; [
            setuptools
          ];
        };
      in {
        config.riglets.my-riglet = {
          tools = [ myScript ];
        };
      }
      ```
      
      ## Helper Tools
      
      **nix-init**: Automatically generate package expressions for Python projects. Prefetches sources, parses dependencies, and fills in most metadata.
      
      ## Further Reading
      
      - **Official nixpkgs Python documentation**: https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/python.section.md
      - **NixOS Wiki - Packaging/Python**: https://wiki.nixos.org/wiki/Packaging/Python
      - **Python language guide**: https://ryantm.github.io/nixpkgs/languages-frameworks/python/
      - **Tutorial - Using and creating Python packages**: https://fridh.github.io/nix-tutorials/tutorials/02-python/01-using-and-creating-python-packages.html
      
    • packaging-ruby.md 3.3 KB
      # Packaging Ruby Tools with Nix
      
      Quick reference for packaging Ruby applications and gems as Nix derivations.
      
      ## Basic Application Packaging: bundlerApp
      
      For Ruby executables intended as standalone tools, use `bundlerApp`:
      
      ```nix
      { bundlerApp }:
      
      bundlerApp {
        pname = "my-ruby-tool";
        gemdir = ./.;  # Directory with Gemfile, Gemfile.lock, gemset.nix
        exes = [ "my-tool" ];  # List of executables to expose
      }
      ```
      
      `bundlerApp` creates a package that only exposes the listed executables, avoiding conflicts from common paths like `bin/rake` or `bin/bundler`.
      
      ## Using bundlerEnv
      
      For development environments or when you need all gems available:
      
      ```nix
      { bundlerEnv, ruby }:
      
      let
        gems = bundlerEnv {
          name = "my-project-gems";
          gemdir = ./.;
        };
      in
      mkShell {
        packages = [ gems gems.wrappedRuby ];
      }
      ```
      
      `bundlerEnv` is a wrapper over all gems in your gemset, making all `/lib` and `/bin` directories available.
      
      **Note**: By default, only the `default` group is included. To include other groups:
      
      ```nix
      bundlerEnv {
        name = "my-gems";
        gemdir = ./.;
        groups = [ "default" "development" "test" ];
      }
      ```
      
      ## Generating gemset.nix with bundix
      
      Ruby packaging in Nix requires a `gemset.nix` file generated from your `Gemfile.lock`:
      
      ```bash
      # Install bundix
      nix-shell -p bundix
      
      # Generate gemset.nix
      bundix
      ```
      
      This creates `gemset.nix` alongside your `Gemfile` and `Gemfile.lock`.
      
      ## Directory Structure
      
      Your Ruby project directory should contain:
      ```
      my-ruby-tool/
      ├── Gemfile
      ├── Gemfile.lock
      ├── gemset.nix       # Generated by bundix
      └── my-tool.rb       # or bin/my-tool
      ```
      
      ## Local Ruby Tool in a Riglet
      
      Example of packaging a local Ruby script:
      
      ```nix
      _:
      { pkgs, riglib, ... }: {
        config.riglets.my-riglet = {
          tools = [
            (pkgs.bundlerApp {
              pname = "my-tool";
              gemdir = ./scripts/my-tool;
              exes = [ "my-tool" ];
            })
          ];
      
          docs = riglib.writeFileTree {
            "SKILL.md" = ''
              # My Ruby Riglet
      
              Use `my-tool` to...
            '';
          };
      
          meta = {
            name = "My Ruby Riglet";
            description = "Provides my-tool for X";
          };
        };
      }
      ```
      
      ## Packaging Individual Gems
      
      For packaging a single gem (less common in riglets):
      
      ```nix
      { lib, bundlerApp, fetchFromGitHub }:
      
      bundlerApp {
        pname = "jekyll";
        gemdir = ./.;
        exes = [ "jekyll" ];
      }
      ```
      
      ## Alternative: ruby-nix
      
      For modern reproducible Ruby environments, consider `ruby-nix`:
      
      ```bash
      # Generate nix files from Gemfile.lock
      nix run github:inscapist/ruby-nix -- lock
      ```
      
      This generates `.nix-ruby` directory with all necessary Nix files.
      
      ## Ruby Versions
      
      Specify Ruby version by using different Ruby packages:
      
      ```nix
      bundlerApp.override { ruby = pkgs.ruby_3_3; }
      ```
      
      Available: `ruby` (default), `ruby_3_3`, `ruby_3_2`, etc.
      
      ## Further Reading
      
      - **Official nixpkgs Ruby documentation**: https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/ruby.section.md
      - **Ruby language guide**: https://ryantm.github.io/nixpkgs/languages-frameworks/ruby/
      - **NixOS Wiki - Packaging/Ruby**: https://nixos.wiki/wiki/Packaging/Ruby
      - **bundix repository**: https://github.com/nix-community/bundix
      - **ruby-nix (modern approach)**: https://github.com/inscapist/ruby-nix
      - **Ruby development guide**: https://jamesmead.org/blog/2020-07-26-a-simple-ruby-development-environment-using-nix-shell
      
    • packaging-rust.md 2.9 KB
      # Packaging Rust Tools with Nix
      
      Quick reference for packaging Rust applications as Nix derivations.
      
      ## Basic Application Packaging: buildRustPackage
      
      Standard approach using `rustPlatform.buildRustPackage`:
      
      ```nix
      { lib, rustPlatform, fetchFromGitHub }:
      
      rustPlatform.buildRustPackage rec {
        pname = "my-rust-tool";
        version = "1.0.0";
      
        src = fetchFromGitHub {
          owner = "example";
          repo = "my-tool";
          rev = "v${version}";
          hash = "sha256-...";
        };
      
        # Hash of all Cargo dependencies
        cargoHash = "sha256-...";
      
        meta = with lib; {
          description = "My Rust tool";
          homepage = "https://example.com";
          license = licenses.mit;
          mainProgram = "my-tool";
        };
      }
      ```
      
      ## Getting the cargoHash
      
      Use a fake hash initially:
      
      ```nix
      cargoHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
      ```
      
      Build the package and Nix will provide the correct hash. Replace with it.
      
      ## Alternative: Using Cargo.lock Directly
      
      Simpler approach when you have `Cargo.lock`:
      
      ```nix
      { lib, rustPlatform }:
      
      rustPlatform.buildRustPackage {
        pname = "my-tool";
        version = "0.1.0";
      
        src = lib.cleanSource ./.;
      
        # Reference Cargo.lock directly
        cargoLock.lockFile = ./Cargo.lock;
      
        meta = with lib; {
          description = "My Rust tool";
          license = licenses.mit;
        };
      }
      ```
      
      This is often simpler for local projects where you already have a committed `Cargo.lock`.
      
      ## Local Rust Projects
      
      For Rust tools included in your riglet:
      
      ```nix
      { pkgs, system, ... }:
      
      {
        config.riglets.my-riglet = {
          tools = [
            (pkgs.rustPlatform.buildRustPackage {
              pname = "my-local-tool";
              version = "0.1.0";
              src = ./scripts/my-tool;  # Contains Cargo.toml and Cargo.lock
              cargoLock.lockFile = ./scripts/my-tool/Cargo.lock;
            })
          ];
        };
      }
      ```
      
      ## Advanced: Faster Builds with Alternative Tools
      
      For larger projects, these tools can provide faster incremental builds by separating dependencies from application code:
      
      - **crane**: Modern, composable Rust build system for Nix
      - **naersk**: Minimal, fast Rust builds
      - **crate2nix**: Generates Nix expressions from Cargo.toml
      
      Example with crane:
      ```nix
      { crane, system }:
      
      let
        craneLib = crane.mkLib pkgs;
      in
      craneLib.buildPackage {
        src = ./.;
        # Crane automatically handles Cargo.lock
      }
      ```
      
      ## 2025 Development: devenv Integration
      
      Modern Rust development environments can use `devenv` with `languages.rust.import` for automatic packaging.
      
      ## Further Reading
      
      - **Official NixOS Wiki - Rust**: https://wiki.nixos.org/wiki/Rust
      - **nixpkgs Rust documentation**: https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/rust.section.md
      - **How to package a Rust app**: https://m7.rs/blog/2022-11-01-package-a-rust-app-with-nix/
      - **devenv Rust guide (2025)**: https://devenv.sh/blog/2025/08/22/closing-the-nix-gap-from-environments-to-packaged-applications-for-rust/
      - **Building from workspaces**: https://www.tweag.io/blog/2022-09-22-rust-nix/
      
    • patterns.md 2 KB
      # Riglet Documentation Patterns
      
      Proven patterns for organizing riglet documentation effectively.
      
      ## Pattern 1: Sequential Workflow
      
      Use when the riglet teaches step-by-step procedures:
      
      ```markdown
      ## Workflow: Rotating PDFs
      
      1. Load document: `pdftool load file.pdf`
      2. Rotate pages: `pdftool rotate -a 90 file.pdf`
      3. Save result: `pdftool save file.pdf`
      
      For bulk operations: See [batch-operations.md](references/batch-operations.md)
      ```
      
      ## Pattern 2: Domain-Specific Organization
      
      Use when covering multiple domains (e.g., BigQuery finance vs. product metrics):
      
      ```markdown
      # BigQuery Riglet
      
      ## Overview
      
      Query BigQuery for metrics across different domains.
      
      ## Financial Metrics
      
      See [finance.md](references/finance.md) for:
      - Revenue calculations
      - Billing costs
      
      ## Product Metrics
      
      See [product.md](references/product.md) for:
      - Feature usage
      - API adoption
      ```
      
      Agents only load the domain reference they need.
      
      ## Pattern 3: Conditional Details with Progressive Disclosure
      
      Use for tools/topics with basic and advanced usage:
      
      ```markdown
      ## Creating Documents
      
      Basic template for most cases:
      
      ```nix
      typst { title = "..."; }
      ```
      
      **Advanced layouts**: See [layouts.md](references/layouts.md)
      **Custom styling**: See [styling.md](references/styling.md)
      **Performance**: See [performance.md](references/performance.md)
      ```
      
      ## Pattern 4: Troubleshooting-Driven Organization
      
      Use when users commonly hit problems:
      
      ```markdown
      ## Common Workflows
      
      - Creating a change (simple case)
      - Rebasing changes
      
      ## Troubleshooting
      
      See [troubleshooting.md](references/troubleshooting.md) for:
      - "I accidentally deleted a change"
      - "Rebasing is creating conflicts"
      - "I need to undo multiple changes"
      ```
      
      ## Pattern 5: Skill-to-Riglet Direct Port
      
      When converting an existing Agent Skill to a riglet:
      
      1. Copy SKILL.md content verbatim (it's already well-written)
      2. Move advanced sections to `references/` subdirectory
      3. Update any skill-specific instructions (build scripts, etc.)
      4. Keep the same organization and linking structure
      
      This is the lowest-friction conversion.
      
      
  • default.nix 1023 B · in bundle
  • SKILL.md 17.1 KB
    # Riglet Creator
    
    Creating effective riglets means writing knowledge (SKILL.md) that agents will rely on. This guide focuses on how to write high-quality documentation for riglets, organized efficiently.
    
    For the structural/technical side of riglets (what goes in the Nix module, metadata fields, schema), see the riglet agent-rig-system's `SKILL.md` and `references/metadata-guide.md`.
    
    ## Core Principles
    
    ### Define the Main Intent
    
    Ask yourself: what is the end goal here? What should this riglet teach?
    The `intent` metadata is there to help you here. It should guide how you approach the writing of a riglet.
    As a reminder, the possible intents are:
    - base: "abstract" riglet (e.g. to define options) solely meant to be imported by others to factorize configuration. Cannot be disclosed in a manifest
    - sourcebook: compendium of knowledge, glossary, useful domain knowledge
    - toolbox: open-ended set of tools related together
    - cookbook: operational know-how, heuristics, tricks and techniques that are useful to apprehend an otherwise complex toolset or domain
    - playbook: specific procedure or workflow to follow in a rigorous manner
    
    A riglet should fall under **one** of these categories. If several apply, then it might be a better idea to split it into several.
    **Discuss that with your user.** Several riglets, each one with a clear focus, are better than one unorganized riglet that tries to cover everything without a real goal.
    Remember riglets can depend on each other via `imports`, so for example a very specialized "playbook" can depend on tools explained and documented in a more general "toolbox".
    
    ### Concise is Key
    
    Agents share context windows with conversation history, system instructions, and other riglets in the rig. Context is a shared resource.
    
    **Default assumption: Agents are already very capable.** Only include knowledge agents don't already have. Challenge each piece of information: "Does the agent really need this explanation?" and "Does this paragraph justify its token cost?"
    
    Prefer concrete examples over verbose explanations. Prefer links to references over embedding everything in SKILL.md.
    
    ### Set Appropriate Degrees of Freedom
    
    Match documentation specificity to the task's fragility and variability:
    
    **High freedom (general guidance)**: Use when multiple approaches are valid, decisions depend on context, or heuristics guide the process. Example: "Organizing commits in JJ" — many strategies work.
    
    **Medium freedom (documented patterns with options)**: Use when a preferred pattern exists but some variation is acceptable. Example: "Creating PDFs with Typst" — follow the basic template but customize styling.
    
    **Low freedom (specific procedures, few choices)**: Use when operations are fragile and error-prone, consistency is critical, or a specific sequence must be followed. Example: "Setting up encrypted credentials" — must follow exact steps.
    
    Think of it as a path: a narrow bridge with cliffs needs specific guardrails (low freedom, detailed steps), while an open field allows many routes (high freedom, general principles).
    
    ### Structure: Know What Goes Where
    
    Riglets have different components for different purposes:
    
    **SKILL.md** - Primary workflows and procedures
    - What: Core knowledge agents load first
    - When: Procedures, common workflows, decision trees
    - Length: ~100-150 lines ideally
    - Load cost: Loaded for every interaction
    
    **references/** - Deep knowledge, advanced topics
    - What: Advanced patterns, troubleshooting, detailed specifications
    - When: Complex scenarios, edge cases, detailed reference material
    - Length: 50-200 lines each, with TOC if >100
    - Load cost: Only loaded when agent determines it's needed
    
    **tools in Nix** - Executable packages
    - What: CLI tools, compilers, interpreters needed by the riglet
    - When: When the riglet teaches workflows that use specific tools
    - Load cost: Built into rig environment, always available
    
    Keep information in one place: SKILL.md or references, not both. Prefer references for detailed material unless it's core to the riglet—this keeps SKILL.md lean and makes information discoverable without hogging context.
    
    ## Understanding the Riglet with Concrete Examples
    
    Skip this step only when the riglet's patterns are already clearly understood.
    
    Before writing a riglet, deeply understand what it will teach. Concrete examples drive effective documentation.
    
    To create an effective riglet, clarify the scope with concrete examples:
    
    - "What workflows does this riglet enable?"
    - "What are realistic use cases?"
    - "What problems does it solve?"
    - "What would agents ask for that this riglet answers?"
    
    For example, when building a riglet about version control with JJ:
    - What functionality should it cover? (Creating changes, managing history, collaboration?)
    - Can you give concrete examples? ("I need to reorganize my commits" or "I'm collaborating with git users")
    - What would an agent say that should trigger this riglet?
    
    To avoid overwhelming agents later, ask progressively—start with the most important questions. Conclude when the riglet's scope is clear and you have concrete examples.
    
    ## Planning the Reusable Documentation Contents
    
    Transform concrete examples into effective documentation by analyzing what knowledge is needed.
    
    For each concrete example/workflow:
    
    1. **What knowledge is needed to execute it?** (procedures, patterns, concepts)
    2. **What details are essential vs. advanced?** (core flow vs. edge cases)
    3. **What reference materials would help?** (checklists, templates, troubleshooting)
    
    Example: For a JJ riglet handling "reorganizing commits":
    1. Agents need to understand: revsets, rebasing, interactive rebase workflows
    2. Essential: Basic rebase commands; Advanced: complex revset patterns
    3. Reference materials: Revset syntax guide, troubleshooting merge conflicts
    
    Example: For a PDF riglet handling "extracting tables from PDFs":
    1. Agents need: Understanding of PDF structure, table detection, format conversion
    2. Essential: Simple table extraction; Advanced: handling complex nested tables
    3. Reference materials: Format specifications, edge cases, tool limitations
    
    Example: For a Typst riglet handling "generating documents":
    1. Agents need: Typst syntax, layout patterns, styling fundamentals
    2. Essential: Basic template structure; Advanced: custom layouts and functions
    3. Tools needed: `typst` compiler, `pandoc` for format conversion
    4. Configuration: Templates for common document types
    5. Reference materials: Syntax reference, styling guide, troubleshooting layout issues
    
    From this analysis, create a list of:
    - Main sections for SKILL.md (primary workflows)
    - Reference files needed (advanced patterns, troubleshooting, checklists)
    - **Tools to include** (what agents will need to execute workflows)
    - **Configuration** (templates, pre-configured settings)
    
    ## Writing Effective SKILL.md
    
    SKILL.md is the core knowledge. Write for agent efficiency:
    
    ### Content Organization
    
    Start with **overview**:
    ```markdown
    # My Riglet
    
    This riglet teaches [what it covers].
    
    Primary use cases:
    - Use case 1
    - Use case 2
    - Use case 3
    
    See references/advanced.md for deeper patterns.
    ```
    
    Remain concise in this section, DO NOT duplicate info that is already in the `meta.description` and `meta.whenToUse`.
    
    For documentation patterns, see [patterns.md](references/patterns.md).
    
    ### Documentation Patterns
    
    For proven patterns to organize riglet documentation, see [patterns.md](references/patterns.md). It covers:
    - Sequential workflows
    - Domain-specific organization  
    - Conditional details with progressive disclosure
    - Troubleshooting-driven structures
    - Converting Skills to riglets
    
    ### Writing Guidelines
    
    **Avoid deeply nested references** - Keep reference links one level deep. All reference files should link directly from SKILL.md, not from other references.
    
    **Use imperative/infinitive form**:
    - Good: "Use jj to manage changes"
    - Avoid: "This riglet manages changes" or "JJ is a version control system"
    
    **Avoid using bold text as pseudo section headers**:
    You can go up to level 4 headers (`####`). The Rig manifest may show a table of contents of the riglets' SKILL.md files, and it detects headers starting at level 2 (`##`).
    Therefore, structuring with proper Markdown headers helps making this table of contents meaningful and evocative of what the SKILL.md will contain.
    For the same reason, do not go deeper than level 4, this would make the ToC more cluttered that it needs to.
    
    **Include concrete examples**:
    ```markdown
    Bad: You can create commits with jj.
    
    Good: To create a new commit:
      jj new -m "Add feature X"
    ```
    
    **Show expected output** when relevant:
    ```markdown
    $ jj log
    @  ckd6n8pf 2025-12-15 alice (empty) Add feature X
    ○  xzrxt9al 2025-12-15 alice Add docs
    ```
    
    **Link to references when context is available**:
    ```markdown
    For complex scenarios, see [patterns.md](references/patterns.md) or [metadata-guide.md](references/metadata-guide.md).
    ```
    
    Don't link proactively—mention references only when the agent is in a situation where they'd be relevant.
    
    **Avoid overwhelming context** - Keep SKILL.md to ~100 lines. Extended explanations belong in reference files.
    
    **Use relative paths for references** - All paths are relative to the file mentioning them: `[patterns.md](references/patterns.md)`
    
    ## What Goes Where: SKILL.md vs References
    
    **Keep in SKILL.md:**
    - Primary workflows and procedures agents will use most
    - Common decision trees ("If X, then do Y")
    - Essential concepts agents need to understand the workflows
    - Links to reference files (but not the detailed content itself)
    
    **Move to references:**
    - Advanced patterns and edge cases
    - Detailed specifications and schemas
    - Troubleshooting guides
    - Code examples longer than 10 lines
    - Domain knowledge only needed for specific scenarios
    - Detailed API or command documentation
    
    **Rule of thumb:** Information should live in SKILL.md OR references, not both. Information repetition wastes token budget.
    
    When you find yourself writing "For more details, see..." you've found something that belongs in a reference file.
    
    ## Organizing Reference Files
    
    Reference files provide depth without bloating SKILL.md.
    
    ### Design Principle: One Level Deep
    
    Keep all references one level deep from SKILL.md. References should not link to other references.
    
    Good:
    ```
    SKILL.md → references/advanced.md
    SKILL.md → references/troubleshooting.md
    ```
    
    Avoid:
    ```
    SKILL.md → references/patterns.md → references/patterns-detailed.md
    ```
    
    Why? Agents need to understand the full scope of what's available. If references link to other references, the structure becomes opaque and agents might miss information.
    
    ### Structure Longer References
    
    For reference files longer than ~100 lines, include a table of contents so agents can see the full scope when previewing:
    
    ```markdown
    # Advanced JJ Patterns
    
    ## Table of Contents
    
    - Revset Syntax (line 10)
    - Interactive Rebase (line 45)
    - Conflict Resolution (line 80)
    - Undoing Changes (line 120)
    
    ## Revset Syntax
    
    ...
    ```
    
    This lets agents understand the file's full scope without reading all of it, helping them decide if they need to load it.
    
    ### Naming conventions
    
    Use clear, specific names:
    - `advanced.md` - Advanced patterns in the main topic
    - `troubleshooting.md` - Common problems and solutions
    - `checklists.md` - Reusable checklists
    - `domain-name.md` - Domain-specific knowledge (for multi-domain riglets)
    - `syntax-reference.md` - Detailed syntax specifications
    
    ## Packaging Custom Tools or Scripts with Riglets
    
    Operations that are expected to be commonly performed when using the riglet can and probably SHOULD be provided as helper scripts.
    It's Nix, so tools can be created on the fly and properly packaged with the usual builders like `writeShellScriptBin`, `writeShellApplication` or even `stdenv.mkDerivation`, but riglets have a simple option for simple cases.
    
    ### Simple cases: write local scripts and list paths in `tools`
    
    The `tools` field supports direct file paths to scripts, which are automatically wrapped as executable packages:
    
    **How it works:**
    - Script paths (e.g., `./scripts/helper[.sh]`) are detected and wrapped using `writeShellScriptBin`
    - Final executable name is derived from filename (with extension if it has any, so prefer without extensions)
    - Scripts become available in the rig's `bin/` directory alongside other tools
    
    **This is intended ONLY for SIMPLE sh or bash scripts which have NO DEPENDENCIES besides what is already listed in `tools`** (as they will be together in `$PATH` once the rig is built).
    
    **Example directory-based riglet with scripts:**
    ````nix
    _:
    { pkgs, riglib, ... }: {
      config.riglets.my-riglet = {
        tools = [
          pkgs.jujutsu
          ./scripts/jj-desc-read  # → executable "jj-desc-read"
          ./scripts/jj-desc-edit  # → executable "jj-desc-edit"
        ];
    
        docs = riglib.writeFileTree {
          "SKILL.md" = ''
            # My Riglet
    
            ## Utility Scripts
    
            **Read a revision:**
            ```bash
            jj-desc-read @
            ```
    
            **Edit description programmatically:**
            ```bash
            jj-desc-edit sed 's/foo/bar/g'
            ```
          '';
        };
    
        meta = {
          name = "My Riglet";
          description = "JJ utilities with helper scripts";
          # ... other metadata
        };
      };
    }
    ````
    
    **Directory structure:**
    ```
    riglets/my-riglet/
    ├── default.nix
    └── scripts/
        ├── jj-desc-read
        └── jj-desc-edit
    ```
    
    ### Advanced cases: make a custom tool via a custom derivation
    
    For cases when you need more control over the packaging of the tools, consider the usual Nix builders from nixpkgs.
    
    `writeShellApplication` e.g. can package an inlined script with its dependencies:
    
    ```nix
    writeShellApplication {
      name = "show-nixos-org";
    
      runtimeInputs = [
        curl
        w3m
      ];
    
      text = ''
        curl -s 'https://nixos.org' | w3m -dump -T text/html
      '';
    }
    ```
    
    For instance, if you want to include a Python script to the riglet, package it properly with `buildPythonApplication` so ALL its dependencies are present.
    
    #### Language-specific packaging guides
    
    See the references directory for detailed guides on packaging tools in specific languages:
    - [Python](references/packaging-python.md) - `buildPythonApplication` and modern `pyproject.toml` support
    - [Node.js/JavaScript](references/packaging-nodejs.md) - `buildNpmPackage` for npm-based projects
    - [Rust](references/packaging-rust.md) - `buildRustPackage` with `cargoHash` or `Cargo.lock`
    - [Go](references/packaging-go.md) - `buildGoModule` with `vendorHash`
    - [Haskell](references/packaging-haskell.md) - `haskellPackages.developPackage` and `callCabal2nix`
    - [Ruby](references/packaging-ruby.md) - `bundlerApp` and `bundlerEnv` for gems
    - [Java/Kotlin](references/packaging-java-kotlin.md) - `buildMavenPackage` and Gradle approaches
    
    #### About external package-managers (uv, npm...)
    
    If the riglet assumes that Python scripting will have to be done **manually** as part of **executing the riglet's instructions**, then prefer relying on `uvx` (provided through `tools = [ pkgs.uv ... ]`) and including usage instructions in the riglet's docs. Same goes for JS/TS with `npx`, etc.
    
    **But** in such case DO:
    - include a proper `pyproject.toml`/`package.json`/etc. as an asset file (`<riglet-folder>/assets/<foo>/pyproject.toml`)
    - refer to it in the main riglet's doc
    - **MAKE SURE it is packaged via the `docs` of the riglet** (either as part of a path to a folder, or as an arg to `riglib.writeFileTree`)
    
    The GOLDEN RULE is: **users of a riglet must NEVER have to install ANYTHING globally on their system to use this riglet!!**.
    This is why use of `uvx`, `npx`, etc (i.e. anything installing packages in a **project-scoped** fashion) is tolerated, but `pip install` **IS NOT**.
    
    However **whenever you can**, proper packaging of ALL dependencies, packages etc. through Nix is **always** preferable to enable easy one-command installation of the whole rig.
    
    ## The Riglet Creation Process
    
    Putting it all together:
    
    1. **Understand** with concrete examples (5-10 min)
       - What workflows? What problems? What would agents ask for?
    
    2. **Plan** the documentation structure (5-10 min)
       - Which sections for SKILL.md?
       - Which topics need reference files?
       - Any assets or templates?
    
    3. **Write SKILL.md** with primary workflows (20-30 min)
       - Overview
       - 3-5 core workflows with concrete examples
       - Links to reference files
    
    4. **Write reference files** for advanced topics (10-20 min per reference)
       - Advanced patterns
       - Troubleshooting
       - Detailed specifications
    
    5. **Test with real tasks** (10+ min)
       - Use the riglet for actual work
       - Notice gaps or confusion
       - Update SKILL.md or references
    
    6. **Iterate** based on usage
       - Clarify confusing sections
       - Add missing workflows
       - Reorganize if structure isn't working
    
    ## Quality Checklist
    
    Before considering documentation complete:
    
    - [ ] **SKILL.md exists** and covers primary workflows
    - [ ] **Concrete examples** throughout (commands, output, use cases)
    - [ ] **No jargon without explanation** - define domain terms
    - [ ] **Links to references** mentioned naturally (not exhaustively)
    - [ ] **Reference files** structured with TOC if >100 lines
    - [ ] **Relative paths** all correct (tested from the docs directory)
    - [ ] **No unreferenced tools** - everything mentioned has a link or exists in the rig
    - [ ] **Tested in practice** - actually used for real workflows
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related