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
31 changes: 31 additions & 0 deletions .github/workflows/release-notes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Release notes

# Regenerates a release's notes on demand, for any tag. New releases don't
# need this: their notes run as a separate job, so "Re-run failed jobs"
# retries them. It's for releases cut before that split (0.2.9 and earlier),
# where the notes step ran after `npm publish` in the same job and a re-run
# would try to publish the same version again.
on:
workflow_dispatch:
inputs:
tag:
description: Release tag to regenerate notes for (e.g. v0.2.9)
required: true

permissions:
contents: write

jobs:
notes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
fetch-tags: true
- name: Generate AI release notes
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
RELEASE_TAG: ${{ inputs.tag }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bash .github/scripts/ai-release-notes.sh
22 changes: 18 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
permissions:
contents: write # edit the GitHub Release with AI-generated notes
contents: read
id-token: write # npm publish provenance
steps:
- name: Checkout
Expand Down Expand Up @@ -71,10 +71,24 @@ jobs:
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

# Best-effort: replace the release body with human-readable notes written by
# Claude. If it fails, the release keeps release-please's default notes.
# Replaces the release body with human-readable notes. Its own job, after
# publish, so a failure (e.g. an empty API credit balance) shows red without
# touching the release, and "Re-run failed jobs" retries just this - never
# npm publish. If it stays failed, the release keeps release-please's notes.
notes:
needs: [release-please, publish]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
permissions:
contents: write # edit the GitHub Release
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true

- name: Generate AI release notes
continue-on-error: true
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
RELEASE_TAG: ${{ needs.release-please.outputs.tag_name }}
Expand Down
2 changes: 2 additions & 0 deletions docs/agent/log.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ conventional commits, what needs a device — are in

## Runs

- **2026-10-08** — **Shipped 0.2.9** (the #36 `onDimensions` fix) to npm with provenance. npm's homepage now points at the site. The Release workflow's AI-notes step failed with `credit balance is too low` from the Anthropic API. It's `continue-on-error`, so the publish went through, but the release kept release-please's plain notes. Re-running the Release job can't fix that: the notes step comes after `npm publish`, which refuses a version that already exists. Fixed two ways. In `release.yml` the notes now run as their own `notes` job after `publish`, without `continue-on-error`: a failure shows red without touching the release, and "Re-run failed jobs" retries only the notes. `publish` drops to `contents: read`. Added `.github/workflows/release-notes.yml` (manual dispatch with a `tag` input) for releases cut before the split: `gh workflow run release-notes.yml -f tag=v0.2.9`.

- **2026-10-07** — **Public site and demo video** (`website/`, deployed by `.github/workflows/pages.yml`; README GIF closes #28). Design and plan: [`plans/2026-10-07-public-website-and-demo-video.md`](plans/2026-10-07-public-website-and-demo-video.md). Re-cut the video with `website/scripts/make-demo.sh <capture> <ending>`. The source recordings aren't in the repo, and the capture recording's own ending shows pre-#50 sizes, which the script cuts. Cloudflare Web Analytics beacon in the page. It reports only from `tristanheilman.github.io`, so localhost shows a CORS error, which is expected. A final review found two Important issues: the size tile disagreed with the video, and `og:image` was relative. Both fixed, plus 320 px overflow (upgraded from Minor because Display Zoom iPhones use 320). **Deferred minors, for the owner:** the tile label says `onDimensions` where the public API is `addDimensionsListener`; the copy-fallback label 'Press ⌘C' assumes a Mac; 'Expo works too' could read as Expo Go (it needs prebuild/dev client); `make-demo.sh` has no usage message and its `stat -f%z` is macOS-only.

- **2026-10-07** — **#36 verified and fixed: `onDimensions` reported the capture volume, not the object.** Scanned a tissue box measured at ~22 × 11 × 12.5 cm. The USDZ was right (22.8 × 12.8 × 13.5 via `usdcat` and ModelIO), and native and JS agreed exactly, so the bridge was fine. But the value itself was 44.5 × 22.2 × 28.9: it came from the `.bounds` request, which returns the detection box plus padding. Now measured from the written model with `MDLAsset(url:).boundingBox`, and verified on device: 23.1 × 12.5 × 13.2. Handy: `swift` scripts can run ModelIO on the Mac against a USDZ pulled with `devicectl device copy from`, which checks a measurement before any device run. **Watch for: a RealityKit crash** — SIGTRAP, `assertion failure: (m_size > 0) Queue<T> is empty` in `re::AssetManager::updateLoadRequests`, while the scan screen first renders (right after session state `ready`). No library frames on the stack. It hit 2 of about 6 launches on the fix build, with the phone at ~12% battery (Low Power Mode likely on). It didn't reproduce on 3 opens of the previous build, or later on the fix build once charged. If it recurs, record battery and Low Power state, and pull `systemCrashLogs` with `devicectl` to compare signatures.
Expand Down
Loading