claude-forgejo-sandbox/packages/reforge-scripts.nix
Padreug df0fd9a9ba feat: extract reforge engine into a standalone consumable flake
The forgejo-sandbox / reforge harness, lifted out of the machine config
into a host-agnostic, generic engine anyone can consume with Nix.

Two layers:
- engine (this repo) — nixosModules.reforge stands up the sandbox forge,
  provisions role accounts + tokens, enforces branch protection, and puts
  the reforge-* CLI + forgejo-mcp on PATH. Carries no project specifics.
- run config — per-project manifest/charter/agenda/issues an adopter fills
  in; scaffold one with the `reforge` flake template.

Portability fixes vs the in-config version:
- forgejo-mcp resolved from $REFORGE_MCP_BIN or PATH, never a named host
  (kills the nixosConfigurations.omni hardcode).
- all instance data + paths parameterized via REFORGE_* env, baked into the
  reforge-scripts wrappers from module options (configDir, agentsDir,
  refsDir, org, port, tokenOwner, ...).
- option namespace neutral (reforge.* not omni.packs.*); settings policies
  carry no absolute /etc/nixos paths.
- role briefs + orchestrator playbook genericized: all project specifics
  point at the charter; refs corpus optional.

Validated: nix flake check (eval) + builds of forgejo-mcp, reforge-scripts,
and a module-eval check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 22:51:47 +02:00

103 lines
2.8 KiB
Nix

# packages/reforge-scripts.nix
#
# The reforge-* operator CLI: the lifecycle scripts (scripts/*.sh) wrapped
# as `reforge-<name>` commands with this host's defaults baked in as
# REFORGE_* environment variables, plus the runtime tools they need on
# PATH. Every default is overridable per-invocation by exporting the
# matching REFORGE_* variable before running.
#
# The engine's generic agent briefs (agents/) and permission policies
# (scripts/settings/) are shipped under $out/share/reforge and referenced
# by default; override with agentsDir / REFORGE_AGENTS_DIR to customize the
# role framing for your project.
{
lib,
stdenvNoCC,
makeWrapper,
bash,
coreutils,
git,
curl,
jq,
gnugrep,
gawk,
gnused,
openssh,
gnutar,
gzip,
findutils,
# env defaults (supplied by modules/reforge.nix from its options)
forgejoMcp,
forgeUrl,
org,
adminUser,
tokensDir,
stateDir,
configDir,
agentsDir ? null,
refsDir ? null,
}:
let
scriptsDir = ../scripts;
runtimePath = lib.makeBinPath [
bash
coreutils
git
curl
jq
gnugrep
gawk
gnused
openssh
gnutar
gzip
findutils
];
in
stdenvNoCC.mkDerivation {
pname = "reforge-scripts";
version = "0.1.0";
dontUnpack = true;
nativeBuildInputs = [ makeWrapper ];
installPhase = ''
runHook preInstall
mkdir -p $out/bin $out/share/reforge
cp -r ${../scripts/settings} $out/share/reforge/settings
cp -r ${../agents} $out/share/reforge/agents
AGENTS=${
if agentsDir != null then lib.escapeShellArg (toString agentsDir) else "$out/share/reforge/agents"
}
SETTINGS=$out/share/reforge/settings
for f in ${scriptsDir}/*.sh; do
name=$(basename "$f" .sh)
makeWrapper ${bash}/bin/bash "$out/bin/$name" \
--add-flags "$f" \
--prefix PATH : "${runtimePath}" \
--set-default REFORGE_MCP_BIN ${forgejoMcp}/bin/forgejo-mcp \
--set-default REFORGE_FORGE_URL ${lib.escapeShellArg forgeUrl} \
--set-default REFORGE_ORG ${lib.escapeShellArg org} \
--set-default REFORGE_ADMIN_USER ${lib.escapeShellArg adminUser} \
--set-default REFORGE_TOKENS_DIR ${lib.escapeShellArg tokensDir} \
--set-default REFORGE_STATE_DIR ${lib.escapeShellArg stateDir} \
--set-default REFORGE_CONFIG_DIR ${lib.escapeShellArg (toString configDir)} \
--set-default REFORGE_SETTINGS_DIR "$SETTINGS" \
--set-default REFORGE_AGENTS_DIR "$AGENTS" \
${lib.optionalString (
refsDir != null
) "--set-default REFORGE_REFS_DIR ${lib.escapeShellArg (toString refsDir)}"}
done
runHook postInstall
'';
meta = with lib; {
description = "reforge lifecycle CLI (seed/reset/compare/smoke/kickoff/role/orchestrator/fetch-targets)";
mainProgram = "reforge-seed";
license = licenses.mit;
};
}