fix(iso): retire clawdie-ai from ISO build — skills + tarball now from colibri
- 53 skills copied to colibri/.agent/skills/ (canonical home) - import-colibri-skills.sh: imports from colibri instead of clawdie-ai - build.sh: 4 clawdie-ai functions deleted, step 4 gated behind FEATURE_COLIBRI != YES, skills import uses colibri path - build manifest: clawdie_ai_commit set to "(retired)" - CLAWDIE_REF resolution simplified to git ls-remote (no deleted funcs) - clawdie-ai.tar.gz copy gated behind FEATURE_COLIBRI != YES
This commit is contained in:
parent
b4c86b68f4
commit
be7a782113
2 changed files with 105 additions and 91 deletions
115
build.sh
115
build.sh
|
|
@ -127,7 +127,7 @@ fi
|
|||
echo "==> clawdie-iso build"
|
||||
echo " ISO : ${ISO_VERSION}-${BUILD_CHANNEL} (zot ${ZOT_RESOLVED_VERSION})"
|
||||
echo " FreeBSD : ${FREEBSD_VERSION} ${FREEBSD_ARCH}"
|
||||
echo " Clawdie : ${CLAWDIE_REF}"
|
||||
echo " Clawdie : CLI phased out — Colibri is the control plane"
|
||||
echo " Desktop : ${DEFAULT_DESKTOP}"
|
||||
echo " Pkg : ${DEFAULT_PKG_BRANCH}"
|
||||
echo " GPU : ${GPU_DRIVER:-auto-detect}"
|
||||
|
|
@ -304,13 +304,7 @@ resolve_colibri_paths() {
|
|||
fi
|
||||
}
|
||||
|
||||
resolve_clawdie_ai_repo() {
|
||||
_resolved_clawdie_ai_repo="${CLAWDIE_AI_REPO:-/home/clawdie/ai/clawdie-ai}"
|
||||
case "${_resolved_clawdie_ai_repo}" in
|
||||
/*) ;;
|
||||
*) _resolved_clawdie_ai_repo="${SCRIPT_DIR}/${_resolved_clawdie_ai_repo}" ;;
|
||||
esac
|
||||
}
|
||||
# clawdie-ai retired — Colibri is the control plane.
|
||||
|
||||
preflight_colibri_artifacts() {
|
||||
[ "${FEATURE_COLIBRI:-NO}" = "YES" ] || return 0
|
||||
|
|
@ -419,54 +413,6 @@ json_escape() {
|
|||
printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'
|
||||
}
|
||||
|
||||
resolve_clawdie_commit() {
|
||||
_ref="$1"
|
||||
_repo="https://code.smilepowered.org/clawdie/clawdie-ai.git"
|
||||
if printf '%s' "$_ref" | grep -Eq '^[0-9a-fA-F]{40}$'; then
|
||||
printf '%s\n' "$_ref"
|
||||
return 0
|
||||
fi
|
||||
if command -v git >/dev/null 2>&1; then
|
||||
git ls-remote "$_repo" \
|
||||
"refs/heads/${_ref}" \
|
||||
"refs/tags/${_ref}^{}" \
|
||||
"refs/tags/${_ref}" 2>/dev/null \
|
||||
| awk '
|
||||
$2 ~ /\^\{\}$/ { print $1; found = 1; exit }
|
||||
first == "" { first = $1 }
|
||||
END { if (!found && first != "") print first }
|
||||
'
|
||||
fi
|
||||
}
|
||||
|
||||
resolve_latest_clawdie_tag() {
|
||||
_repo_api="https://code.smilepowered.org/api/v1/repos/clawdie/clawdie-ai"
|
||||
_repo_git="https://code.smilepowered.org/clawdie/clawdie-ai.git"
|
||||
|
||||
_tag=$(
|
||||
curl -fsS "${_repo_api}/releases?limit=20" 2>/dev/null \
|
||||
| grep -o '"tag_name":"[^"]*"' \
|
||||
| head -1 \
|
||||
| cut -d'"' -f4
|
||||
)
|
||||
if [ -n "$_tag" ]; then
|
||||
printf '%s\n' "$_tag"
|
||||
return 0
|
||||
fi
|
||||
|
||||
git ls-remote --tags "$_repo_git" 2>/dev/null \
|
||||
| awk -F/ '$2 == "tags" && $3 ~ /^v[0-9]+\.[0-9]+\.[0-9]+$/ { print $3 }' \
|
||||
| sed 's/^v//' \
|
||||
| sort -t. -k1,1n -k2,2n -k3,3n \
|
||||
| tail -n 1 \
|
||||
| sed 's/^/v/'
|
||||
}
|
||||
|
||||
is_pinned_clawdie_ref() {
|
||||
_ref="$1"
|
||||
printf '%s' "$_ref" | grep -Eq '^[0-9a-fA-F]{40}$|^v[0-9]+\.[0-9]+\.[0-9]+$'
|
||||
}
|
||||
|
||||
# Assert a repo has no uncommitted *or untracked* changes. `git status --porcelain`
|
||||
# is used (not `git diff`) so stray untracked files — which would change the build
|
||||
# yet pass a diff-only check — also fail the gate. Increments _release_errors on a
|
||||
|
|
@ -492,9 +438,6 @@ check_release_gate() {
|
|||
|
||||
assert_clean_repo "clawdie-iso" "${SCRIPT_DIR}"
|
||||
|
||||
resolve_clawdie_ai_repo
|
||||
assert_clean_repo "clawdie-ai" "${_resolved_clawdie_ai_repo}"
|
||||
|
||||
if [ "${FEATURE_COLIBRI:-NO}" = "YES" ]; then
|
||||
resolve_colibri_paths
|
||||
assert_clean_repo "colibri" "${_resolved_colibri_repo}"
|
||||
|
|
@ -544,17 +487,7 @@ write_build_manifest() {
|
|||
fi
|
||||
# Clawdie-AI provenance: the image stages a git checkout of the AI source,
|
||||
# so record whether the tree is modified at build time.
|
||||
_clawdie_ai_modified="null"
|
||||
if command -v git >/dev/null 2>&1; then
|
||||
resolve_clawdie_ai_repo
|
||||
if git -C "${_resolved_clawdie_ai_repo}" rev-parse --git-dir >/dev/null 2>&1; then
|
||||
if [ -z "$(git -C "${_resolved_clawdie_ai_repo}" status --porcelain 2>/dev/null)" ]; then
|
||||
_clawdie_ai_modified="false"
|
||||
else
|
||||
_clawdie_ai_modified="true"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
_clawdie_ai_modified="(retired)"
|
||||
if [ -n "${LIVE_SSH_PUBKEY_FP:-}" ]; then
|
||||
_live_ssh_pubkey_fp_json="\"$(json_escape "${LIVE_SSH_PUBKEY_FP}")\""
|
||||
fi
|
||||
|
|
@ -607,8 +540,8 @@ write_build_manifest() {
|
|||
"build_channel": "$(json_escape "${BUILD_CHANNEL}")",
|
||||
"freebsd_version": "$(json_escape "${FREEBSD_VERSION}")",
|
||||
"freebsd_arch": "$(json_escape "${FREEBSD_ARCH}")",
|
||||
"clawdie_ai_ref": "$(json_escape "${CLAWDIE_REF}")",
|
||||
"clawdie_ai_commit": "$(json_escape "${CLAWDIE_AI_COMMIT:-unknown}")",
|
||||
"clawdie_ai_ref": "(retired)",
|
||||
"clawdie_ai_commit": "(retired)",
|
||||
"clawdie_ai_modified": ${_clawdie_ai_modified:-null},
|
||||
"pi_version": "$(json_escape "${_pi_version:-unknown}")",
|
||||
"live_ssh_pubkey_fp": ${_live_ssh_pubkey_fp_json},
|
||||
|
|
@ -1055,15 +988,15 @@ install_colibri_service() {
|
|||
echo " colibri skills seeded: 6 entries"
|
||||
fi
|
||||
|
||||
# Import clawdie-ai skill definitions into the catalog.
|
||||
# Import colibri skill definitions into the catalog.
|
||||
# Reads .agent/skills/*/SKILL.md and registers name + description.
|
||||
resolve_clawdie_ai_repo
|
||||
_clawdie_ai_dir="${_resolved_clawdie_ai_repo}"
|
||||
if [ -d "${_clawdie_ai_dir}/.agent/skills" ]; then
|
||||
"${SCRIPT_DIR}/scripts/import-clawdie-skills.sh" \
|
||||
"${_clawdie_ai_dir}" "${MOUNT_POINT}"
|
||||
resolve_colibri_paths
|
||||
_colibri_dir="${_resolved_colibri_repo}"
|
||||
if [ -d "${_colibri_dir}/.agent/skills" ]; then
|
||||
"${SCRIPT_DIR}/scripts/import-colibri-skills.sh" \
|
||||
"${_colibri_dir}" "${MOUNT_POINT}"
|
||||
else
|
||||
echo " clawdie-ai checkout not found, skipping skill import"
|
||||
echo " colibri .agent/skills not found, skipping skill import"
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
@ -2265,29 +2198,26 @@ else
|
|||
fi
|
||||
|
||||
# --- step 4: fetch + prepare Clawdie-AI tarball (offline-ready) ---
|
||||
# Skip when Colibri is the control plane — the TypeScript AI tarball
|
||||
# is no longer needed for firstboot.
|
||||
if [ "${FEATURE_COLIBRI:-NO}" = "YES" ]; then
|
||||
echo "==> [4/7] Clawdie-AI tarball skipped (FEATURE_COLIBRI=YES — Colibri is the control plane)"
|
||||
else
|
||||
# Resolve "latest" from Forgejo releases first, then tags.
|
||||
if [ "${CLAWDIE_REF:-${CLAWDIE_VERSION:-}}" = "latest" ] || [ -z "${CLAWDIE_REF:-}" ]; then
|
||||
echo "==> [4/7] Resolving latest Clawdie-AI version..."
|
||||
CLAWDIE_VERSION=$(resolve_latest_clawdie_tag | sed 's/^v//')
|
||||
CLAWDIE_VERSION=$(git ls-remote --tags https://code.smilepowered.org/clawdie/clawdie-ai.git 2>/dev/null | awk -F/ '$2 == "tags" && $3 ~ /^v[0-9]+\.[0-9]+\.[0-9]+$/ { print $3 }' | sed 's/^v//' | sort -t. -k1,1n -k2,2n -k3,3n | tail -n 1 | sed 's/^/v/')
|
||||
if [ -z "$CLAWDIE_VERSION" ]; then
|
||||
echo "ERROR: could not resolve latest Clawdie-AI release/tag from Forgejo."
|
||||
echo " Pin --clawdie-ref main or --clawdie-version X.Y.Z explicitly."
|
||||
echo "ERROR: could not resolve latest Clawdie-AI release/tag."
|
||||
exit 1
|
||||
fi
|
||||
CLAWDIE_REF="v${CLAWDIE_VERSION}"
|
||||
echo " Resolved: ${CLAWDIE_REF}"
|
||||
fi
|
||||
|
||||
CLAWDIE_AI_COMMIT=$(resolve_clawdie_commit "$CLAWDIE_REF" | head -n 1)
|
||||
CLAWDIE_AI_COMMIT=$(git ls-remote https://code.smilepowered.org/clawdie/clawdie-ai.git "refs/heads/${CLAWDIE_REF}" "refs/tags/${CLAWDIE_REF}^{}" "refs/tags/${CLAWDIE_REF}" 2>/dev/null | head -1 | awk '{print $1}')
|
||||
CLAWDIE_AI_COMMIT="${CLAWDIE_AI_COMMIT:-unknown}"
|
||||
echo " Clawdie commit: ${CLAWDIE_AI_COMMIT}"
|
||||
|
||||
if [ "$CLAWDIE_AI_COMMIT" = "unknown" ] && [ "$SKIP_PKG_FETCH" -eq 1 ] && ! is_pinned_clawdie_ref "$CLAWDIE_REF"; then
|
||||
echo "ERROR: cannot safely skip the fetch for moving Clawdie-AI ref '${CLAWDIE_REF}' without resolving its commit."
|
||||
echo " Run without --skip-fetch / --skip-fetch-pkg, or pin --clawdie-version / --clawdie-ref to a commit."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$CLAWDIE_AI_COMMIT" != "unknown" ]; then
|
||||
CLAWDIE_ARCHIVE_REF="$CLAWDIE_AI_COMMIT"
|
||||
CLAWDIE_CACHE_KEY="$CLAWDIE_AI_COMMIT"
|
||||
|
|
@ -2369,6 +2299,7 @@ EOF
|
|||
else
|
||||
echo "==> [4/7] Clawdie-AI offline tarball cached."
|
||||
fi
|
||||
fi # FEATURE_COLIBRI guard (step 4)
|
||||
|
||||
# Exit here if --fetch-only (CI package pre-fetch step, no root required)
|
||||
if [ "$FETCH_ONLY" -eq 1 ]; then
|
||||
|
|
@ -2612,7 +2543,9 @@ if [ -d "$NPM_GLOBALS_DIR" ]; then
|
|||
echo " Bundled npm-globals: ${NPM_GLOBAL_TARBALL_COUNT} tarballs"
|
||||
fi
|
||||
install_live_npm_globals
|
||||
cp "${CLAWDIE_TARBALL_ISO}" "${USB_SHARE}/clawdie-ai.tar.gz"
|
||||
if [ "${FEATURE_COLIBRI:-NO}" != "YES" ]; then
|
||||
cp "${CLAWDIE_TARBALL_ISO}" "${USB_SHARE}/clawdie-ai.tar.gz"
|
||||
fi
|
||||
cp "${SCRIPT_DIR}/build.cfg" "${USB_SHARE}/"
|
||||
write_build_manifest "${USB_SHARE}/build-manifest.json"
|
||||
|
||||
|
|
|
|||
81
scripts/import-colibri-skills.sh
Executable file
81
scripts/import-colibri-skills.sh
Executable file
|
|
@ -0,0 +1,81 @@
|
|||
#!/bin/sh
|
||||
# Import colibri skill definitions into the colibri skills catalog.
|
||||
#
|
||||
# Reads .agent/skills/*/SKILL.md from a colibri checkout, extracts
|
||||
# YAML frontmatter (name, description), derives category, and inserts
|
||||
# into the colibri SQLite coordination database.
|
||||
#
|
||||
# Usage during ISO build:
|
||||
# scripts/import-clawdie-skills.sh /path/to/colibri /path/to/mount-point
|
||||
|
||||
set -eu
|
||||
|
||||
COLIBRI="${1:?usage: $0 <colibri-dir> <mount-point>}"
|
||||
MOUNT_POINT="${2:?usage: $0 <colibri-dir> <mount-point>}"
|
||||
DB="${MOUNT_POINT}/var/db/colibri/colibri.sqlite"
|
||||
|
||||
if [ ! -d "$COLIBRI/.agent/skills" ]; then
|
||||
echo " colibri skills dir not found, skipping import"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! command -v sqlite3 >/dev/null 2>&1; then
|
||||
echo " sqlite3 not available, skipping skills import"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Ensure the skills table exists
|
||||
sqlite3 "$DB" "CREATE TABLE IF NOT EXISTS skills (
|
||||
id TEXT PRIMARY KEY NOT NULL,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
description TEXT,
|
||||
category TEXT,
|
||||
created_at TEXT NOT NULL
|
||||
);" 2>/dev/null || true
|
||||
|
||||
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
IMPORTED=0
|
||||
SKIPPED=0
|
||||
|
||||
for skill_md in "$COLIBRI"/.agent/skills/*/SKILL.md; do
|
||||
[ -f "$skill_md" ] || continue
|
||||
|
||||
# Extract YAML frontmatter between --- markers
|
||||
frontmatter=$(sed -n '/^---$/,/^---$/p' "$skill_md" | sed '1d;$d')
|
||||
|
||||
# Extract name (first "name:" line after frontmatter)
|
||||
name=$(echo "$frontmatter" | grep -m1 '^name:' | sed 's/^name: *//' | tr -d '"')
|
||||
[ -n "$name" ] || continue
|
||||
|
||||
# Extract description
|
||||
description=$(echo "$frontmatter" | sed -n '/^description:/,/^[a-z]/p' | sed '$d' | sed 's/^description: *//' | tr '\n' ' ' | sed 's/ */ /g' | sed 's/^ *//;s/ *$//')
|
||||
# Handle multi-line descriptions (| indicator)
|
||||
if echo "$description" | grep -q '^|$'; then
|
||||
description=$(echo "$frontmatter" | awk '/^description:/{found=1; next} /^[a-z]/{if(found) exit} found{print}' | tr '\n' ' ' | sed 's/ */ /g' | sed 's/^ *//;s/ *$//')
|
||||
fi
|
||||
[ -n "$description" ] || description="$name skill"
|
||||
|
||||
# Derive category from skill name prefix
|
||||
case "$name" in
|
||||
git-*) category="git" ;;
|
||||
db-*|postgres*) category="database" ;;
|
||||
zfs-*) category="zfs" ;;
|
||||
add-*) category="integration" ;;
|
||||
freebsd-*) category="freebsd" ;;
|
||||
ansible-*) category="automation" ;;
|
||||
*) category="clawdie" ;;
|
||||
esac
|
||||
|
||||
# Override category if compatibility field indicates FreeBSD
|
||||
if echo "$frontmatter" | grep -q 'compatibility:.*FreeBSD'; then
|
||||
category="freebsd"
|
||||
fi
|
||||
|
||||
id=$(uuidgen 2>/dev/null || python3 -c "import uuid; print(uuid.uuid4())" 2>/dev/null || echo "skill-$(echo "$name" | md5)")
|
||||
|
||||
sqlite3 "$DB" "INSERT OR IGNORE INTO skills (id, name, description, category, created_at)
|
||||
VALUES ('$id', '$(echo "$name" | sed "s/'/''/g")', '$(echo "$description" | sed "s/'/''/g")', '$category', '$NOW');" 2>/dev/null && IMPORTED=$((IMPORTED + 1)) || SKIPPED=$((SKIPPED + 1))
|
||||
done
|
||||
|
||||
chroot "$MOUNT_POINT" chown colibri:colibri /var/db/colibri/colibri.sqlite 2>/dev/null || true
|
||||
echo " colibri skills: $IMPORTED imported, $SKIPPED skipped"
|
||||
Loading…
Add table
Reference in a new issue