Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions .github/workflows/desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ jobs:
echo "::warning::WINDOWS_CERTIFICATE_PFX is not configured; the Windows app ships unsigned"
fi
fi
vpk pack --packId KurrentCapacitor --packVersion "$VERSION" --packTitle "kcap" --packAuthors Kurrent \
vpk pack --packId kcap --packVersion "$VERSION" --packTitle "kcap" --packAuthors Kurrent \
--channel "$RID" --outputDir releases "${args[@]}"
rm -f "$RUNNER_TEMP/kcap-sign.pfx"

Expand All @@ -169,7 +169,7 @@ jobs:
run: |
set -euo pipefail
mkdir -p extracted
ditto -x -k releases/KurrentCapacitor-osx-arm64-Portable.zip extracted
ditto -x -k releases/kcap-osx-arm64-Portable.zip extracted
APP="extracted/kcap.app"
bash scripts/assert-app-plugin.sh "$APP" "$VERSION"
bash scripts/assert-app-cli-version.sh "$APP/Contents/MacOS/kcap" "$VERSION"
Expand Down Expand Up @@ -201,13 +201,13 @@ jobs:
# does not launch the app, so the smoke below starts it.
- name: Install the packed app
if: runner.os == 'Windows'
run: bash scripts/install-windows-setup.sh releases/KurrentCapacitor-win-x64-Setup.exe
run: bash scripts/install-windows-setup.sh releases/kcap-win-x64-Setup.exe

- name: Assert the installed app
if: runner.os == 'Windows'
run: |
set -euo pipefail
install="$(cygpath -u "$LOCALAPPDATA")/KurrentCapacitor"
install="$(cygpath -u "$LOCALAPPDATA")/kcap"
bash scripts/assert-app-plugin.sh "$install/current" "$VERSION"
bash scripts/assert-app-cli-version.sh "$install/current/kcap.exe" "$VERSION"
bash scripts/assert-bundle-digest.sh "$install" trio/bin/daemon.sha256
Expand All @@ -222,7 +222,7 @@ jobs:
$cfg = Join-Path $env:RUNNER_TEMP 'kcap-smoke'
New-Item -ItemType Directory -Force $cfg | Out-Null
$env:KCAP_CONFIG_DIR = $cfg; $env:KCAP_APP_UPDATE_URL = 'http://127.0.0.1:9/'; $env:DO_NOT_TRACK = '1'
$p = Start-Process (Join-Path $env:LOCALAPPDATA 'KurrentCapacitor\current\kcap-desktop.exe') -PassThru
$p = Start-Process (Join-Path $env:LOCALAPPDATA 'kcap\current\kcap-desktop.exe') -PassThru
Start-Sleep 15
if ($p.HasExited) { Write-Error "the packed app exited within 15 s (exit $($p.ExitCode))"; exit 1 }
Stop-Process -Id $p.Id -Force
Expand All @@ -231,7 +231,7 @@ jobs:
if: runner.os == 'Linux'
run: |
set -euo pipefail
(cd releases && ./KurrentCapacitor-linux-x64.AppImage --appimage-extract >/dev/null)
(cd releases && ./kcap-linux-x64.AppImage --appimage-extract >/dev/null)
app=releases/squashfs-root/usr/bin
bash scripts/assert-app-plugin.sh "$app" "$VERSION"
bash scripts/assert-app-cli-version.sh "$app/bin/kcap" "$VERSION"
Expand All @@ -248,7 +248,7 @@ jobs:
export KCAP_CONFIG_DIR="$RUNNER_TEMP/kcap-smoke" KCAP_APP_UPDATE_URL=http://127.0.0.1:9/ DO_NOT_TRACK=1
export APPIMAGE_EXTRACT_AND_RUN=1 XDG_DATA_HOME="$RUNNER_TEMP/kcap-data"
mkdir -p "$KCAP_CONFIG_DIR"
xvfb-run -a releases/KurrentCapacitor-linux-x64.AppImage > smoke.log 2>&1 &
xvfb-run -a releases/kcap-linux-x64.AppImage > smoke.log 2>&1 &
pid=$!
sleep 20
if ! kill -0 "$pid" 2>/dev/null; then echo "::error::the packed app exited within 20 s"; cat smoke.log; exit 1; fi
Expand All @@ -267,14 +267,14 @@ jobs:
DEB="releases/kcap-$VERSION-linux-x64.deb"
bash scripts/build-deb.sh publish/app "$VERSION" "$DEB"
sudo apt-get install -y "./$DEB"
app=/usr/lib/kurrent-capacitor
app=/usr/lib/kcap-desktop
bash scripts/assert-app-plugin.sh "$app" "$VERSION"
bash scripts/assert-app-cli-version.sh "$app/bin/kcap" "$VERSION"
bash scripts/assert-bundle-digest.sh "$app" trio/bin/daemon.sha256
export KCAP_CONFIG_DIR="$RUNNER_TEMP/kcap-deb-smoke" KCAP_APP_UPDATE_URL=http://127.0.0.1:9/ DO_NOT_TRACK=1
export XDG_RUNTIME_DIR="$RUNNER_TEMP/kcap-deb-runtime"
mkdir -p "$KCAP_CONFIG_DIR" && mkdir -m 0700 -p "$XDG_RUNTIME_DIR"
xvfb-run -a kurrent-capacitor > deb-smoke.log 2>&1 &
xvfb-run -a kcap-desktop > deb-smoke.log 2>&1 &
pid=$!
sleep 20
if ! kill -0 "$pid" 2>/dev/null; then echo "::error::the installed app exited within 20 s"; cat deb-smoke.log; exit 1; fi
Expand Down Expand Up @@ -310,8 +310,8 @@ jobs:
set -euo pipefail
cp trio/bin/daemon.sha256 trio/bin/kcap.sha256 releases/
case "$RUNNER_OS" in
Windows) mv "releases/KurrentCapacitor-$RID-Setup.exe" "releases/kcap-$VERSION-$RID-Setup.exe" ;;
Linux) cp "releases/KurrentCapacitor-$RID.AppImage" "releases/kcap-$VERSION-$RID.AppImage" ;;
Windows) mv "releases/kcap-$RID-Setup.exe" "releases/kcap-$VERSION-$RID-Setup.exe" ;;
Linux) cp "releases/kcap-$RID.AppImage" "releases/kcap-$VERSION-$RID.AppImage" ;;
esac

- name: Upload the release set
Expand All @@ -328,7 +328,7 @@ jobs:
with:
name: app-${{ inputs.rid }}-unsigned
path: |
releases/KurrentCapacitor-osx-arm64-Portable.zip
releases/KurrentCapacitor-win-x64-Setup.exe
releases/KurrentCapacitor-linux-x64.AppImage
releases/kcap-osx-arm64-Portable.zip
releases/kcap-win-x64-Setup.exe
releases/kcap-linux-x64.AppImage
releases/kcap-*-linux-x64.deb
11 changes: 4 additions & 7 deletions .github/workflows/publish-desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,11 @@ jobs:
for suffix in $INSTALLERS; do
FILE="releases/kcap-$VERSION-$CHANNEL$suffix"
aws s3 cp $R2 "$FILE" "$DEST/kcap-$VERSION-$CHANNEL$suffix" --cache-control "public, max-age=31536000, immutable"
# Keep legacy download links current while publishing the kcap names.
for alias in $aliases; do
for name in kcap Kurrent-Capacitor; do
case "$alias" in
beta) aws s3 cp $R2 "$FILE" "$DEST/$name-$CHANNEL-beta$suffix" --cache-control "public, max-age=300" ;;
stable) aws s3 cp $R2 "$FILE" "$DEST/$name-$CHANNEL$suffix" --cache-control "public, max-age=300" ;;
esac
done
case "$alias" in
beta) aws s3 cp $R2 "$FILE" "$DEST/kcap-$CHANNEL-beta$suffix" --cache-control "public, max-age=300" ;;
stable) aws s3 cp $R2 "$FILE" "$DEST/kcap-$CHANNEL$suffix" --cache-control "public, max-age=300" ;;
esac
done
done

Expand Down
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,21 +111,18 @@ Updates arrive through the app: it checks a few times a day, downloads in the ba

Help → Report a Bug… / Send Feedback… (or the help button in the session rail's footer) sends a report to Kurrent support; replies arrive by email.

**Upgrading an existing macOS installation:** use **Check for Updates…** in the installed app, or open **kcap** from the new disk image and choose **Quit and update**. Existing installations stay in their Applications folder and migrate from `Kurrent Capacitor.app` to `kcap.app`. The migration updates owned terminal links and background-service paths, then refreshes previously installed agent integrations with the bundled CLI to repair MCP commands, git hooks, and the Claude marketplace path. A failed integration refresh is reported and retried on the next launch. It preserves sign-in and settings, and keeps supported agent sessions for resumption unless `daemon.auto_resume` is off. An installer that finds valid installations in both Applications folders, or another app occupying the destination, asks for a destination first. Opening an installed `kcap.app` keeps that copy when its own folder needs no migration, even if a legacy copy remains in the other folder. An unrelated app is never replaced. Redundant copies are removed after the replacement opens successfully; a failed migration restores the installation or retains recovery backups and reports what needs attention. An equal or newer installed version offers **Open installed copy**.
**Upgrading an existing macOS installation:** use **Check for Updates…** in the installed app, or open **kcap** from the new disk image and choose **Quit and update**. The installation stays in its Applications folder. Moving the app to the other Applications folder updates owned terminal links and background-service paths, then refreshes previously installed agent integrations with the bundled CLI to repair MCP commands, git hooks, and the Claude marketplace path. A failed integration refresh is reported and retried on the next launch. An update preserves sign-in and settings, and keeps supported agent sessions for resumption unless `daemon.auto_resume` is off. An installer that finds valid installations in both Applications folders, or another app occupying the destination, asks for a destination first. An unrelated app is never replaced. Redundant copies are removed after the replacement opens successfully; a failed update restores the installation or retains recovery backups and reports what needs attention. An equal or newer installed version offers **Open installed copy**.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

### Desktop app on Windows

Download `kcap-<version>-win-x64-Setup.exe` from the [GitHub release](https://github.com/kurrent-io/kcap-cli/releases) (Windows 10 or later, x64) and run it. It installs per user into `%LocalAppData%\KurrentCapacitor` with no administrator prompt and adds a Start-menu entry. Like the macOS app it bundles its own `kcap` CLI and daemon. The first run offers to add the app's folder to your user PATH, so `kcap` works from any new terminal. Signing in installs the daemon as a background service (a per-user Scheduled Task that starts at sign-in) and starts it, as on macOS.
Download `kcap-<version>-win-x64-Setup.exe` from the [GitHub release](https://github.com/kurrent-io/kcap-cli/releases) (Windows 10 or later, x64) and run it. It installs per user into `%LocalAppData%\kcap` with no administrator prompt and adds a Start-menu entry. Like the macOS app it bundles its own `kcap` CLI and daemon. The first run offers to add the app's folder to your user PATH, so `kcap` works from any new terminal. Signing in installs the daemon as a background service (a per-user Scheduled Task that starts at sign-in) and starts it, as on macOS.

Windows draws no application menu, so **Settings…**, **Changelog** and the app version sit in the help button in the session rail's footer, next to Documentation and the report items. Closing the window keeps the app running in the notification area — quit from the tray icon's menu. Updates arrive through the app the same way as on macOS, from the Windows feed.

### Rebrand compatibility

kcap keeps existing configuration filenames, data directories, worktree locations,
and branch prefixes. Internal app and package IDs also stay unchanged, including
`io.kurrent.capacitor` and `KurrentCapacitor`. These conventions apply to new
installations too; no data-directory migration or manual reinstall is required
for the rebrand.
and branch prefixes; no data-directory migration is required for the rebrand.

The connection skill is now `connect-kcap` (`kcap-connect-kcap` in the shared
agent skill tree), and the Muse recording skill is `kcap-recording`. Refreshing
Expand Down
2 changes: 1 addition & 1 deletion scripts/assemble-app-bundle.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ cmp "$tmp/publish/kcap" "$bundle/Contents/MacOS/kcap"
cmp "$tmp/publish/kcap-desktop" "$bundle/Contents/MacOS/kcap-desktop"
[[ "$(/usr/libexec/PlistBuddy -c 'Print CFBundleExecutable' "$bundle/Contents/Info.plist")" == kcap-desktop ]]
[[ "$(/usr/libexec/PlistBuddy -c 'Print CFBundleDisplayName' "$bundle/Contents/Info.plist")" == kcap ]]
[[ "$(/usr/libexec/PlistBuddy -c 'Print CFBundleIdentifier' "$bundle/Contents/Info.plist")" == io.kurrent.capacitor ]]
[[ "$(/usr/libexec/PlistBuddy -c 'Print CFBundleIdentifier' "$bundle/Contents/Info.plist")" == io.kurrent.kcap ]]
test -f "$bundle/Contents/Resources/kcap-icon.icns"
bash "$here/assert-app-plugin.sh" "$bundle" 1.3.0-beta.7 >/dev/null
if bash "$here/assemble-app-bundle.sh" "$tmp/publish" "$bundle" 1.3.0-beta.8 >/dev/null 2>&1; then
Expand Down
16 changes: 8 additions & 8 deletions scripts/build-deb.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# Usage: build-deb.sh <app-directory> <version> <output.deb>
# Packages a published Linux app directory (the app, plus bin/ and the kcap/ plugin) as a .deb that
# installs under /usr/lib/kurrent-capacitor. Velopack does not manage this install: apt or a newer
# installs under /usr/lib/kcap-desktop. Velopack does not manage this install: apt or a newer
# .deb updates it, and the app hides its own update item when Velopack is absent.
set -euo pipefail
here="$(cd "$(dirname "$0")" && pwd)"
Expand All @@ -18,26 +18,26 @@ deb_version="${deb_version//-/\~}"
root="$(mktemp -d)"
trap 'rm -rf "$root"' EXIT
chmod 0755 "$root"
lib="$root/usr/lib/kurrent-capacitor"
lib="$root/usr/lib/kcap-desktop"
mkdir -p "$lib" "$root/usr/bin" "$root/usr/share/applications" "$root/usr/share/icons/hicolor/512x512/apps" "$root/DEBIAN"
cp -a "$app/." "$lib/"
chmod -R go-w,a+rX "$lib"
ln -s "../lib/kurrent-capacitor/kcap-desktop" "$root/usr/bin/kurrent-capacitor"
cp "$here/../src/Capacitor.App/Assets/kcap-icon.png" "$root/usr/share/icons/hicolor/512x512/apps/kurrent-capacitor.png"
ln -s "../lib/kcap-desktop/kcap-desktop" "$root/usr/bin/kcap-desktop"
cp "$here/../src/Capacitor.App/Assets/kcap-icon.png" "$root/usr/share/icons/hicolor/512x512/apps/kcap-desktop.png"

cat > "$root/usr/share/applications/kurrent-capacitor.desktop" <<'EOF'
cat > "$root/usr/share/applications/kcap-desktop.desktop" <<'EOF'
[Desktop Entry]
Type=Application
Name=kcap
Comment=Run and watch coding agents
Exec=kurrent-capacitor
Icon=kurrent-capacitor
Exec=kcap-desktop
Icon=kcap-desktop
Terminal=false
Categories=Development;
EOF

cat > "$root/DEBIAN/control" <<EOF
Package: kurrent-capacitor
Package: kcap-desktop
Version: $deb_version
Architecture: amd64
Maintainer: Kurrent <team@kcap.ai>
Expand Down
10 changes: 8 additions & 2 deletions scripts/desktop-baseline.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# `vpk download` leaves the channel's highest full package in the releases dir (no manifest), and
# `vpk pack` refuses a version at or below that baseline. Keep the package only when it is strictly
# below the candidate; otherwise delete it so the pack runs full-only, without a delta.
# `vpk pack` refuses a version at or below that baseline. Keep the package only when it carries the
# kcap pack ID and is strictly below the candidate; otherwise delete it so the pack runs full-only.
# Usage: desktop-baseline.sh <releases-dir> <candidate-version>
set -euo pipefail
here="$(cd "$(dirname "$0")" && pwd)"
Expand All @@ -18,6 +18,12 @@ if [ "${#pkgs[@]}" -eq 0 ]; then echo "no baseline package; packing full-only";
[ "${#pkgs[@]}" -eq 1 ] || { echo "expected one full package in $dir, found ${#pkgs[@]}" >&2; exit 1; }

pkg="${pkgs[0]}"
id="$(unzip -p "$pkg" '*.nuspec' | grep -oE '<id>[^<]+</id>' | head -1 | sed -E 's#</?id>##g')"
if [ "$id" != kcap ]; then
rm -f "$pkg"
echo "baseline package id '$id' is not kcap; discarded, packing full-only"
exit 0
fi
base="$(unzip -p "$pkg" '*.nuspec' | grep -oE '<version>[^<]+</version>' | head -1 | sed -E 's#</?version>##g')"
[ -n "$base" ] || { echo "no <version> in the nuspec of $pkg" >&2; exit 1; }

Expand Down
12 changes: 8 additions & 4 deletions scripts/desktop-baseline.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ here="$(cd "$(dirname "$0")" && pwd)"
sh="$here/desktop-baseline.sh"
tmp="$(mktemp -d)"; trap 'rm -rf "$tmp"' EXIT

make_pkg() { # <dir> <version> — the real download layout: one full nupkg, no manifest beside it
local dir="$1" v="$2" work; work="$(mktemp -d)"
printf '<?xml version="1.0"?><package><metadata><id>KurrentCapacitor</id><version>%s</version></metadata></package>' "$v" > "$work/KurrentCapacitor.nuspec"
(cd "$work" && zip -q "$dir/KurrentCapacitor-$v-osx-arm64-full.nupkg" KurrentCapacitor.nuspec)
make_pkg() { # <dir> <version> [id] — the real download layout: one full nupkg, no manifest beside it
local dir="$1" v="$2" id="${3:-kcap}" work; work="$(mktemp -d)"
printf '<?xml version="1.0"?><package><metadata><id>%s</id><version>%s</version></metadata></package>' "$id" "$v" > "$work/$id.nuspec"
(cd "$work" && zip -q "$dir/$id-$v-osx-arm64-full.nupkg" "$id.nuspec")
rm -rf "$work"
}

Expand All @@ -26,6 +26,10 @@ d="$tmp/equal"; mkdir -p "$d"; make_pkg "$d" "0.12.2"
bash "$sh" "$d" "0.12.2" >/dev/null
[ "$(count "$d")" = "0" ] || { echo "FAIL: equal baseline should be deleted"; fail=1; }

d="$tmp/other-id"; mkdir -p "$d"; make_pkg "$d" "0.12.1" "SomeOtherApp"
bash "$sh" "$d" "0.12.2" >/dev/null
[ "$(count "$d")" = "0" ] || { echo "FAIL: a baseline under another pack id should be deleted"; fail=1; }

d="$tmp/empty"; mkdir -p "$d"
bash "$sh" "$d" "0.12.2" >/dev/null || { echo "FAIL: empty download should be a no-op"; fail=1; }

Expand Down
2 changes: 1 addition & 1 deletion scripts/install-windows-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ set -euo pipefail

setup="${1:?usage: install-windows-setup.sh <Setup.exe>}"
unix() { if command -v cygpath >/dev/null 2>&1; then cygpath -u "$1"; else printf '%s' "$1"; fi; }
root="$(unix "${LOCALAPPDATA:?LOCALAPPDATA is not set}")/KurrentCapacitor"
root="$(unix "${LOCALAPPDATA:?LOCALAPPDATA is not set}")/kcap"
shortcut="$(unix "${APPDATA:?APPDATA is not set}")/Microsoft/Windows/Start Menu/Programs/kcap.lnk"

"$setup" --silent || { echo "Setup.exe failed (exit $?)" >&2; exit 1; }
Expand Down
8 changes: 4 additions & 4 deletions scripts/install-windows-setup.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ sh="$here/install-windows-setup.sh"
tmp="$(mktemp -d)"; trap 'rm -rf "$tmp"' EXIT

layout=(
"Local/KurrentCapacitor/Update.exe"
"Local/KurrentCapacitor/current/kcap-desktop.exe"
"Local/KurrentCapacitor/current/kcap.exe"
"Local/KurrentCapacitor/current/kcap-daemon.exe"
"Local/kcap/Update.exe"
"Local/kcap/current/kcap-desktop.exe"
"Local/kcap/current/kcap.exe"
"Local/kcap/current/kcap-daemon.exe"
"Roaming/Microsoft/Windows/Start Menu/Programs/kcap.lnk"
)

Expand Down
2 changes: 1 addition & 1 deletion scripts/promote-desktop-aliases.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ manifest() { # <file> <versions...> — Velopack's releases.<channel>.json shap
{ printf '{"Assets":['; local first=1
for v in "$@"; do
[ $first -eq 1 ] || printf ','; first=0
printf '{"PackageId":"KurrentCapacitor","Version":"%s","Type":"Full","FileName":"KurrentCapacitor-%s-osx-arm64-full.nupkg","SHA1":"","SHA256":"","Size":1}' "$v" "$v"
printf '{"PackageId":"kcap","Version":"%s","Type":"Full","FileName":"kcap-%s-osx-arm64-full.nupkg","SHA1":"","SHA256":"","Size":1}' "$v" "$v"
done
printf ']}'; } > "$file"
}
Expand Down
2 changes: 1 addition & 1 deletion scripts/refuse-published-desktop.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
set -uo pipefail
usage="usage: refuse-published-desktop.sh <channel> <version>"
channel="${1:?$usage}"; version="${2:?$usage}"
key="desktop/$channel/KurrentCapacitor-$version-$channel-full.nupkg"
key="desktop/$channel/kcap-$version-$channel-full.nupkg"

err="$(aws s3api head-object --endpoint-url "${R2_ENDPOINT:?}" --bucket "${R2_BUCKET:?}" --key "$key" 2>&1 >/dev/null)"
rc=$?
Expand Down
4 changes: 2 additions & 2 deletions scripts/verify-desktop-immutables.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ fetch="${3:?usage: verify-desktop-immutables.sh <local-dir> <version> <fetch-scr
channel="${4:-osx-arm64}"

names=(
"KurrentCapacitor-$version-$channel-full.nupkg"
"KurrentCapacitor-$version-$channel-delta.nupkg"
"kcap-$version-$channel-full.nupkg"
"kcap-$version-$channel-delta.nupkg"
"kcap-$version-$channel.dmg"
"kcap-$version-$channel-Setup.exe"
"kcap-$version-$channel.AppImage"
Expand Down
4 changes: 2 additions & 2 deletions scripts/verify-desktop-immutables.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ sh="$here/verify-desktop-immutables.sh"
tmp="$(mktemp -d)"; trap 'rm -rf "$tmp"' EXIT
v="0.12.0-beta.2"
local_dir="$tmp/local"; remote="$tmp/remote"; mkdir -p "$local_dir" "$remote"
printf 'full' > "$local_dir/KurrentCapacitor-$v-osx-arm64-full.nupkg"
printf 'full' > "$local_dir/kcap-$v-osx-arm64-full.nupkg"
printf 'dmg' > "$local_dir/kcap-$v-osx-arm64.dmg"
fetch="$tmp/fetch.sh"
printf '#!/usr/bin/env bash\n[ -f "%s/$1" ] || exit 44\ncp "%s/$1" "$2"\n' "$remote" "$remote" > "$fetch"; chmod +x "$fetch"
Expand All @@ -15,7 +15,7 @@ assert() { local rc; set +e; bash "$sh" "$local_dir" "$v" "$fetch" >/dev/null 2>
if [ "$rc" != "$2" ]; then echo "FAIL: $1 -> rc=$rc (want $2)"; fail=1; fi; }

assert "nothing published yet passes" 0
cp "$local_dir/KurrentCapacitor-$v-osx-arm64-full.nupkg" "$remote/"
cp "$local_dir/kcap-$v-osx-arm64-full.nupkg" "$remote/"
assert "identical bytes already published passes (retry)" 0
printf 'other-bytes' > "$remote/kcap-$v-osx-arm64.dmg"
assert "different bytes already published fails" 1
Expand Down
Loading
Loading