Files
project-orchestrator/scripts/create-project.sh
autonomic-bot 346ed31acb feat: project-orchestrator — engine@v0.1.0 submodule, PO config, fleet.toml registry, mgmt scripts, docs, Nix
The PO is itself a project using the agent-orchestrator harness (engine/ submodule pinned at
v0.1.0). Adds: agents.toml (one persistent fleet-management agent) + prompts/; fleet.toml (the
sole project<->harness<->ref registry) + docs/fleet-registry.md; scripts/ (fleet.py +
create/start/stop/update-project.sh); docs/manage-projects.md + docs/bootstrap.md; flake.nix/.lock
devShell (python311+tmux+git); README.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 19:15:47 +00:00

118 lines
4.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# create-project.sh — scaffold a NEW project that uses a harness.
#
# Produces a self-contained project repo: the chosen harness vendored as the `engine/` submodule at
# a pinned ref, plus a harness config scaffolded by the harness's own `init`. The project contains
# NO project-orchestrator / fleet metadata — knowledge is one-directional (PO → project). Registering
# the project in the PO's fleet.toml is a SEPARATE, PO-side step (use --register, or edit fleet.toml
# by hand); nothing about the fleet ever lands inside the project repo.
#
# Usage:
# scripts/create-project.sh <name> [options]
#
# Options:
# --dir <parent> parent directory to create the project under (default: ./projects)
# --engine-url <url> harness repo to vendor as engine/ (default: the agent-orchestrator repo)
# --ref <ref> harness ref to pin the submodule at (default: v0.1.0)
# --prefix <prefix> session_prefix to write into the project's config (default: <name>-)
# --register also append a [[project]] entry to this PO's fleet.toml (PO-side only)
# --no-commit leave the project tree uncommitted (default: make an initial commit)
#
# Drive it by hand afterwards, exactly like any project:
# cd <parent>/<name> && python3 engine/agents.py status
set -euo pipefail
die() { echo "create-project: $*" >&2; exit 1; }
[ $# -ge 1 ] || die "usage: create-project.sh <name> [--dir P] [--engine-url U] [--ref R] [--prefix X] [--register] [--no-commit]"
NAME="$1"; shift
[[ "$NAME" =~ ^[a-z0-9][a-z0-9-]*$ ]] || die "name must be kebab-case (got: $NAME)"
PO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
PARENT="$PO_ROOT/projects"
ENGINE_URL="https://git.autonomic.zone/recipe-maintainers/agent-orchestrator.git"
REF="v0.1.0"
PREFIX=""
REGISTER=0
COMMIT=1
while [ $# -gt 0 ]; do
case "$1" in
--dir) PARENT="$2"; shift 2;;
--engine-url) ENGINE_URL="$2"; shift 2;;
--ref) REF="$2"; shift 2;;
--prefix) PREFIX="$2"; shift 2;;
--register) REGISTER=1; shift;;
--no-commit) COMMIT=0; shift;;
*) die "unknown option: $1";;
esac
done
PREFIX="${PREFIX:-${NAME}-}"
command -v git >/dev/null || die "git not on PATH"
command -v python3 >/dev/null || die "python3 not on PATH"
DEST="$PARENT/$NAME"
[ -e "$DEST" ] && die "$DEST already exists — refusing to overwrite"
mkdir -p "$PARENT"
echo "create-project: scaffolding '$NAME' at $DEST (engine $ENGINE_URL @ $REF)"
git init -q -b main "$DEST"
cd "$DEST"
# 1) vendor the harness as a pinned submodule under engine/
git -c protocol.version=2 submodule add -q "$ENGINE_URL" engine
( cd engine && git fetch -q --tags origin && git checkout -q "$REF" )
git add .gitmodules engine
# 2) scaffold the harness config + prompts via the harness's OWN init (no PO/fleet metadata)
python3 engine/agents.py init . >/dev/null
# stamp the chosen session_prefix into the scaffolded config (keeps namespaces unique per project)
python3 - "$PREFIX" <<'PY'
import re, sys, pathlib
prefix = sys.argv[1]
p = pathlib.Path("agents.toml")
txt = p.read_text()
txt = re.sub(r'session_prefix\s*=\s*"[^"]*"', f'session_prefix = "{prefix}"', txt, count=1)
p.write_text(txt)
PY
# 3) ignore runtime state; the project knows nothing about any PO
cat > .gitignore <<'EOF'
# runtime state + logs (never committed)
.ao-state/
*.log
__pycache__/
*.pyc
result
EOF
git add agents.toml prompts .gitignore 2>/dev/null || true
if [ "$COMMIT" -eq 1 ]; then
git -c user.name="project-orchestrator" -c user.email="po@localhost" \
commit -q -m "init: scaffold $NAME (engine @ $REF)"
fi
echo "create-project: done — $DEST"
echo " engine pinned at: $(cd engine && git rev-parse HEAD) ($REF)"
echo " config: agents.toml (session_prefix = $PREFIX)"
echo " verify it: ( cd $DEST && python3 engine/agents.py status )"
if [ "$REGISTER" -eq 1 ]; then
echo "create-project: registering '$NAME' in $PO_ROOT/fleet.toml"
cat >> "$PO_ROOT/fleet.toml" <<EOF
[[project]]
name = "$NAME"
location = "$DEST"
harness = "agent-orchestrator"
ref = "$REF"
enabled = false
secrets = ".env"
config = "agents.toml"
notes = "Created by scripts/create-project.sh"
EOF
python3 "$PO_ROOT/scripts/fleet.py" --file "$PO_ROOT/fleet.toml" validate
fi