Skip to content

Promote dev to master: post-3.3.0 fixes for 3.3.1 - #400

Merged
AminDhouib merged 16 commits into
masterfrom
dev
Sep 11, 2026
Merged

AminDhouib merged 16 commits into
masterfrom
dev

Conversation

@AminDhouib

Copy link
Copy Markdown
Member

Promotes dev (c7b681de) to master.

Included since the last promotion (#383):

Changesets from #389/#396/#397/#398 will fold into the Version Packages PR (#384) on merge; 3.3.1 is published only when #384 is merged.

…onsumers install

core declares libheif-js as an optionalDependency with `^1.19.8`. The
workspace lockfile pinned 1.19.8, but a lockfile-less install — the
package smoke consumer, and every real user — resolves 1.23.2, the
newest 1.x. So the HEIC integration suite proved a decoder that nobody
installs, and `smoke:packages` installs 1.23.2 but only measures bundle
shape and size (assertConsumerBundleShape never executes a decode).
Nothing in CI exercised the version users actually get.

Verified before pinning: 1.23.2 decodes the repo's real 64x64 HEIC
fixture through heic-decode.ts unchanged — same module shape (default
factory), same HeifDecoder/decode/display/free API, 406 source bytes ->
64x64 -> a 785-byte JPEG with valid SOI/EOI markers, byte-for-byte the
same result as 1.19.8.

Applied as a three-hunk lockfile edit rather than through pnpm: both
`pnpm update libheif-js --filter @useupup/core` and
`pnpm add libheif-js@^1.19.8 --filter @useupup/core --save-optional`
re-resolved unrelated peer graphs (1194-2828 changed lines, including a
vitest 4.1.11 -> 4.1.2 downgrade), and the first also rewrote core's
manifest range. A control `pnpm install` with no dependency change
produced no diff, so the churn came from the re-resolution, not from
lockfile drift. `pnpm install --frozen-lockfile` accepts the edited
lockfile — it refuses to rewrite one — which is what proves it
self-consistent.

core's `^1.19.8` range is unchanged, so consumers receive exactly what
they did before; this moves only what we test.
Sync dev with master after the #383 promotion
…kfile

chore(deps): pin libheif-js 1.23.2 in the lockfile so CI tests what consumers install
A pre-existing security-review notice flagged mutable action tags. Every
`uses:` across .github/workflows is now pinned to a 40-char commit SHA with
the resolved version in a trailing comment:

- actions/upload-artifact@v4 -> ea165f8d # v4.6.2 (main, e2e, nightly).
  v4 currently resolves to the same commit as v4.6.2, so this is a no-op
  behaviorally; it just stops the tag from moving under us.
- publish-sdk.yml's actions/checkout@v7 / actions/setup-node@v7 -> the same
  SHAs the other workflows already pin (v7.0.1 / v7.0.0).

Actions that were already SHA-pinned are untouched, as is changesets/action
(pinned at v1.9.0 because its major is coupled to the Changesets CLI major).

publish-sdk.yml also picks up a whole-file prettier reformat: it was
committed with 2-space indentation against this repo's 4-space prettier
config, so it has been failing `prettier --check` since it landed. CI never
caught it because prettier-check is scoped to packages/*/src; staging the
file for the pin change put it in front of lint-staged, which does check it.
The old comment asserted that every @useupup package already had its npm
trusted publisher configured, dated 2026-08-01. That claim was false for
@useupup/server until today, and a dated "this is already done" note decays
the moment a package is added or a scope moves.

Reworded as a standing precondition instead of a status report: publishing is
OIDC-only; every @useupup package must have a trusted publisher (GitHub
Actions, DevinoSolutions/upup, workflow publish.yml); a package without one
fails its own publish and therefore the job, but its version number is not
burned, so the fix is to add the publisher and re-run; verify each package's
npm access page before merging a Version Packages PR.

The npm-upgrade-after-setup-node ordering note is preserved verbatim in
substance — it is the other half of why this step is shaped the way it is.
…r flow

Two staleness fixes in the operating guide:

- The npm scope moved to @useupup on 2026-09-02, but CLAUDE.md still named
  @upupjs/* in 34 places (package map, principles, gates, test paths, subpath
  examples). Swept with an exact-substring codemod over every line outside the
  "Naming vocabulary" scope-history bullet, which deliberately narrates the
  @upupjs era and is preserved verbatim. The only surviving `upupjs` tokens in
  the file are that bullet's three, which is also why vocab:check's scan roots
  exclude this file.
- The "Git & commits" section still described `v2-clean` as the integration
  branch and forbade touching master. Replaced with the model actually in use:
  master is production/release (publish.yml runs on push to master), dev is
  the integration branch, feature branches PR into dev, dev is promoted to
  master via a dev->master PR and master is synced back with a master->dev PR,
  and PRs merge with --admin because self-approval is impossible here.

Remaining bullets in that section (conventional commits, explicit staging,
docs/superpowers, the hooks) are unchanged.
chore: post-release hygiene — action SHA pins, publish.yml precondition, CLAUDE.md sweep
…dFileTypes

A host that set allowedFileTypes to a type no capture source can produce
still got camera/microphone/screen chips in the default source set, and
every recording they made was rejected on add (#340).

normalizeUploaderOptions now drops a DEFAULT capture source when no entry
in the resolved accept list could match anything that source emits. The
declared output sets come from the code that builds the File: camera
image/jpeg (plus image/png, the toDataURL fallback), microphone
audio/webm|ogg|mp4, screen video/webm|mp4.

The matcher fails open - a wildcard, an extension it cannot classify, or
an entry that is neither a MIME type nor an extension keeps every source.
local and url are never filtered, cloud drives are unaffected, and an
explicit sources array is honored verbatim. Each dropped source logs one
dev-only console.warn.
stripExifData skips animated GIF/WebP/APNG because canvas has no animated
encoder, so those files reach storage with the metadata the host asked to
remove - and animated WebP and APNG both carry EXIF. The skip was silent,
so a privacy-sensitive host had no way to detect it (#367 item 4).

The exif step now records it on the file: metadata.metadataStripSkipped
true with metadata.metadataStripSkippedReason 'animated-image', using the
same assign-a-new-metadata-object shape the thumbnail step already uses.
No new event, no new option.

The compress step deliberately does NOT set it: nothing was asked to be
removed there, so the marker would be a false privacy signal.
…e string

A failure carrying a machine code rendered as uploadFailedWithCode, which
interpolated the code and nothing else - so an endpoint that returned a
useful sentence watched it disappear between onError and the panel (#367
item 2).

The key gains a second {message} slot fed from the error's own message, and
all nine locale bundles carry both slots so translators control placement:
overriding the key can reorder them, drop the code, or show only the host's
wording. All six framework panels pass both values identically (react is
the canon; preact re-exports it), and the value renders as a text node, so
a markup-looking message is never interpreted.

The empty-message case cannot render: every framework already gates the
upload-error slot on a truthy uploadError, which is pinned by the react
suite - so no second key variant is needed.
fix(core): hide default capture sources that can never satisfy allowedFileTypes
fix(core): host error message slot and EXIF-skip signal (#367 items 2, 4)
Two UI fixes across React and its five DOM-identical ports.

#352 part 2 — the compact FileRow wrapped ProgressBar in a second `!!progress`
gate. ProgressBar already self-gates on `progress || isUploadActive(status)`,
so the outer wrapper only ever subtracted: between "run started" and "first
byte acknowledged" the list row stayed blank while the grid tile, the hero and
the list footer all showed their bars. Removing the wrapper (not rewriting the
condition) leaves one gate, inside ProgressBar. Idle is unchanged — no
progress, no active run, still no bar — so parity fixtures do not move.

#229 — the four base64 PNG logos in src/assets/logos.ts shipped at up to
1905x580 for a fixed 61x13 CSS-pixel box. They are re-exported at 122x26 (2x
the rendered box, palette-quantized where that wins, alpha kept), regenerated
once and copied byte-identically into all five packages. Per-file: 167 KB to
13 KB; about 109 KB gzipped off every UI bundle. Rendered appearance is
unchanged, including the existing horizontal squash of the devino wordmark,
which the fixed-size box already applied.
Four comment-only corrections. No SHA, no workflow logic, no code changes.

The 23 `pnpm/action-setup@0977fd99` pins across e2e, main, nightly and publish
were all annotated `# v4.4.0`. That SHA is v6.0.10: the annotated tag
refs/tags/v6.0.10 is ff378ebe, which dereferences to commit 0977fd99 (PGP
signature verified). Since the pin is what actually runs, the comment was
understating the action by two majors to anyone reading or reviewing it.

CLAUDE.md's lint gate claimed "3 apps (playground, landing, docs)". There is no
apps/docs — the docs moved into apps/landing — and only landing and playground
define a `lint` script, so the leaf count is 2.

publish-sdk.yml's header said this repo's release flow "publishes the root
`upup` package". Root package.json is `name: upup`, `private: true`, and is
never published; changesets publishes the nine `@useupup/*` workspace packages.
The point the sentence was making — that this workflow must never fire as a
side effect of the release flow — is preserved and now rests on a true premise.

CLAUDE.md's package map had no entry for `sdk/` at all, leaving a publishable
directory and a second publish workflow undocumented. Added as a name
reservation: `@useupup/sdk@0.0.1`, outside the pnpm workspace globs, outside the
changesets release, workflow_dispatch only, maintainer decision to touch.
fix(ui): drop redundant progress wrapper and shrink branding logo assets (#352, #229)
chore: correct action pin comments and stale doc statements
@codesandbox

codesandbox Bot commented Sep 11, 2026

Copy link
Copy Markdown

Review or Edit in CodeSandbox

Open the branch in Web EditorVS CodeInsiders

Open Preview

@AminDhouib
AminDhouib merged commit 2464bb8 into master Sep 11, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant