From 35ce6be8f9ce9c977f56cba527114d660665d944 Mon Sep 17 00:00:00 2001 From: Jelle Spreeuwenberg Date: Wed, 9 Sep 2026 17:31:25 +0200 Subject: [PATCH] feat: add agent session tooling and shared skills Install agent-deck and tmux, wire Codex notifications and hooks, and expose shared Context7/NixOS skills plus the Nix-managed Ponytail plugin marketplace. Preserve the accumulated input updates, including the older Elephant revision; its rollback rationale was not recorded. Flake evaluation passed; no activation or agent-session pilot performed during cleanup. --- flake.lock | 67 ++++++++++++------- flake.nix | 4 ++ modules/capabilities/ai.nix | 30 ++++++++- .../capabilities/skills/context7-mcp/SKILL.md | 56 ++++++++++++++++ 4 files changed, 131 insertions(+), 26 deletions(-) create mode 100644 modules/capabilities/skills/context7-mcp/SKILL.md diff --git a/flake.lock b/flake.lock index b920c0b..b085be2 100644 --- a/flake.lock +++ b/flake.lock @@ -66,11 +66,11 @@ ] }, "locked": { - "lastModified": 1784365424, - "narHash": "sha256-kJO1Tww/GkvLq5amrV4BKidYGr5YumM+cH/xYALAiw4=", + "lastModified": 1775706155, + "narHash": "sha256-h7Rw0vlb0n0Jsk21WJPm7H+1T1bG+PEuxE5cJ2TZl8A=", "owner": "abenz1267", "repo": "elephant", - "rev": "23f37238367355cf46843015ad5e94706200176a", + "rev": "376ee71c66db38683daabd57350bf3f6f086eaf8", "type": "github" }, "original": { @@ -125,11 +125,11 @@ ] }, "locked": { - "lastModified": 1788487777, - "narHash": "sha256-Ro/e1N4ZR8/XaFF+sF9SgfPK79HM5YNEppzFj8p+0Ak=", + "lastModified": 1788651960, + "narHash": "sha256-v9wJd32eZ2bvhBzVOd7TIjLQd011P7nwOhjKtWlci5I=", "owner": "nix-community", "repo": "home-manager", - "rev": "693e8ce0fb240a73c116a03cfd7b19269c87af88", + "rev": "2c0350c759688177331b8f5242311fae8877bdb3", "type": "github" }, "original": { @@ -164,11 +164,11 @@ "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1788602747, - "narHash": "sha256-WsI2ZhA2Gv/1pSYcovj7kbikl4hfuJmFPb0GK1Nfpzo=", + "lastModified": 1788858717, + "narHash": "sha256-lNh6z7qJ35S8msz4kH3xNxXTN7PLENpesL5LatpNBGA=", "owner": "numtide", "repo": "llm-agents.nix", - "rev": "9cd345e386f30d746cf763343de805f283068649", + "rev": "30e001e67438ab6ba024fa8d4f2e9be0ba7548af", "type": "github" }, "original": { @@ -184,11 +184,11 @@ ] }, "locked": { - "lastModified": 1788080100, - "narHash": "sha256-n14luQo3F/ZLfCEHk1QieiI1nGnW92ZQZeZ0UIb0UMQ=", + "lastModified": 1788680125, + "narHash": "sha256-amGSoDobwmp4CFvCn841ws2iuitus+HUJdD/gKgsrJA=", "owner": "nix-community", "repo": "nix-index-database", - "rev": "dbb978fa87faf13398e90ccbc52c343d21c7dd6d", + "rev": "116ad1c2adb642405ef8916f6a94c8626f971344", "type": "github" }, "original": { @@ -204,11 +204,11 @@ ] }, "locked": { - "lastModified": 1788546427, - "narHash": "sha256-vOgWUFj6iCUi9p0+jEBi4cM6vcQsaBujYOBCw1ALVUs=", + "lastModified": 1788744583, + "narHash": "sha256-oNMrijfyaoRjjWhxHNFSBYyEB4u/zb/AxoKewC56LvE=", "owner": "BirdeeHub", "repo": "nix-wrapper-modules", - "rev": "7f7c780597c2dc595d5db7eaffd7387b417e1eb5", + "rev": "e88c449105c6aafa460196d3cbd16718655aee0f", "type": "github" }, "original": { @@ -224,11 +224,11 @@ ] }, "locked": { - "lastModified": 1788335262, - "narHash": "sha256-3jBEq8avfzlrsY4UpW4d5TOmm7ocseZfnitEJhqauyc=", + "lastModified": 1788860136, + "narHash": "sha256-MhPMOFV4pVkygWEbQ8t1De/uQ9cWF1u++tRe2L5tG48=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "44d95795ee2d475b3d687325e26dcf4ca9104557", + "rev": "62173785b9a18c78b4a15aca2623d02bceb9d077", "type": "github" }, "original": { @@ -240,11 +240,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1788400875, - "narHash": "sha256-v4ZEET1Ah1K9+wMaIwPH/JTQK3MwW/gZC/SyjnlBX74=", - "rev": "5545adfad2e98de106a5544ca7067e03010410bd", + "lastModified": 1788834054, + "narHash": "sha256-kkWAS4mE+fmi+u3mxwD9/bfX6DGJ49Tv8O9kzN5r0HQ=", + "rev": "e9b9cbecbf6c25ca26c150d78570e6332694a129", "type": "tarball", - "url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.11pre1066699.5545adfad2e9/nixexprs.tar.xz" + "url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.11pre1069601.e9b9cbecbf6c/nixexprs.tar.xz" }, "original": { "type": "tarball", @@ -273,11 +273,11 @@ ] }, "locked": { - "lastModified": 1788600693, - "narHash": "sha256-rFFsGcRc7B1GdwpFk/2VCSWL+vpMXi8EFgmWuKJd9I0=", + "lastModified": 1788886125, + "narHash": "sha256-5rgQFUGr8GXYyyuy8ynrN39WfZzSiO/wqGWjELBOkEY=", "owner": "noctalia-dev", "repo": "noctalia", - "rev": "f81c030d6403edeaae1a0953ee60ad43f334e300", + "rev": "d6607b4eafbb92f6d494ebed3e296d4b741c0b58", "type": "github" }, "original": { @@ -286,6 +286,22 @@ "type": "github" } }, + "ponytail": { + "flake": false, + "locked": { + "lastModified": 1788798420, + "narHash": "sha256-LPNMyHsri3+eeDmphEAKL1JgoRE4dLIPfZ4XZ+xu5UY=", + "owner": "DietrichGebert", + "repo": "ponytail", + "rev": "356918eba965ee1eac64bd3a7f0dd02108350de5", + "type": "github" + }, + "original": { + "owner": "DietrichGebert", + "repo": "ponytail", + "type": "github" + } + }, "root": { "inputs": { "disko": "disko", @@ -298,6 +314,7 @@ "nixos-hardware": "nixos-hardware", "nixpkgs": "nixpkgs", "noctalia": "noctalia", + "ponytail": "ponytail", "sops-nix": "sops-nix", "walker": "walker" } diff --git a/flake.nix b/flake.nix index 9b14c35..39e5a9e 100644 --- a/flake.nix +++ b/flake.nix @@ -29,6 +29,10 @@ url = "github:noctalia-dev/noctalia"; inputs.nixpkgs.follows = "nixpkgs"; }; + ponytail = { + url = "github:DietrichGebert/ponytail"; + flake = false; + }; sops-nix = { url = "github:Mic92/sops-nix"; inputs.nixpkgs.follows = "nixpkgs"; diff --git a/modules/capabilities/ai.nix b/modules/capabilities/ai.nix index 0b6d072..c7704b7 100644 --- a/modules/capabilities/ai.nix +++ b/modules/capabilities/ai.nix @@ -25,6 +25,11 @@ in plan_mode_reasoning_effort = "high"; service_tier = "default"; approvals_reviewer = "auto_review"; + features.hooks = true; + notify = [ + "${pkgs.llm-agents.agent-deck}/bin/agent-deck" + "codex-notify" + ]; tui = { status_line = [ @@ -109,7 +114,9 @@ in pkgs.llm-agents.codex pkgs.llm-agents.pi pkgs.llm-agents.claude-code + pkgs.llm-agents.agent-deck pkgs.llm-agents.herdr + pkgs.tmux pkgs.ctx7 ]; @@ -156,6 +163,27 @@ in be modified as authorized. ''; - home.file.".codex/skills/nixos-maintainer".source = ./skills/nixos-maintainer; + home.file = { + ".agents/plugins/marketplace.json".text = builtins.toJSON { + name = "nix-managed"; + plugins = [ + { + name = "ponytail"; + source = { + source = "local"; + path = "./.codex/plugins/ponytail"; + }; + policy = { + installation = "AVAILABLE"; + authentication = "ON_INSTALL"; + }; + category = "Productivity"; + } + ]; + }; + ".agents/skills/context7-mcp".source = ./skills/context7-mcp; + ".agents/skills/nixos-maintainer".source = ./skills/nixos-maintainer; + ".codex/plugins/ponytail".source = inputs.ponytail; + }; }; } diff --git a/modules/capabilities/skills/context7-mcp/SKILL.md b/modules/capabilities/skills/context7-mcp/SKILL.md new file mode 100644 index 0000000..245b080 --- /dev/null +++ b/modules/capabilities/skills/context7-mcp/SKILL.md @@ -0,0 +1,56 @@ +--- +name: context7-mcp +description: This skill should be used when the user asks about libraries, frameworks, API references, or needs code examples. Activates for setup questions, code generation involving libraries, or mentions of specific frameworks like React, Vue, Next.js, Prisma, Supabase, etc. +--- + +When the user asks about libraries, frameworks, or needs code examples, use Context7 to fetch current documentation instead of relying on training data. + +## When to Use This Skill + +Activate this skill when the user: + +- Asks setup or configuration questions ("How do I configure Next.js middleware?") +- Requests code involving libraries ("Write a Prisma query for...") +- Needs API references ("What are the Supabase auth methods?") +- Mentions specific frameworks (React, Vue, Svelte, Express, Tailwind, etc.) + +## How to Fetch Documentation + +### Step 1: Resolve the Library ID + +Call `resolve-library-id` with: + +- `libraryName`: The library name extracted from the user's question +- `query`: The user's full question (improves relevance ranking) + +### Step 2: Select the Best Match + +From the resolution results, choose based on: + +- Exact or closest name match to what the user asked for +- Higher benchmark scores indicate better documentation quality +- If the user mentioned a version (e.g., "React 19"), prefer version-specific IDs + +### Step 3: Fetch the Documentation + +Call `query-docs` with: + +- `libraryId`: The selected Context7 library ID (e.g., `/vercel/next.js`) +- `query`: The user's specific question, scoped to a single concept + +If the user's question spans multiple distinct concepts (e.g. routing and auth and caching), make a separate `query-docs` call per concept with the same library ID, unless the question is about how the concepts interact — combined queries dilute ranking and return shallow results for each topic. + +### Step 4: Use the Documentation + +Incorporate the fetched documentation into your response: + +- Answer the user's question using current, accurate information +- Include relevant code examples from the docs +- Cite the library version when relevant + +## Guidelines + +- **Be specific**: Pass the user's full question as the query for better results, but keep each query to a single concept +- **One topic per query**: Split multi-topic questions into separate `query-docs` calls — resolve the library ID once, then query per concept, unless the question is about how the concepts interact +- **Version awareness**: When users mention versions ("Next.js 15", "React 19"), use version-specific library IDs if available from the resolution step +- **Prefer official sources**: When multiple matches exist, prefer official/primary packages over community forks