Files
buzz/desktop/scripts/demo-build-config.test.mjs
Logan Johnson 4a9de1a3a1 feat(desktop): add isolated named demo builds (#6407)
🤖 I’m Larry, updating this description on Logan’s behalf.

## Summary

Build named macOS demo apps without Finder automation or collisions with
installed Buzz. `just desktop-demo-build "PR 6407 Demo"` produces a
matching app and DMG, with a fresh build identity even when the same
display name is reused.

- The headless DMG packager uses `hdiutil`; optional Finder styling is
bounded. The existing production release recipe is unchanged.
- Each demo has independent app data, keychain, nest, CLI name,
voice-model storage, repository discovery, and agent OAuth/config
storage. Reset preserves production and sibling-demo state, and retains
retry intent when credential removal or root resolution fails.
- Native links accept only the active build’s registered scheme, then
translate validated entity links into the frontend’s canonical `buzz:`
format.
- The recipe builds all six executable sidecars. Display names are
capped at 31 ASCII characters so the generated identity fits Rust’s
build-time limit.

**Open delivery requirement:** downloaded demos must run without a
Gatekeeper security override. The current recipe is ad-hoc signed and
unnotarized; it does **not** satisfy this requirement. Trusted
branch-demo signing/distribution remains blocked on establishing an
approved signing path. This PR is not being presented as complete
download-and-run delivery.

### Related issue

N/A — reported in the Buzz DMG-packaging workstream.

### Testing

At `11ce21ff97cb387ad676e7caa65b00964097d0bb`, macOS Blox passed the
Tauri workspace suite and compiled-flags gate (including the full
named-demo state; each library pass: 2,992 passed, 19 ignored), Tauri
all-target clippy, the full `buzz-agent` package suite, and frontend
lint/typecheck plus 5,733 tests. Regression coverage includes
cold-start/running entity-link handling, wrong-build rejection, OAuth
deletion failure and retry, unresolved credential roots, and
production/sibling preservation.

At the same head, an extra full named-demo/mesh-enabled run had 3,092
passing tests and one failure: a pre-existing shared-compute `auto`
versus `mesh` expectation, also reproduced on the old published head
`a77b25eca`. The ordinary and demo-state matrix above passes; this is
not an all-features-green claim. Live macOS Launch Services delivery
remains unverified.

GitHub CI completed with 30 successful checks and 9 skipped. The
exact-range security review has not run; its authorization notice
remains open. CI success does not establish trusted signing or
downloaded-app launch.

Earlier demo artifacts established matching app/DMG names, side-by-side
launch, and six non-empty executable arm64 sidecars. These screenshots
show an earlier artifact, not a new build of the final repair commit.
Signature-integrity checks are not Gatekeeper/notarization evidence.

<img width="1032" height="548" alt="Buzz PR 6407 Demo disk image
containing the matching app"
src="https://github.com/user-attachments/assets/bca0277e-db03-4308-b280-fcad55e6d601"
/>

<img width="1186" height="821" alt="Buzz PR 6407 Demo running alongside
other Buzz installations"
src="https://github.com/user-attachments/assets/b4bf4ae5-c341-4e15-8090-9d2ea7c623b6"
/>

---------

Signed-off-by: Logan Johnson <loganj@squareup.com>
Signed-off-by: Larry <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz>
Co-authored-by: Other Brother Darryl <cee32d92756729ee0c097c5661b879c6199931cd25315c8cf398dcbf0f155cf1@buzz.block.builderlab.xyz>
Co-authored-by: Larry <loganj+sandbox-larry@squareup.com>
Co-authored-by: Larry <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz>
2026-08-31 21:14:19 -04:00

135 lines
3.7 KiB
JavaScript

import assert from "node:assert/strict";
import test from "node:test";
import {
demoBuildConfig,
productionBuildIdentity,
} from "./demo-build-config.mjs";
const expected = (name, slug) => ({
name,
slug,
productName: `Buzz ${name}`,
dmgVolumeName: `Buzz ${name}`,
dmgFileStem: `Buzz_${name.replace(/ /g, "_")}`,
identifier: `xyz.block.buzz.app.demo.${slug}`,
appDataIdentity: `xyz.block.buzz.app.demo.${slug}`,
deepLinkScheme: `buzz-demo-${slug}`,
keyringService: `buzz-desktop-demo.${slug}`,
nestName: `.buzz-demo-${slug}`,
cliName: `buzz-demo-${slug}`,
tauriConfig: {
productName: `Buzz ${name}`,
identifier: `xyz.block.buzz.app.demo.${slug}`,
plugins: { "deep-link": { desktop: { schemes: [`buzz-demo-${slug}`] } } },
bundle: { targets: ["app"] },
},
});
test("production identity remains unchanged", () => {
assert.deepEqual(productionBuildIdentity, {
productName: "Buzz",
identifier: "xyz.block.buzz.app",
deepLinkScheme: "buzz",
keyringService: "buzz-desktop",
nestName: ".buzz",
cliName: "buzz",
});
});
test("two demo names produce complete, distinct identities", () => {
const board = demoBuildConfig("Workstream Board", "27a4294c27a4294c");
const interests = demoBuildConfig("Interests Demo", "deb5339adeb5339a");
assert.deepEqual(
board,
expected("Workstream Board", "workstream-board-27a4294c27a4294c"),
);
assert.deepEqual(
interests,
expected("Interests Demo", "interests-demo-deb5339adeb5339a"),
);
for (const key of [
"productName",
"dmgVolumeName",
"dmgFileStem",
"identifier",
"appDataIdentity",
"deepLinkScheme",
"keyringService",
"nestName",
"cliName",
]) {
assert.notEqual(board[key], interests[key], key);
assert.notEqual(board[key], productionBuildIdentity[key], key);
}
});
test("normalized spelling aliases retain distinct runtime identities", () => {
for (const [leftName, rightName] of [
["A B", "A-B"],
["Demo", "demo"],
["Workstream Board", "WORKSTREAM BOARD"],
]) {
const left = demoBuildConfig(leftName, "1111111111111111");
const right = demoBuildConfig(rightName, "2222222222222222");
assert.notEqual(left.slug, right.slug);
for (const key of [
"identifier",
"appDataIdentity",
"deepLinkScheme",
"keyringService",
"nestName",
"cliName",
]) {
assert.notEqual(
left[key],
right[key],
`${leftName}/${rightName}: ${key}`,
);
}
}
});
test("the same display name gets a distinct identity for each build", () => {
const first = demoBuildConfig("Demo", "1111111111111111");
const second = demoBuildConfig("Demo", "2222222222222222");
assert.equal(first.productName, second.productName);
assert.equal(first.dmgFileStem, second.dmgFileStem);
for (const key of [
"slug",
"identifier",
"appDataIdentity",
"deepLinkScheme",
"keyringService",
"nestName",
"cliName",
]) {
assert.notEqual(first[key], second[key], key);
}
});
test("whitespace normalization preserves deterministic identity", () => {
assert.deepEqual(
demoBuildConfig(" Workstream Board ", "27a4294c27a4294c"),
demoBuildConfig("Workstream Board", "27a4294c27a4294c"),
);
});
test("maximum-length name produces a Rust-valid 48-byte slug", () => {
const config = demoBuildConfig("x".repeat(31), "1234567812345678");
assert.equal(config.slug.length, 48);
assert.match(config.slug, /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/);
});
for (const name of [
"",
" ",
"Workstream/Board",
"Workstream_Board",
"équipe",
"x".repeat(32),
]) {
test(`rejects unusable name ${JSON.stringify(name)}`, () =>
assert.throws(() => demoBuildConfig(name, "1234567812345678")));
}