Files
kandev/apps/backend/internal/agent/runtime/lifecycle/default_scripts.go
T
2026-05-16 20:07:57 +01:00

169 lines
6.6 KiB
Go

package lifecycle
// DefaultPrepareScript returns the default prepare script for a given executor type string.
func DefaultPrepareScript(executorType string) string {
switch executorType {
case "local":
return defaultLocalPrepareScript
case "worktree":
return defaultWorktreePrepareScript
case "local_docker", "remote_docker":
return defaultDockerPrepareScript
case "sprites":
return defaultSpritesPrepareScript
default:
return ""
}
}
// KandevBranchCheckoutPostlude returns a kandev-managed shell snippet that
// guarantees the session's feature branch is checked out inside the
// workspace, no matter what the user's stored prepare_script does.
//
// Why a postlude instead of just relying on the default script: profiles
// created in the UI snapshot the *then-current* default into their stored
// prepare_script field. When kandev's default is updated to add a new
// kandev-managed step (like the worktree-branch checkout), older profiles
// silently miss it forever. Making the checkout an invariant — appended
// after the user's script — keeps the contract regardless of which default
// the user happens to have stored.
//
// The snippet is wrapped in a subshell + `|| true` so any failure (e.g. the
// user's script never produced /workspace, or the branch is the same as the
// base) is benign and doesn't block agentctl from starting.
//
//nolint:dupword // two `fi` tokens close two distinct shell blocks.
func KandevBranchCheckoutPostlude() string {
return `
# ---- kandev-managed: ensure session feature branch is checked out ----
# Appended automatically after the user's prepare script. Idempotent and
# non-destructive: prefer an existing local branch (which may carry unpushed
# work after a container resume), then fall through to a fresh tracking
# branch off origin, and only as a last resort create the branch off HEAD.
# The previous "git checkout -B feature origin/feature" form was destructive
# for the resume case — overwriting local commits with the remote tip.
(
if [ -d "{{workspace.path}}/.git" ] \
&& [ -n "{{worktree.branch}}" ] \
&& [ "{{worktree.branch}}" != "{{repository.branch}}" ]; then
cd "{{workspace.path}}" || exit 0
if git rev-parse --verify "{{worktree.branch}}" >/dev/null 2>&1; then
git checkout "{{worktree.branch}}"
elif git fetch --depth=1 origin "{{worktree.branch}}" 2>/dev/null; then
git checkout -b "{{worktree.branch}}" "origin/{{worktree.branch}}"
else
git checkout -b "{{worktree.branch}}"
fi
fi
) || true
`
}
const defaultLocalPrepareScript = `#!/bin/bash
# Prepare local environment
# Runs before launching the local agent runtime.
# The script executes with working directory set to {{workspace.path}}.
# Use {{repository.path}} when you need the canonical repository root path.
# ---- Repository setup (if configured) ----
{{repository.setup_script}}
`
const defaultWorktreePrepareScript = `#!/bin/bash
# Prepare worktree environment
# Runs after the worktree has already been created/reused by Kandev.
# The script executes with working directory set to {{worktree.path}}.
# Use {{repository.path}} if you need to run commands in the main repository.
# ---- Repository setup (if configured) ----
{{repository.setup_script}}
`
const defaultDockerPrepareScript = `#!/bin/sh
# Prepare Docker container environment (kandev/multi-agent image)
# git, node, and agentctl are already installed in the image
set -eu
# ---- Git identity (optional) ----
{{git.identity_setup}}
# Mounted local remotes and workspaces can be owned by a host UID that does
# not match the container user.
git config --global --add safe.directory '*'
# ---- Configure git/gh for HTTPS auth ----
git config --global url."https://github.com/".insteadOf "git@github.com:"
git config --global url."https://github.com/".insteadOf "ssh://git@github.com/"
# Configure GitHub token for gh CLI and git operations
{{github.auth_setup}}
# ---- Clone repository ----
# The kandev-managed feature-branch checkout is appended as an invariant
# postlude (see KandevBranchCheckoutPostlude) — keep it out of the default
# so old profiles snapshotting this script and the postlude never disagree.
git clone --depth=1 --branch {{repository.branch}} {{repository.clone_url}} {{workspace.path}}
cd {{workspace.path}}
# Strip embedded token from remote URL to avoid persisting credentials in .git/config
git remote set-url origin "$(git remote get-url origin | sed 's|https://[^@]*@github.com/|https://github.com/|')" 2>/dev/null || true
# ---- Repository setup (if configured) ----
{{repository.setup_script}}
`
const defaultSpritesPrepareScript = `#!/bin/bash
# Prepare Sprites.dev cloud sandbox
#
# Pre-installed tools (no need to install):
# git, curl, wget, gh (GitHub CLI), node, python, go,
# build-essential, openssh-client, ca-certificates
set -euo pipefail
# ---- Add SSH host keys (prevent "Host key verification failed") ----
mkdir -p ~/.ssh
ssh-keyscan -t ed25519 github.com gitlab.com bitbucket.org >> ~/.ssh/known_hosts 2>/dev/null
# ---- Configure git/gh for HTTPS auth (token-based, no SSH keys needed) ----
# Rewrite SSH URLs to HTTPS so git clone git@github.com:... works via token auth
git config --global url."https://github.com/".insteadOf "git@github.com:"
git config --global url."https://github.com/".insteadOf "ssh://git@github.com/"
# Configure GitHub token for gh CLI and git operations
# GH_TOKEN is the primary env var for gh CLI authentication
{{github.auth_setup}}
# ---- Install pnpm globally ----
curl -fsSL https://github.com/pnpm/pnpm/releases/download/v10.32.1/pnpm-linux-x64 -o /usr/local/bin/pnpm
chmod +x /usr/local/bin/pnpm
# ---- Git identity ----
{{git.identity_setup}}
# ---- Clone repository ----
# The kandev-managed feature-branch checkout is appended as an invariant
# postlude (see KandevBranchCheckoutPostlude) — keep it out of the default
# so old profiles snapshotting this script and the postlude never disagree.
echo "Cloning {{repository.clone_url}} (branch: {{repository.branch}})..."
git clone --depth=1 --quiet --branch {{repository.branch}} {{repository.clone_url}} {{workspace.path}}
cd {{workspace.path}}
# Strip embedded token from remote URL to avoid persisting credentials in .git/config
git remote set-url origin "$(git remote get-url origin | sed 's|https://[^@]*@github.com/|https://github.com/|')" 2>/dev/null || true
# ---- Repository setup (if configured) ----
{{repository.setup_script}}
# ---- Pre-install agent CLI(s) ----
{{kandev.agents.install}}
# ---- Install and start Kandev agent controller ----
echo "Starting agent controller..."
{{kandev.agentctl.install}}
{{kandev.agentctl.start}}
echo "Prepare complete."
`