mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-07 02:51:50 +00:00
The kanban prefix makes the skill discoverable alongside `kanban-orchestrator` and `kanban-worker`, and signals up front that this skill drives the kanban plugin rather than being a generic video tool. Updated: - directory rename - SKILL.md frontmatter `name:` and H1 - setup.sh.tmpl header
185 lines
8.1 KiB
Bash
185 lines
8.1 KiB
Bash
#!/usr/bin/env bash
|
|
# ═══════════════════════════════════════════════════════════════════════
|
|
# Video Pipeline Setup — {{TITLE}}
|
|
#
|
|
# Generated by kanban-video-orchestrator skill.
|
|
#
|
|
# Slug: {{SLUG}}
|
|
# Workspace: {{WORKSPACE}}
|
|
# Tenant: {{TENANT}}
|
|
# ═══════════════════════════════════════════════════════════════════════
|
|
set -euo pipefail
|
|
|
|
PROJECT_SLUG="{{SLUG}}"
|
|
WORKSPACE="$HOME/projects/video-pipeline/${PROJECT_SLUG}"
|
|
TENANT="{{TENANT}}"
|
|
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
# 1. Verify required API keys
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
echo "═══ Checking required API keys ═══"
|
|
|
|
check_key() {
|
|
local var="$1"
|
|
local kc_account="${2:-hermes}"
|
|
local kc_service="${3:-$1}"
|
|
if grep -q "^${var}=" "$HOME/.hermes/.env" 2>/dev/null && \
|
|
[ -n "$(grep "^${var}=" "$HOME/.hermes/.env" | cut -d= -f2-)" ]; then
|
|
echo " ✓ ${var} (env)"
|
|
return 0
|
|
fi
|
|
if command -v security >/dev/null 2>&1 && \
|
|
security find-generic-password -a "${kc_account}" -s "${kc_service}" -w >/dev/null 2>&1; then
|
|
echo " ✓ ${var} (Keychain ${kc_account}/${kc_service})"
|
|
return 0
|
|
fi
|
|
echo " ✗ ${var} not set in ~/.hermes/.env or Keychain (${kc_account}/${kc_service})"
|
|
return 1
|
|
}
|
|
|
|
# Customize this list per project — only check keys actually used:
|
|
{{KEY_CHECKS}}
|
|
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
# 2. Create project workspace
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
echo "═══ Creating project workspace ═══"
|
|
mkdir -p "$WORKSPACE"/{taste,audio/{voiceover,sfx},assets,scenes,checkpoints,tools,output}
|
|
{{SCENE_DIRS}}
|
|
echo " ✓ $WORKSPACE"
|
|
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
# 3. Create Hermes profiles
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
echo "═══ Creating Hermes profiles ═══"
|
|
|
|
{{PROFILE_CREATE_COMMANDS}}
|
|
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
# 4. Configure profiles (toolsets, skills, cwd)
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
echo "═══ Configuring profiles ═══"
|
|
|
|
configure_profile() {
|
|
local profile="$1"
|
|
local toolsets_json="$2" # JSON array string, e.g. '["kanban","terminal","file"]'
|
|
local skills_json="$3" # JSON array string, e.g. '["kanban-worker","ascii-video"]'
|
|
python3 - "$profile" "$toolsets_json" "$skills_json" "$WORKSPACE" <<'PY'
|
|
"""Patch a Hermes profile config.yaml using PyYAML so we don't depend on the
|
|
exact default-config string format. Validates the patch took effect and exits
|
|
non-zero if anything's off."""
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
try:
|
|
import yaml
|
|
except ImportError:
|
|
print("ERROR: PyYAML required. pip install pyyaml", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
profile, toolsets_json, skills_json, workspace = sys.argv[1:5]
|
|
toolsets = json.loads(toolsets_json)
|
|
skills = json.loads(skills_json)
|
|
|
|
p = os.path.expanduser(f"~/.hermes/profiles/{profile}/config.yaml")
|
|
if not os.path.exists(p):
|
|
print(f" ✗ profile config not found: {p}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
with open(p) as f:
|
|
cfg = yaml.safe_load(f) or {}
|
|
|
|
# Apply our changes — only the keys we actually want to set.
|
|
cfg["toolsets"] = toolsets
|
|
cfg.setdefault("skills", {})
|
|
cfg["skills"]["always_load"] = skills
|
|
|
|
# Note: we do NOT touch cfg["approvals"] — that's a security-sensitive
|
|
# setting (manual confirmation of tool calls). Workspace cwd is overridden
|
|
# per-task by `--workspace dir:<path>` on `hermes kanban create`, so we
|
|
# don't need to mutate cfg["terminal"]["cwd"] either.
|
|
|
|
with open(p, "w") as f:
|
|
yaml.safe_dump(cfg, f, sort_keys=False)
|
|
|
|
# Validate
|
|
with open(p) as f:
|
|
after = yaml.safe_load(f)
|
|
errors = []
|
|
if after.get("toolsets") != toolsets:
|
|
errors.append(f"toolsets mismatch: {after.get('toolsets')!r}")
|
|
if after.get("skills", {}).get("always_load") != skills:
|
|
errors.append(f"skills.always_load mismatch: {after.get('skills', {}).get('always_load')!r}")
|
|
if errors:
|
|
print(f" ✗ {profile}: " + "; ".join(errors), file=sys.stderr)
|
|
sys.exit(1)
|
|
PY
|
|
if [ $? -ne 0 ]; then
|
|
echo " ✗ failed to configure ${profile}" >&2
|
|
exit 1
|
|
fi
|
|
echo " ✓ ${profile}"
|
|
}
|
|
|
|
{{PROFILE_CONFIG_COMMANDS}}
|
|
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
# 5. Write SOUL.md per profile
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
echo "═══ Writing profile personalities ═══"
|
|
|
|
{{SOUL_WRITES}}
|
|
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
# 6. Copy brief, TEAM.md, and any provided assets
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
echo "═══ Writing brief + taste ═══"
|
|
|
|
cat > "$WORKSPACE/brief.md" <<'BRIEF_EOF'
|
|
{{BRIEF_CONTENTS}}
|
|
BRIEF_EOF
|
|
|
|
cat > "$WORKSPACE/TEAM.md" <<'TEAM_EOF'
|
|
{{TEAM_CONTENTS}}
|
|
TEAM_EOF
|
|
|
|
{{TASTE_WRITES}}
|
|
|
|
{{ASSET_COPIES}}
|
|
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
# 7. Fire the initial kanban task
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
echo "═══ Firing initial kanban task ═══"
|
|
|
|
hermes kanban create "Direct production of {{TITLE}}" \
|
|
--assignee director \
|
|
--workspace dir:"$WORKSPACE" \
|
|
--tenant "$TENANT" \
|
|
--priority 2 \
|
|
--max-runtime 4h \
|
|
--body "$(cat <<EOF
|
|
Read brief.md, TEAM.md, and taste/.
|
|
|
|
Decompose into the team graph defined in TEAM.md.
|
|
|
|
All child tasks MUST use:
|
|
workspace_kind="dir"
|
|
workspace_path="$WORKSPACE"
|
|
tenant="$TENANT"
|
|
|
|
Do not execute the work yourself — route every concrete subtask to the
|
|
appropriate profile via kanban_create.
|
|
EOF
|
|
)"
|
|
|
|
echo ""
|
|
echo "═══ Setup complete ═══"
|
|
echo ""
|
|
echo "Monitor with:"
|
|
echo " hermes kanban watch --tenant $TENANT"
|
|
echo " hermes kanban list --tenant $TENANT"
|
|
echo " hermes dashboard"
|
|
echo ""
|
|
echo "Workspace: $WORKSPACE"
|