| name | release-peekaboo |
| description | Peekaboo release: notarization, npm/GitHub release, appcast, verify, closeout. |
| metadata | {"clawdbot":{"emoji":"👁️","requires":{"bins":["pnpm","op","tmux","gh","xcrun","jq","node","npm"]}}} |
Peekaboo Release
Release ~/Projects/Peekaboo as the npm package @steipete/peekaboo plus signed/notarized macOS app assets.
Use $one-password, $browser-use, $npm, $autoreview, and repo AGENTS.md rules. Load $release-private if it exists before resolving Peter-owned credential locators. Read $npm before any npm auth, token, or publish recovery work. Keep all op secret work inside one persistent tmux session. Never print .p8, npm tokens, passwords, or OTPs.
Current Secrets
- Peter-owned credential item names, key ids, issuer ids, keychain paths, and npm token locators live in
$release-private.
- Required ASC fields:
key_id, issuer_id, private_key_p8.
- Stale/revoked key symptom:
xcrun notarytool submit fails with HTTP status code: 401. Unauthenticated.
- All ASC fields must come from the same current item; do not mix profile values with 1Password refs.
Sparkle key:
- Repo
.mac-release.env has the current fallback.
- Do not set
SPARKLE_PRIVATE_KEY_FILE for normal releases.
Developer ID release keychain:
- Resolve the release keychain item/path from
$release-private.
- If macOS shows
codesign wants to use the release keychain, enter the keychain item password, not the Developer ID .p12 password.
- The Developer ID certificate password is only for importing the
.p12 while creating the keychain.
- After setup/import, run
security unlock-keychain and security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" so codesign can use the identity without GUI prompts.
npm publish token:
- Resolve token/TOTP locators from
$release-private.
- Use
$npm rules. Run inside the same tmux session, write only a temp npmrc, delete it immediately, and use the npmjs TOTP item for web auth if npm prompts.
- Do not create short-lived/granular bypass tokens for a normal Peekaboo publish. They add cleanup risk and did not help the 3.2.1 slow-upload/web-auth path.
Notary Credential Check
Use the service account from $release-private first. Put the token in the tmux environment without printing it:
tmux -S "$SOCKET" set-environment -t "$SESSION" OP_SERVICE_ACCOUNT_TOKEN "$SERVICE_ACCOUNT_TOKEN"
Create a temp env file with service-account refs from $release-private:
APP_STORE_CONNECT_API_KEY_P8=<1Password ref from release-private>
APP_STORE_CONNECT_KEY_ID=<1Password ref from release-private>
APP_STORE_CONNECT_ISSUER_ID=<1Password ref from release-private>
Before a release, verify shape and Apple auth without printing values:
op run --env-file "$ENVFILE" -- bash -c '
set -euo pipefail
KEY_FILE="/tmp/AuthKey_${APP_STORE_CONNECT_KEY_ID}.p8"
printf "%s\n" "$APP_STORE_CONNECT_API_KEY_P8" > "$KEY_FILE"
chmod 600 "$KEY_FILE"
xcrun notarytool history \
--key "$KEY_FILE" \
--key-id "$APP_STORE_CONNECT_KEY_ID" \
--issuer "$APP_STORE_CONNECT_ISSUER_ID" \
--output-format json >/dev/null
rm -f "$KEY_FILE"
'
Peekaboo forces notarytool submit --no-s3-acceleration; the default S3 accelerated upload path can return a misleading 401 even when history auth succeeds.
If both history and non-S3 submit fail, suspect wrong access level or stale key. Browser route:
- Use
$browser-use real Chrome profile.
- Open
https://appstoreconnect.apple.com/access/integrations/api.
- Generate Team Key named
Peekaboo Release <version> with Admin access.
- Download
.p8 once from the key row.
- Store immediately into the private credential map; verify
notarytool history; delete ~/Downloads/AuthKey_<key_id>.p8.
- Revoke the older Peekaboo release key after the new key validates.
Release Flow
- Start on clean
main; pull ff-only if needed.
- Set version in:
package.json
version.json
Apps/CLI/Sources/Resources/version.json
- README npm badge
Core/PeekabooCore/Sources/PeekabooAgentRuntime/MCP/PeekabooMCPVersion.swift
- Xcode marketing versions under
Apps/*
- Date
CHANGELOG.md and Apps/CLI/CHANGELOG.md for the release.
- Run focused proof or release script preflight. Release gates must be warning-free.
- Use
$autoreview before commit unless the change is trivial/docs-only.
- Commit release prep with
committer.
- Push
main.
- Run:
op run --env-file "$ENVFILE" -- \
bash -c 'printf "y\n" | ./scripts/release-binaries.sh --create-github-release --publish-npm'
The script builds universal CLI, npm package, signed/notarized app zip, appcast, checksums, draft GitHub release, and npm publish.
Use a non-login shell: profile exports can replace current 1Password ASC IDs with stale values while leaving the current .p8, producing a misleading 401.
Notarized app releases must sign with Developer ID Application: OpenClaw Foundation (FWJYW4S8P8), not a personal or development identity. The tracked release manifest resolves the shared passwordless signing keychain from the OpenClaw-Core vault; never copy the keychain path or signing material into the repository. The standalone CLI deliberately keeps Developer ID Application: Peter Steinberger (Y5PE65HELJ) for compatibility with pre-3.8 GUI bridge hosts, and the release driver verifies that exact split. Do not migrate the CLI signer without a separate bridge-compatibility plan.
If npm upload is slow and TOTP expires, use the stored npm token through a temp npmrc and complete npm web auth immediately when prompted with the configured TOTP. Do not create granular bypass tokens for this; if one was created by mistake, delete it before closeout.
Verify
Required before closeout:
npm view @steipete/peekaboo@<version> version dist-tags dist.tarball dist.integrity time --json
(cd /tmp && npm exec --yes --package=@steipete/peekaboo@<version> -- peekaboo --version)
gh release view v<version> --repo openclaw/Peekaboo --json tagName,isDraft,isPrerelease,url,assets,body
xmllint --noout appcast.xml
git status --short --branch
Confirm:
- npm version exists and
latest points to it.
- npm-downloaded CLI reports the release version from a neutral cwd.
- GitHub release/tag/assets exist; release body is from changelog.
- app zip asset exists and appcast points at
v<version>.
appcast.xml changes are committed and pushed.
- Publish draft release if the script leaves it draft.
Closeout
- Add next patch
Unreleased section to root and CLI changelogs.
- Commit with
committer "docs(changelog): open <next-version>" CHANGELOG.md Apps/CLI/CHANGELOG.md.
- Push.
- Watch release/homebrew/CI workflows if triggered.
git checkout main && git pull --ff-only && git status --short --branch.
- Clear tmux
OP_SERVICE_ACCOUNT_TOKEN, remove temp env/key files, and final with what landed.