- Add gateway.webApp config (enabled, port, dev) as the unified toggle for both the Next.js web UI and the built-in control UI - Spawn Next.js app alongside the gateway; stop it on shutdown - Auto-enable webApp in config for new and existing installs - Pre-build Next.js in deploy.sh and ship .next/ in the npm package so installed users get instant startup (no build step) - Gateway skips build when pre-built .next/ exists; builds on first run for dev/git-checkout users - Onboarding "Open the Web UI" now opens the Ironclaw web app - Fix pre-existing Next.js build errors (ES2023 lib, Tiptap v3 types, Suspense boundary, ReportConfig type alignment) - Rename deploy target from openclaw-ai-sdk to ironclaw Co-authored-by: Cursor <cursoragent@cursor.com>
197 lines
6.5 KiB
Bash
Executable File
197 lines
6.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# deploy.sh — build and publish ironclaw to npm
|
|
#
|
|
# Versioning convention (mirrors upstream openclaw tags):
|
|
# --upstream <ver> Sync to an upstream release version.
|
|
# If that version is already published, appends .1, .2, …
|
|
# (or -1, -2, … when the base has no prerelease).
|
|
# --bump Increment the local fork suffix on the current version.
|
|
# 2026.2.6-3 → 2026.2.6-3.1
|
|
# 2026.2.6-3.1 → 2026.2.6-3.2
|
|
# 2026.2.7 → 2026.2.7-1
|
|
# (no flag) Publish whatever version is already in package.json.
|
|
#
|
|
# Environment:
|
|
# NPM_TOKEN Required. npm auth token for publishing.
|
|
|
|
set -euo pipefail
|
|
|
|
PACKAGE_NAME="ironclaw"
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
|
cd "$ROOT_DIR"
|
|
|
|
# ── helpers ──────────────────────────────────────────────────────────────────
|
|
|
|
die() { echo "error: $*" >&2; exit 1; }
|
|
|
|
current_version() {
|
|
node -p "require('./package.json').version"
|
|
}
|
|
|
|
# Check whether a specific version is already on the npm registry.
|
|
npm_version_exists() {
|
|
local v="$1"
|
|
npm view "${PACKAGE_NAME}@${v}" version 2>/dev/null | grep -q "${v}" 2>/dev/null
|
|
}
|
|
|
|
# Given a base version, return it if available on npm, otherwise find the
|
|
# next free slot by appending a dot-suffix (.1, .2, …) for versions that
|
|
# already contain a prerelease, or a hyphen-suffix (-1, -2, …) otherwise.
|
|
find_available_version() {
|
|
local base="$1"
|
|
if ! npm_version_exists "$base"; then
|
|
echo "$base"
|
|
return
|
|
fi
|
|
|
|
local n=1
|
|
if [[ "$base" == *-* ]]; then
|
|
# Has prerelease already → append .N
|
|
while npm_version_exists "${base}.${n}"; do
|
|
n=$((n + 1))
|
|
done
|
|
echo "${base}.${n}"
|
|
else
|
|
# No prerelease → append -N
|
|
while npm_version_exists "${base}-${n}"; do
|
|
n=$((n + 1))
|
|
done
|
|
echo "${base}-${n}"
|
|
fi
|
|
}
|
|
|
|
# Increment the local fork suffix on a version string.
|
|
# 2026.2.6-3 → 2026.2.6-3.1 (upstream prerelease, add .1)
|
|
# 2026.2.6-3.1 → 2026.2.6-3.2 (increment last dot segment)
|
|
# 2026.2.7 → 2026.2.7-1 (no prerelease, add -1)
|
|
# 2026.2.7-1 → 2026.2.7-1.1 (treat -1 as upstream-like, add .1)
|
|
bump_version() {
|
|
local current="$1"
|
|
|
|
# If the prerelease already has a dot (e.g. 3.1 in 2026.2.6-3.1),
|
|
# increment the last numeric segment after the final dot.
|
|
local prerelease="${current#*-}"
|
|
if [[ "$current" == *-* ]] && [[ "$prerelease" == *.* ]]; then
|
|
if [[ "$current" =~ ^(.*\.)([0-9]+)$ ]]; then
|
|
echo "${BASH_REMATCH[1]}$((BASH_REMATCH[2] + 1))"
|
|
return
|
|
fi
|
|
fi
|
|
|
|
# Has a prerelease but no dot-suffix yet → append .1
|
|
if [[ "$current" == *-* ]]; then
|
|
echo "${current}.1"
|
|
return
|
|
fi
|
|
|
|
# Plain semver with no prerelease → append -1
|
|
echo "${current}-1"
|
|
}
|
|
|
|
# ── parse args ───────────────────────────────────────────────────────────────
|
|
|
|
MODE=""
|
|
UPSTREAM_VERSION=""
|
|
DRY_RUN=false
|
|
SKIP_BUILD=false
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--upstream)
|
|
MODE="upstream"
|
|
UPSTREAM_VERSION="${2:?--upstream requires a version argument}"
|
|
shift 2
|
|
;;
|
|
--bump)
|
|
MODE="bump"
|
|
shift
|
|
;;
|
|
--dry-run)
|
|
DRY_RUN=true
|
|
shift
|
|
;;
|
|
--skip-build)
|
|
SKIP_BUILD=true
|
|
shift
|
|
;;
|
|
--help|-h)
|
|
sed -n '2,/^[^#]/{ /^#/s/^# \{0,1\}//p; }' "$0"
|
|
exit 0
|
|
;;
|
|
*)
|
|
die "unknown argument: $1 (see --help)"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# ── auth ─────────────────────────────────────────────────────────────────────
|
|
|
|
if [[ -z "${NPM_TOKEN:-}" ]]; then
|
|
die "NPM_TOKEN environment variable is required"
|
|
fi
|
|
|
|
# Write a temporary .npmrc for auth (npm_config_ env vars can't encode
|
|
# registry-scoped keys because they contain slashes and colons).
|
|
NPMRC_TEMP="${ROOT_DIR}/.npmrc.deploy"
|
|
trap 'rm -f "$NPMRC_TEMP"' EXIT
|
|
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > "$NPMRC_TEMP"
|
|
NPM_FLAGS=(--userconfig "$NPMRC_TEMP")
|
|
|
|
# ── compute version ─────────────────────────────────────────────────────────
|
|
|
|
CURRENT="$(current_version)"
|
|
|
|
case "$MODE" in
|
|
upstream)
|
|
VERSION="$(find_available_version "$UPSTREAM_VERSION")"
|
|
echo "upstream sync: $UPSTREAM_VERSION → publishing as $VERSION"
|
|
;;
|
|
bump)
|
|
NEXT="$(bump_version "$CURRENT")"
|
|
VERSION="$(find_available_version "$NEXT")"
|
|
echo "local bump: $CURRENT → $VERSION"
|
|
;;
|
|
*)
|
|
if npm_version_exists "$CURRENT"; then
|
|
die "version $CURRENT already exists on npm. Use --bump or --upstream <ver>."
|
|
fi
|
|
VERSION="$CURRENT"
|
|
echo "publishing current version: $VERSION"
|
|
;;
|
|
esac
|
|
|
|
if [[ "$DRY_RUN" == true ]]; then
|
|
echo "[dry-run] would publish ${PACKAGE_NAME}@${VERSION}"
|
|
exit 0
|
|
fi
|
|
|
|
# ── set version ──────────────────────────────────────────────────────────────
|
|
|
|
npm version "$VERSION" --no-git-tag-version --allow-same-version "${NPM_FLAGS[@]}"
|
|
|
|
# ── build ────────────────────────────────────────────────────────────────────
|
|
|
|
if [[ "$SKIP_BUILD" != true ]]; then
|
|
echo "building..."
|
|
pnpm build
|
|
|
|
# Build the Ironclaw Next.js web app so the npm package ships a ready-to-run
|
|
# production build (gateway can skip the build step at startup).
|
|
echo "building web app..."
|
|
(cd apps/web && npm install --legacy-peer-deps && npx next build)
|
|
fi
|
|
|
|
# ── publish ──────────────────────────────────────────────────────────────────
|
|
|
|
# Always tag as "latest" — npm skips the latest tag for prerelease versions
|
|
# by default, but we want `npm i -g ironclaw` to always resolve to
|
|
# the most recently published version.
|
|
echo "publishing ${PACKAGE_NAME}@${VERSION}..."
|
|
npm publish --access public --tag latest "${NPM_FLAGS[@]}"
|
|
|
|
echo ""
|
|
echo "published ${PACKAGE_NAME}@${VERSION}"
|
|
echo "install: npm i -g ${PACKAGE_NAME}"
|