feat(deployment): Add support for Gemini and Codex
- RFC-MULTI-AGENT-DEPLOYMENT.md: Design for unified deployment - modules/ai-skills.nix: Added geminiSkills option - bin/use-skills.sh: Added GEMINI_HOME support - bin/deploy-skill.sh: Inject configs for Codex and Gemini
This commit is contained in:
parent
9669f473b3
commit
84d2de1683
62
RFC-MULTI-AGENT-DEPLOYMENT.md
Normal file
62
RFC-MULTI-AGENT-DEPLOYMENT.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# RFC: Multi-Agent Skill Deployment
|
||||
|
||||
**Status:** Draft
|
||||
**Date:** 2026-01-19
|
||||
**Author:** Gemini CLI Agent
|
||||
|
||||
## Context
|
||||
|
||||
This repository (`~/proj/skills`) is the single source of truth for AI capabilities. However, the runtime environment has fragmented into four distinct agents:
|
||||
|
||||
1. **Claude Code** (The original consumer)
|
||||
2. **OpenCode** (The open-source alternative)
|
||||
3. **OpenAI Codex** (The specialized coding agent)
|
||||
4. **Gemini CLI** (The interactive shell agent)
|
||||
|
||||
Currently, our deployment script only targets Claude and OpenCode.
|
||||
|
||||
## The Goal: "Write Once, Deploy Everywhere"
|
||||
|
||||
We want a single command (`./bin/deploy-skill.sh <skill>`) to make that skill available to ALL agents on the system immediately after a system rebuild.
|
||||
|
||||
## Target Paths
|
||||
|
||||
| Agent | Config File (Dotfiles) | Target Path (Runtime) |
|
||||
|-------|------------------------|-----------------------|
|
||||
| **Claude Code** | `home/claude.nix` | `~/.claude/skills/<name>` |
|
||||
| **OpenCode** | `home/opencode.nix` | `~/.config/opencode/skills/<name>` |
|
||||
| **OpenAI Codex** | `home/codex.nix` | `~/.codex/skills/<name>` |
|
||||
| **Gemini CLI** | `home/gemini.nix` | `~/.gemini/skills/<name>` |
|
||||
|
||||
## Proposed Changes
|
||||
|
||||
### 1. Update `bin/deploy-skill.sh`
|
||||
|
||||
The script currently injects config into `claude.nix` and `opencode.nix`. We will expand it to also check for and inject into `codex.nix` and `gemini.nix` if they exist in the dotfiles repo.
|
||||
|
||||
**Logic:**
|
||||
```bash
|
||||
# For each agent target:
|
||||
inject_home_file "$DOTFILES/home/codex.nix" ".codex/skills/$SKILL" ...
|
||||
inject_home_file "$DOTFILES/home/gemini.nix" ".gemini/skills/$SKILL" ...
|
||||
```
|
||||
|
||||
### 2. Standardize Skill Format
|
||||
|
||||
Fortunately, all four agents share the same fundamental skill interface:
|
||||
* **Definition:** `SKILL.md` (Markdown with Frontmatter)
|
||||
* **Execution:** Bash scripts (via `run_shell_command` or similar)
|
||||
|
||||
No changes are needed to the skill format itself, provided we stick to standard POSIX bash and relative paths in scripts.
|
||||
|
||||
## Benefits
|
||||
|
||||
* **Unified Capability:** Fixing a bug in `git-commit` skill fixes it for Gemini, Claude, and Codex simultaneously.
|
||||
* **Agent Agnosticism:** You can switch agents mid-task without losing access to your tools.
|
||||
* **Testing:** You can verify a skill using Gemini (cheaper/faster) before using it with Claude (smarter/expensive).
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
1. Update `bin/deploy-skill.sh` to support the new targets.
|
||||
2. Create placeholder `home/codex.nix` and `home/gemini.nix` in dotfiles (if missing) to test injection.
|
||||
3. Deploy a test skill (`verify-work`) to all 4 targets.
|
||||
|
|
@ -201,7 +201,25 @@ inject_home_file "$DOTFILES_REPO/home/opencode.nix" \
|
|||
"recursive = true;" \
|
||||
"$SKILL_NAME"
|
||||
|
||||
# 3. Antigravity / Global Config
|
||||
# 3. Codex Config (if home/codex.nix exists)
|
||||
if [[ -f "$DOTFILES_REPO/home/codex.nix" ]]; then
|
||||
inject_home_file "$DOTFILES_REPO/home/codex.nix" \
|
||||
".codex/skills/$SKILL_NAME" \
|
||||
"../claude/skills/$SKILL_NAME" \
|
||||
"recursive = true;" \
|
||||
"$SKILL_NAME"
|
||||
fi
|
||||
|
||||
# 4. Gemini Config (if home/gemini.nix exists)
|
||||
if [[ -f "$DOTFILES_REPO/home/gemini.nix" ]]; then
|
||||
inject_home_file "$DOTFILES_REPO/home/gemini.nix" \
|
||||
".gemini/skills/$SKILL_NAME" \
|
||||
"../claude/skills/$SKILL_NAME" \
|
||||
"recursive = true;" \
|
||||
"$SKILL_NAME"
|
||||
fi
|
||||
|
||||
# 5. Antigravity / Global Config
|
||||
# Check if antigravity.nix exists, otherwise warn
|
||||
ANTIGRAVITY_NIX="$DOTFILES_REPO/home/antigravity.nix"
|
||||
if [[ -f "$ANTIGRAVITY_NIX" ]]; then
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ set -euo pipefail
|
|||
|
||||
# Default to per-repo Codex skills unless overridden by the caller.
|
||||
export CODEX_HOME="${CODEX_HOME:-$PWD/.codex}"
|
||||
export GEMINI_HOME="${GEMINI_HOME:-$PWD/.gemini}"
|
||||
|
||||
# Ensure global auth is available in per-repo CODEX_HOME to prevent login resets
|
||||
if [[ -n "${CODEX_HOME:-}" && -f "$HOME/.codex/auth.json" ]]; then
|
||||
|
|
@ -43,6 +44,10 @@ use_skill() {
|
|||
mkdir -p "${CODEX_HOME}/skills"
|
||||
ln -sfn "$out" "${CODEX_HOME}/skills/${skill}"
|
||||
fi
|
||||
if [[ -n "${GEMINI_HOME:-}" ]]; then
|
||||
mkdir -p "${GEMINI_HOME}/skills"
|
||||
ln -sfn "$out" "${GEMINI_HOME}/skills/${skill}"
|
||||
fi
|
||||
echo "use_skill: ${skill}"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,13 @@ in {
|
|||
example = [ "worklog" "hq" ];
|
||||
};
|
||||
|
||||
geminiSkills = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = "Skills to deploy to Gemini CLI (~/.gemini/skills/). ${skillsList}";
|
||||
example = [ "worklog" "web-search" ];
|
||||
};
|
||||
|
||||
# Lenses for orch multi-model review
|
||||
enableLenses = mkOption {
|
||||
type = types.bool;
|
||||
|
|
@ -53,12 +60,6 @@ in {
|
|||
description = "Deploy review lenses to ~/.config/lenses/";
|
||||
};
|
||||
|
||||
# Workflows (beads protos)
|
||||
enableWorkflows = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Deploy workflow protos to ~/.beads/molecules.jsonl";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
|
@ -102,6 +103,19 @@ in {
|
|||
)
|
||||
))
|
||||
|
||||
# Gemini skills
|
||||
(mkIf (cfg.geminiSkills != []) (
|
||||
builtins.listToAttrs (
|
||||
map (skillName: {
|
||||
name = ".gemini/skills/${skillName}";
|
||||
value = {
|
||||
source = "${cfg.skillsPath}/${skillName}";
|
||||
recursive = true;
|
||||
};
|
||||
}) cfg.geminiSkills
|
||||
)
|
||||
))
|
||||
|
||||
# Lenses for orch (separate subdirectories per skill)
|
||||
(mkIf cfg.enableLenses {
|
||||
".config/lenses/code" = {
|
||||
|
|
@ -114,12 +128,6 @@ in {
|
|||
};
|
||||
})
|
||||
|
||||
# Workflows (beads protos)
|
||||
(mkIf cfg.enableWorkflows {
|
||||
".beads/molecules.jsonl" = {
|
||||
source = "${repoRoot}/workflows/molecules.jsonl";
|
||||
};
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue