~ruther/agent-environments

275d15626d29b383a1cdad7ef6bf656bf66fc630 — František Boháček 2 months ago 584ddbf
Add example consumer flakes
A examples/basic/flake.nix => examples/basic/flake.nix +74 -0
@@ 0,0 1,74 @@
{
  description = "agent-environments example: one environment with instructions and skills";

  inputs = {
    # In your own flake: github:<owner>/agent-environments
    agent-environments.url = "path:../..";
    nixpkgs.follows = "agent-environments/nixpkgs";
  };

  outputs =
    { agent-environments, nixpkgs, ... }:
    let
      forAllSystems = nixpkgs.lib.genAttrs [
        "x86_64-linux"
        "aarch64-linux"
        "x86_64-darwin"
        "aarch64-darwin"
      ];
      inherit (agent-environments.lib) mkEnvironment mkSkill mkSkillModule;
    in
    {
      packages = forAllSystems (
        system:
        let
          pkgs = nixpkgs.legacyPackages.${system};

          ripgrep-search = mkSkill {
            inherit pkgs;
            name = "ripgrep-search";
            src = ./skills/ripgrep-search;
            runtimeInputs = [ pkgs.ripgrep ];
          };
          # Depends on ripgrep-search: enabling code-review links both skills.
          code-review = mkSkill {
            inherit pkgs;
            name = "code-review";
            src = ./skills/code-review;
            skills = [ ripgrep-search ];
          };

          env = mkEnvironment {
            inherit pkgs;
            modules = [
              (mkSkillModule ripgrep-search)
              (mkSkillModule code-review)
              {
                claude.enable = true;
                codex.enable = true;

                modules.skills.code-review.enable = true;

                instructions.style.text = ''
                  # Style
                  - Prefer small, focused commits.
                  - Explain *why* in commit messages.
                '';

                claude.settings.includeCoAuthoredBy = false;
                codex.settings.approval_policy = "on-request";

                launchers = {
                  claude-basic.agent = "claude";
                  codex-basic.agent = "codex";
                };
              }
            ];
          };
        in
        {
          default = env.package;
        }
      );
    };
}

A examples/basic/skills/code-review/SKILL.md => examples/basic/skills/code-review/SKILL.md +11 -0
@@ 0,0 1,11 @@
---
name: code-review
description: Use when asked to review a change - a checklist for correctness-first reviews.
---

# Code review

1. Read the diff, then find the callers of every changed function
   (see the ripgrep-search skill).
2. Look for correctness bugs first, style issues last.
3. Report each finding with a file, a line and a concrete failure scenario.

A examples/basic/skills/ripgrep-search/SKILL.md => examples/basic/skills/ripgrep-search/SKILL.md +11 -0
@@ 0,0 1,11 @@
---
name: ripgrep-search
description: Use when searching a codebase for symbols, strings or files - covers fast ripgrep invocations.
---

# Searching with ripgrep

- `rg -n 'pattern'` searches recursively and prints line numbers.
- `rg -l 'pattern'` lists only the matching files.
- `rg --files -g '*.nix'` lists files by glob without searching their contents.
- `rg -w name` matches whole words only.

A examples/multi-account/flake.nix => examples/multi-account/flake.nix +84 -0
@@ 0,0 1,84 @@
{
  description = "agent-environments example: several logins and several environments";

  inputs = {
    # In your own flake: github:<owner>/agent-environments
    agent-environments.url = "path:../..";
    nixpkgs.follows = "agent-environments/nixpkgs";
  };

  outputs =
    { agent-environments, nixpkgs, ... }:
    let
      forAllSystems = nixpkgs.lib.genAttrs [
        "x86_64-linux"
        "aarch64-linux"
        "x86_64-darwin"
        "aarch64-darwin"
      ];
      inherit (agent-environments.lib) mkEnvironment;

      # Shared by both environments.
      common = {
        claude.enable = true;
        instructions.common.text = ''
          Always run the test suite before claiming a task is done.
        '';
      };
    in
    {
      packages = forAllSystems (
        system:
        let
          pkgs = nixpkgs.legacyPackages.${system};

          # One environment, three launchers. Each launcher id gets its own state
          # dir (~/.local/agent-environments/<id>), so each one logs in separately.
          main = mkEnvironment {
            inherit pkgs;
            modules = [
              common
              {
                codex.enable = true;
                launchers = {
                  claude-work-acc.agent = "claude";
                  claude-pers-acc.agent = "claude";
                  codex-work-acc.agent = "codex";
                };
              }
            ];
          };

          # A different set of modules with its own launcher and login.
          review = mkEnvironment {
            inherit pkgs;
            modules = [
              common
              {
                instructions.review = {
                  order = 2000;
                  text = "You only review code. Never edit files.";
                };
                claude.settings.permissions.deny = [
                  "Edit"
                  "Write"
                ];
                launchers.claude-review.agent = "claude";
              }
            ];
          };
        in
        {
          main = main.package;
          review = review.package;
          default = pkgs.symlinkJoin {
            name = "agent-environments";
            paths = [
              main.package
              review.package
            ];
          };
        }
      );
    };
}