@bongos/core 1.19.884 → 1.19.886

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/.bongos-core.json +20 -285
  2. package/docs/architecture.md +0 -1
  3. package/docs/file-map.md +0 -1
  4. package/docs/module-api-changelog.md +4 -0
  5. package/package-lock.json +2 -2
  6. package/package.json +1 -1
  7. package/scripts/gds/gen-session-index.js +8 -1
  8. package/src/bongos/serve-internal.js +10 -56
  9. package/src/module-api.js +1 -1
  10. package/src/platform-server.js +0 -1
  11. package/tests/host_topology_skips.mjs +0 -1
  12. package/tests/instance_release_config.mjs +27 -26
  13. package/tests/session_rename_fallback.mjs +8 -90
  14. package/modules/dev-box/app/README.md +0 -74
  15. package/modules/dev-box/app/assets/tray/mac-alertTemplate.png +0 -0
  16. package/modules/dev-box/app/assets/tray/mac-alertTemplate@2x.png +0 -0
  17. package/modules/dev-box/app/assets/tray/mac-busyTemplate.png +0 -0
  18. package/modules/dev-box/app/assets/tray/mac-busyTemplate@2x.png +0 -0
  19. package/modules/dev-box/app/assets/tray/mac-offTemplate.png +0 -0
  20. package/modules/dev-box/app/assets/tray/mac-offTemplate@2x.png +0 -0
  21. package/modules/dev-box/app/assets/tray/mac-onTemplate.png +0 -0
  22. package/modules/dev-box/app/assets/tray/mac-onTemplate@2x.png +0 -0
  23. package/modules/dev-box/app/assets/tray/win-alert.png +0 -0
  24. package/modules/dev-box/app/assets/tray/win-busy.png +0 -0
  25. package/modules/dev-box/app/assets/tray/win-off.png +0 -0
  26. package/modules/dev-box/app/assets/tray/win-on.png +0 -0
  27. package/modules/dev-box/app/build-resources/dmg-background.png +0 -0
  28. package/modules/dev-box/app/build-resources/dmg-background@2x.png +0 -0
  29. package/modules/dev-box/app/build-resources/icon.png +0 -0
  30. package/modules/dev-box/app/electron-builder.tmpl.yml +0 -95
  31. package/modules/dev-box/app/electron-builder.yml +0 -95
  32. package/modules/dev-box/app/package-lock.json +0 -5291
  33. package/modules/dev-box/app/package.json +0 -30
  34. package/modules/dev-box/app/renderer/app.js +0 -319
  35. package/modules/dev-box/app/renderer/index.html +0 -45
  36. package/modules/dev-box/app/renderer/styles.css +0 -248
  37. package/modules/dev-box/app/renderer/theme.generated.css +0 -16
  38. package/modules/dev-box/app/scripts/apply-dmg-backdrop.sh +0 -82
  39. package/modules/dev-box/app/scripts/dmgbuild-settings.py +0 -39
  40. package/modules/dev-box/app/scripts/gen-brand.js +0 -138
  41. package/modules/dev-box/app/scripts/gen-dmg-backdrop.py +0 -323
  42. package/modules/dev-box/app/scripts/gen-icons.js +0 -286
  43. package/modules/dev-box/app/scripts/vendor-client.js +0 -23
  44. package/modules/dev-box/app/src/box-controller.js +0 -287
  45. package/modules/dev-box/app/src/brand.generated.json +0 -13
  46. package/modules/dev-box/app/src/brand.js +0 -16
  47. package/modules/dev-box/app/src/config.js +0 -31
  48. package/modules/dev-box/app/src/gds-client.js +0 -96
  49. package/modules/dev-box/app/src/main.js +0 -610
  50. package/modules/dev-box/app/src/pairing.js +0 -57
  51. package/modules/dev-box/app/src/preload.js +0 -29
  52. package/modules/dev-box/app/src/session-store.js +0 -82
  53. package/modules/dev-box/app/src/ssh-setup.js +0 -569
  54. package/modules/dev-box/app/src/task-picker.js +0 -70
  55. package/modules/dev-box/app/src/tray.js +0 -99
  56. package/modules/dev-box/app/src/updater.js +0 -55
  57. package/modules/dev-box/app/src/vendor/bongos-client.cjs +0 -1014
  58. package/modules/dev-box/app/test/unit.mjs +0 -526
  59. package/src/devbox-downloads.js +0 -67
  60. package/tests/devbox_artifact_gate.mjs +0 -75
  61. package/tests/devbox_dmg_backdrop.mjs +0 -137
  62. package/tests/devbox_downloads.mjs +0 -140
  63. package/tests/devbox_icons.mjs +0 -304
  64. package/tests/devbox_installer_brand.mjs +0 -232
  65. package/tests/devbox_key_register.mjs +0 -234
  66. package/tests/devbox_update_path.mjs +0 -84
@@ -1,15 +1,16 @@
1
1
  // tests/instance_release_config.mjs
2
2
  //
3
- // serve-internal mounts /downloads/devbox/* and /downloads/bongos/* only when the
4
- // instance ships the matching RELEASE config (config/devbox-app.json,
5
- // config/bongos-cli.json). Those configs are boundary-EXCLUDED from the packaged core,
3
+ // serve-internal mounts /downloads/bongos/* only when the instance ships the matching
4
+ // RELEASE config (config/bongos-cli.json). That config is boundary-EXCLUDED from the packaged core,
6
5
  // so they live at the INSTANCE root — which on a vendored instance (@bongos/core in
7
6
  // node_modules, ADR 0108) is a DIFFERENT directory from the core package dir
8
7
  // serve-internal.js sits in. The old core-relative `require('../../config/…')` looked
9
- // only in node_modules/@bongos/core/config/, so a vendored instance's Dev Box download
10
- // routes never mounted (task 1002371; ADR 0145 papered over it by copying the config
11
- // into node_modules — lost on the next npm ci). Same class as ADR 0144's vendored
12
- // infra/ path bug.
8
+ // only in node_modules/@bongos/core/config/, so a vendored instance's download routes
9
+ // never mounted (task 1002371; ADR 0145 papered over it by copying the config into
10
+ // node_modules — lost on the next npm ci). Same class as ADR 0144's vendored infra/
11
+ // path bug. This test was written against the /downloads/devbox/* twin, which task
12
+ // 1003891 deleted with the Dev Box app; it now proves the SAME ladder against
13
+ // /downloads/bongos/*, the surviving surface that still depends on it.
13
14
  //
14
15
  // The first test is THE regression: a config present ONLY at the instance root must be
15
16
  // found. It fails against the old resolution (which could not see the instance root at
@@ -29,12 +30,12 @@ import path from 'node:path';
29
30
 
30
31
  const require = createRequire(import.meta.url);
31
32
 
32
- // A minimal but VALID release config — buildDevboxDownloads rejects a bad
33
+ // A minimal but VALID release config — buildBongosDownloads rejects a bad
33
34
  // releases_repo/version at boot, so the end-to-end mount below proves real parsing.
34
- const DEVBOX_CFG = {
35
- releases_repo: 'example-owner/example-devbox',
35
+ const CLI_CFG = {
36
+ releases_repo: 'example-owner/example-cli',
36
37
  version: '9.9.9',
37
- assets: { 'mac-arm64': 'Example-Dev-Box-9.9.9-arm64.dmg' },
38
+ assets: { 'mac-arm64': 'bongos-9.9.9-macos-arm64' },
38
39
  aliases: { mac: 'mac-arm64' },
39
40
  };
40
41
 
@@ -50,23 +51,23 @@ function makeRoot(name, contents) {
50
51
 
51
52
  // Point the process at a temp INSTANCE root BEFORE serve-internal loads, so the default
52
53
  // (uninjected) resolution runs the vendored shape: config at the instance root, absent
53
- // from the core package dir. This checkout ships no config/devbox-app.json — it is
54
+ // from the core package dir. This checkout ships no config/bongos-cli.json — it is
54
55
  // instance-only — so the core tier genuinely has nothing to find, exactly like a
55
56
  // freshly-vendored box.
56
- const INSTANCE_ROOT = makeRoot('devbox-app.json', JSON.stringify(DEVBOX_CFG));
57
+ const INSTANCE_ROOT = makeRoot('bongos-cli.json', JSON.stringify(CLI_CFG));
57
58
  process.env.CLOUDBONGOS_INSTANCE_ROOT = INSTANCE_ROOT;
58
59
  const { tryLoadInstanceConfig, mountInternalSurfaces } = require('../src/bongos/serve-internal.js');
59
60
 
60
61
  test('finds a release config that exists ONLY at the instance root (the vendored bug)', () => {
61
- const instance = makeRoot('devbox-app.json', '{"version":"1.0.0"}');
62
+ const instance = makeRoot('bongos-cli.json', '{"version":"1.0.0"}');
62
63
  const core = makeRoot(null);
63
- assert.deepEqual(tryLoadInstanceConfig('devbox-app.json', [instance, core]), { version: '1.0.0' });
64
+ assert.deepEqual(tryLoadInstanceConfig('bongos-cli.json', [instance, core]), { version: '1.0.0' });
64
65
  });
65
66
 
66
67
  test('the instance root wins over the core package dir when both carry a copy', () => {
67
- const instance = makeRoot('devbox-app.json', '{"from":"instance"}');
68
- const core = makeRoot('devbox-app.json', '{"from":"core"}');
69
- assert.equal(tryLoadInstanceConfig('devbox-app.json', [instance, core]).from, 'instance');
68
+ const instance = makeRoot('bongos-cli.json', '{"from":"instance"}');
69
+ const core = makeRoot('bongos-cli.json', '{"from":"core"}');
70
+ assert.equal(tryLoadInstanceConfig('bongos-cli.json', [instance, core]).from, 'instance');
70
71
  });
71
72
 
72
73
  test('falls back to the core package dir (single checkout + the copied-in workaround)', () => {
@@ -76,16 +77,16 @@ test('falls back to the core package dir (single checkout + the copied-in workar
76
77
  });
77
78
 
78
79
  test('absent from every root → null, so the download surface just does not mount', () => {
79
- assert.equal(tryLoadInstanceConfig('devbox-app.json', [makeRoot(null), makeRoot(null)]), null);
80
- assert.equal(tryLoadInstanceConfig('devbox-app.json', []), null);
80
+ assert.equal(tryLoadInstanceConfig('bongos-cli.json', [makeRoot(null), makeRoot(null)]), null);
81
+ assert.equal(tryLoadInstanceConfig('bongos-cli.json', []), null);
81
82
  });
82
83
 
83
84
  test('a MALFORMED config still throws — only a MISSING file is tolerated', () => {
84
- const bad = makeRoot('devbox-app.json', '{ this is not valid json ');
85
- assert.throws(() => tryLoadInstanceConfig('devbox-app.json', [bad]), SyntaxError);
85
+ const bad = makeRoot('bongos-cli.json', '{ this is not valid json ');
86
+ assert.throws(() => tryLoadInstanceConfig('bongos-cli.json', [bad]), SyntaxError);
86
87
  });
87
88
 
88
- test('/downloads/devbox/version mounts from an INSTANCE-root config (end to end)', async () => {
89
+ test('/downloads/bongos/version mounts from an INSTANCE-root config (end to end)', async () => {
89
90
  const express = require('express');
90
91
  const app = express();
91
92
  mountInternalSurfaces(app);
@@ -93,11 +94,11 @@ test('/downloads/devbox/version mounts from an INSTANCE-root config (end to end)
93
94
  const s = app.listen(0, () => resolve(s));
94
95
  });
95
96
  try {
96
- const res = await fetch(`http://127.0.0.1:${server.address().port}/downloads/devbox/version`);
97
+ const res = await fetch(`http://127.0.0.1:${server.address().port}/downloads/bongos/version`);
97
98
  assert.equal(res.status, 200, 'the route must mount when only the INSTANCE root has the config');
98
99
  const body = await res.json();
99
- assert.equal(body.version, DEVBOX_CFG.version);
100
- assert.match(body.assets['mac-arm64'], /^https:\/\/github\.com\/example-owner\/example-devbox\//);
100
+ assert.equal(body.version, CLI_CFG.version);
101
+ assert.match(body.assets['mac-arm64'], /^https:\/\/github\.com\/example-owner\/example-cli\//);
101
102
  } finally {
102
103
  await new Promise((r) => server.close(r));
103
104
  }
@@ -12,9 +12,9 @@
12
12
  // So these tests assert the FALLBACK path fires — a happy-path test on the new name alone would
13
13
  // pass just as well with the back-compat deleted, which is exactly the regression that matters.
14
14
  //
15
- // Three of the read-lists are DUPLICATED rather than imported, because their modules cannot reach
16
- // the canonical one (dependency-free middleware, a separately-bundled Electron app). Those copies
17
- // are pinned here against the real list by parsing the source — an unpinned copy is how a rename
15
+ // Some of the read-lists are DUPLICATED rather than imported, because their modules cannot reach
16
+ // the canonical one (dependency-free middleware, static browser surfaces). Those copies are
17
+ // pinned here against the real list by parsing the source — an unpinned copy is how a rename
18
18
  // half-lands.
19
19
 
20
20
  import test from 'node:test';
@@ -235,6 +235,11 @@ test('routes/auth.js sets ONLY the head name and derives the clear-list from the
235
235
  });
236
236
 
237
237
  // ── 5. the duplicated copies are pinned to the canonical lists ──────────────────────────────
238
+ //
239
+ // There used to be a third copy here and a whole section 7 exercising it: the Dev Box Electron
240
+ // app shipped as its own bundle, so it could not import instance-config and carried its own
241
+ // read-list. Task 1003891 deleted that app, so the copy it was pinned against no longer exists
242
+ // and the cases went with it — there is nothing left to drift.
238
243
 
239
244
  test('rate-limit.js — its dependency-free copy of the cookie names matches the real list', () => {
240
245
  const src = read('src/bongos/middleware/rate-limit.js');
@@ -245,19 +250,6 @@ test('rate-limit.js — its dependency-free copy of the cookie names matches the
245
250
  'the limiter’s copy drifted from src/bongos/auth.js SESSION_COOKIE_NAMES');
246
251
  });
247
252
 
248
- test('dev-box session-store — its bundled copy of the filenames matches the real list', () => {
249
- const src = read('modules/dev-box/app/src/session-store.js');
250
- const head = /const FILE = path\.join\(DIR, '([^']+)'\)/.exec(src);
251
- assert.ok(head, 'FILE not found in the dev-box session store');
252
- const legacy = /const FILES_LEGACY = \[([^\]]*)\]/.exec(src);
253
- assert.ok(legacy, 'FILES_LEGACY not found — the app would stop reading un-migrated sessions');
254
- const names = [head[1], ...[...legacy[1].matchAll(/'([^']+\.json)'/g)].map((x) => x[1])];
255
- assert.deepEqual(names, ic.SESSION_FILENAMES,
256
- 'the dev-box app’s copy drifted from src/instance-config.js SESSION_FILENAMES');
257
- // It must WRITE only the head name.
258
- assert.doesNotMatch(src, /writeFileSync\(\s*FILES_LEGACY/, 'the app must never write a legacy name');
259
- });
260
-
261
253
  test('the browser logout clears every session-cookie name', () => {
262
254
  // Three static surfaces expire the cookie client-side. One that misses the current name leaves a
263
255
  // live cookie behind after "sign out".
@@ -288,80 +280,6 @@ test('the baked box scripts scan BOTH session filenames', () => {
288
280
  }
289
281
  });
290
282
 
291
- // ── 7. the dev-box app's own copy of the fallback, and its sign-out ─────────────────────────
292
- //
293
- // The Electron app shares the CLI's session file on purpose (ADR 0045). It ships as its own
294
- // bundle, so it cannot import instance-config and carries its own read-list — which means its
295
- // fallback needs exercising, not just pinning.
296
- function inDevBoxSandbox(body) {
297
- const home = fs.mkdtempSync(path.join(os.tmpdir(), 'bongos-devbox-'));
298
- try {
299
- const code = `const R=${JSON.stringify(REPO_ROOT)};
300
- const SANDBOX=${JSON.stringify(home)};
301
- const os=require('node:os');
302
- if (os.homedir() !== SANDBOX) {
303
- console.error('ERR sandbox-escape: os.homedir()=' + os.homedir() + ' but the sandbox is ' + SANDBOX);
304
- process.exit(2);
305
- }
306
- const fs=require('node:fs'), path=require('node:path');
307
- const brand=require(R+'/modules/dev-box/app/src/brand.js');
308
- const CFG=path.join(os.homedir(), '.config', brand.CONFIG_DIR);
309
- const store=require(R+'/modules/dev-box/app/src/session-store.js');
310
- const w=(name,obj)=>{fs.mkdirSync(CFG,{recursive:true});fs.writeFileSync(path.join(CFG,name),JSON.stringify(obj,null,2));};
311
- const has=(name)=>fs.existsSync(path.join(CFG,name));
312
- const j=(name)=>JSON.parse(fs.readFileSync(path.join(CFG,name),'utf8'));
313
- (async()=>{ ${body} })().catch((e)=>{ console.error('ERR '+e.message); process.exit(1); });`;
314
- const r = spawnSync(process.execPath, ['-e', code], { encoding: 'utf8', env: sandboxEnv(home) });
315
- return { out: `${r.stdout || ''}${r.stderr || ''}`, status: r.status };
316
- } finally {
317
- fs.rmSync(home, { recursive: true, force: true });
318
- }
319
- }
320
-
321
- test('dev-box: reads an old-name session, and writes migrate to the new name', () => {
322
- const { out, status } = inDevBoxSandbox(`
323
- w('gds-session.json', { token:'TOK-OLD', api_base:'https://x.example.com', gemini_api_key:'KEEP' });
324
- const got = store.read();
325
- store.write({ token:'TOK-NEW', apiBase:'https://x.example.com' });
326
- console.log(JSON.stringify({
327
- readOld: got && got.token,
328
- newFile: has('bongos-session.json') && j('bongos-session.json').token,
329
- keptExtra: has('bongos-session.json') && j('bongos-session.json').gemini_api_key,
330
- oldKept: has('gds-session.json'),
331
- }));`);
332
- assert.equal(status, 0, out);
333
- const r = JSON.parse(out.trim().split('\n').pop());
334
- assert.equal(r.readOld, 'TOK-OLD', 'the app must still read an un-migrated session');
335
- assert.equal(r.newFile, 'TOK-NEW', 'a write must land on the new name');
336
- assert.equal(r.keptExtra, 'KEEP', 'merge-preserving write must carry unknown fields across the rename');
337
- assert.equal(r.oldKept, true, 'the app must not delete the old file either');
338
- });
339
-
340
- test('dev-box: sign-out strips the credential from EVERY accepted filename', () => {
341
- // THE BUG THIS PINS. clear() rewrote only the CURRENT filename, but read() falls through to an
342
- // older name when the current file carries no token — so sign-out left a live token in the
343
- // superseded file and the very next read signed the builder straight back in. Harmless while
344
- // the only legacy name was the long-dead pms-session.json; the common case the moment
345
- // gds-session.json joined the read-list (task 1003704).
346
- const { out, status } = inDevBoxSandbox(`
347
- w('bongos-session.json', { token:'TOK-NEW', api_base:'https://x.example.com' });
348
- w('gds-session.json', { token:'TOK-OLD', api_base:'https://x.example.com', gemini_api_key:'KEEP' });
349
- store.clear();
350
- console.log(JSON.stringify({
351
- stillSignedIn: !!store.read(),
352
- newToken: j('bongos-session.json').token ?? null,
353
- oldToken: j('gds-session.json').token ?? null,
354
- keptExtra: j('gds-session.json').gemini_api_key,
355
- }));`);
356
- assert.equal(status, 0, out);
357
- const r = JSON.parse(out.trim().split('\n').pop());
358
- assert.equal(r.stillSignedIn, false, 'sign-out must not leave a readable session under ANY name');
359
- assert.equal(r.newToken, null, 'the current file must lose its token');
360
- assert.equal(r.oldToken, null, 'the superseded file must lose its token too — this is the bug');
361
- // Sign-out drops credentials only; CLI-adjacent config must survive in every file it touches.
362
- assert.equal(r.keptExtra, 'KEEP', 'clear() must preserve non-credential fields');
363
- });
364
-
365
283
  // ── 8. the credential detector follows the rename ───────────────────────────────────────────
366
284
 
367
285
  test('the artifact-scan credential detector flags a read of EVERY session filename', () => {
@@ -1,74 +0,0 @@
1
- # OTB Dev Box — the desktop switch for a builder's hosted box
2
-
3
- A menu-bar (macOS) / system-tray (Windows) app that turns a builder's hosted
4
- dev box on and off with one switch. Built for the newcomer who should never
5
- see a terminal: sign in with browser clicks (app pairing, ADR 0045), flip the
6
- switch, and connect from Claude Desktop or the browser terminal.
7
-
8
- What it does beyond the switch — each fixing a failure observed in the
9
- 2026-06-10 onboarding sessions that killed the old `curl | bash` flow:
10
-
11
- - **Pairing sign-in** — opens the builders' hall, one Approve click, token
12
- delivered over the app's own secret channel (`/api/bongos/auth/app-pair/*`).
13
- The session is written to `~/.config/otb/gds-session.json`, the same file
14
- the `/builder-*` CLI uses — pairing the app signs in the CLI too.
15
- - **SSH key done right** — generates `~/.ssh/otb_builder` (ed25519) with real
16
- 600 perms (icacls ACL on Windows) and registers it via `POST /box/ssh-key`.
17
- - **known_hosts kept fresh** — Claude Desktop's embedded ssh2 reads ONLY
18
- `~/.ssh/known_hosts`, and host keys change on every re-provision; the app
19
- re-scans and replaces entries each time the box turns active.
20
- - **Claude Desktop connection file** — installs the managed-settings file to
21
- the system path with a native elevation prompt (osascript / UAC), the step
22
- the agent-driven flow could never finish.
23
- - **Native notifications** — box ready, rested while idle.
24
- - **No heartbeats** — the app never sends `claude_active`; the droplet's idle
25
- sweep stays authoritative so an unused box still reclaims itself (~10 min).
26
-
27
- ## Layout
28
-
29
- - `src/main.js` — Electron main: tray, window, IPC, wiring.
30
- - `src/brand.js` — every brand string (ADR 0004: the civ name lives here only).
31
- - `src/{pairing,box-controller,gds-client,session-store,ssh-setup,updater}.js` — the
32
- logic, Electron-free and unit-tested in `test/unit.mjs`.
33
- - `src/updater.js` — in-app update check (#924): semver compare + platform→target
34
- resolution. `main.js` polls `GET /downloads/devbox/version` on open + every 12h
35
- and, when the published release is strictly newer, shows the Update banner; the
36
- Update button downloads the installer and hands it to the OS (browser-download
37
- fallback on any error). **Bumping `config/devbox-app.json` version is what makes
38
- the banner appear in the field.**
39
- - `renderer/` — the panel UI (sandboxed, contextIsolated; preload exposes
40
- named verbs only).
41
- - `scripts/gen-icons.js` — regenerates all icons from pixel grids (`npm run
42
- icons`; borrows `sharp` from the repo root's node_modules).
43
-
44
- ## Develop
45
-
46
- ```
47
- cd devbox-app
48
- npm install
49
- npm test # hermetic unit tests, no Electron needed
50
- npm start # run against prod (or OTB_DEVBOX_API_BASE=http://… npm start)
51
- ```
52
-
53
- Dev/test env hooks: `OTB_DEVBOX_API_BASE` (point at a stub/staging GDS),
54
- `OTB_DEVBOX_NO_ELEVATE=1` (skip the managed-settings elevation prompt),
55
- `OTB_DEVBOX_SCREENSHOT_DIR` (write a PNG of the panel on every state change —
56
- how CI/verification captures proof).
57
-
58
- ## Build & release
59
-
60
- ```
61
- npm run dist:mac # dmg, arm64 + x64 (unsigned → ad-hoc)
62
- npm run dist:win # NSIS one-click installer, x64 + arm64
63
- ```
64
-
65
- CI builds both on every push that touches `devbox-app/**`
66
- (`.github/workflows/build-devbox-app.yml`) and uploads them as artifacts.
67
- Publishing = attach the artifacts to a release on the PUBLIC releases repo
68
- named in `config/devbox-app.json`, then bump that config and ship — the
69
- branded `/downloads/devbox/*` redirects follow the config. (The long-form
70
- release recipe was retired with the other published dev-box recipes —
71
- task 1004013, ADR 0305.)
72
-
73
- This subproject is self-contained on purpose: its `package.json` never feeds
74
- the droplet's `npm ci`, and nothing under `devbox-app/` runs server-side.
@@ -1,95 +0,0 @@
1
- # TEMPLATE — rendered to electron-builder.yml by scripts/gen-brand.js from
2
- # config/branding.json (@@TOKENS@@ are substituted; ${version}/${arch}/${ext}
3
- # are electron-builder's own and stay literal). Edit THIS file, never the
4
- # generated electron-builder.yml.
5
- #
6
- # Brand strings (appId, productName, copyright, artifact slug) come from the
7
- # instance branding so one source tree builds any instance's app (ADR 0004,
8
- # generalised). Signing rides the instance's own CI (main-ref-gated Apple
9
- # Developer ID; ADR 0072) — an unarmed build ad-hoc-signs the mac app, which
10
- # arm64 requires to launch at all.
11
- #
12
- # Artifact names are pinned (no spaces, no world name inside — ADR 0004) and
13
- # MUST match config/devbox-app.json's assets map; tests/devbox_downloads.mjs
14
- # cross-checks the config side.
15
-
16
- appId: @@APP_ID@@
17
- productName: @@PRODUCT_NAME@@
18
- copyright: @@COPYRIGHT@@
19
-
20
- # buildResources is named build-resources (not electron-builder's default
21
- # `build`) because the repo root .gitignore ignores build/ everywhere and the
22
- # app icon in here is COMMITTED source, not output.
23
- directories:
24
- buildResources: build-resources
25
- output: dist
26
-
27
- files:
28
- - src/**/*
29
- - renderer/**/*
30
- - assets/**/*
31
- - package.json
32
-
33
- asar: true
34
-
35
- mac:
36
- category: public.app-category.developer-tools
37
- icon: build-resources/icon.png
38
- target:
39
- - target: dmg
40
- arch: [arm64, x64]
41
- artifactName: @@PRODUCT_SLUG@@-${version}-${arch}.${ext}
42
-
43
- dmg:
44
- artifactName: @@PRODUCT_SLUG@@-${version}-${arch}.${ext}
45
- # On-brand install window (task 912). The backdrop
46
- # (build-resources/dmg-background.png + @2x, drawn by
47
- # scripts/gen-dmg-backdrop.py) guides the drag from the container (the app)
48
- # into Applications. iconSize + window + the contents coords MUST match
49
- # the icon-well centers the backdrop draws (LEFT 180,198 / RIGHT 480,198) — if
50
- # you move one, re-run the generator. The volume icon is the app icon (the
51
- # container). electron-builder auto-picks dmg-background@2x.png on Retina.
52
- #
53
- # task 1235: this electron-builder DMG is only an INTERMEDIATE. Its window
54
- # backdrop does NOT render on macOS >= Sonoma — electron-builder writes a
55
- # `pBBk` bookmark Finder can't resolve, so the install window shows up white.
56
- # The CI step "Apply install-window backdrop (dmgbuild)" re-packages the
57
- # signed+notarized .app out of this DMG into the FINAL DMG via dmgbuild
58
- # (scripts/apply-dmg-backdrop.sh + scripts/dmgbuild-settings.py), which writes
59
- # an alias-only .DS_Store that DOES render. Keep the coords below in sync with
60
- # dmgbuild-settings.py (currently identical: 180,198 / 480,198, 660x400, size 100).
61
- icon: build-resources/icon.png
62
- background: build-resources/dmg-background.png
63
- iconSize: 100
64
- window:
65
- width: 660
66
- height: 400
67
- contents:
68
- - x: 180
69
- y: 198
70
- type: file
71
- - x: 480
72
- y: 198
73
- type: link
74
- path: /Applications
75
-
76
- win:
77
- icon: build-resources/icon.png
78
- target:
79
- - target: nsis
80
- # x64 covers Intel/AMD PCs; arm64 is native for ARM Windows (Surface,
81
- # Snapdragon laptops, Parallels VMs on Apple-silicon Macs). x64 also
82
- # RUNS on arm64 via Windows emulation, so x64 stays the safe default
83
- # link; arm64 is the first-class build for those machines (#908).
84
- arch: [x64, arm64]
85
-
86
- nsis:
87
- oneClick: true
88
- perMachine: false
89
- runAfterFinish: true
90
- deleteAppDataOnUninstall: false
91
- # ${arch} suffix added in #908 when arm64 joined — two arches can't share
92
- # one filename. Must stay in lockstep with config/devbox-app.json assets.
93
- artifactName: @@PRODUCT_SLUG@@-Setup-${version}-${arch}.${ext}
94
-
95
- publish: null
@@ -1,95 +0,0 @@
1
- # TEMPLATE — rendered to electron-builder.yml by scripts/gen-brand.js from
2
- # config/branding.json (@@TOKENS@@ are substituted; ${version}/${arch}/${ext}
3
- # are electron-builder's own and stay literal). Edit THIS file, never the
4
- # generated electron-builder.yml.
5
- #
6
- # Brand strings (appId, productName, copyright, artifact slug) come from the
7
- # instance branding so one source tree builds any instance's app (ADR 0004,
8
- # generalised). Signing rides the instance's own CI (main-ref-gated Apple
9
- # Developer ID; ADR 0072) — an unarmed build ad-hoc-signs the mac app, which
10
- # arm64 requires to launch at all.
11
- #
12
- # Artifact names are pinned (no spaces, no world name inside — ADR 0004) and
13
- # MUST match config/devbox-app.json's assets map; tests/devbox_downloads.mjs
14
- # cross-checks the config side.
15
-
16
- appId: com.cloudbongos.devbox
17
- productName: Cloud Bongos Dev Box
18
- copyright: © Cloud Bongos
19
-
20
- # buildResources is named build-resources (not electron-builder's default
21
- # `build`) because the repo root .gitignore ignores build/ everywhere and the
22
- # app icon in here is COMMITTED source, not output.
23
- directories:
24
- buildResources: build-resources
25
- output: dist
26
-
27
- files:
28
- - src/**/*
29
- - renderer/**/*
30
- - assets/**/*
31
- - package.json
32
-
33
- asar: true
34
-
35
- mac:
36
- category: public.app-category.developer-tools
37
- icon: build-resources/icon.png
38
- target:
39
- - target: dmg
40
- arch: [arm64, x64]
41
- artifactName: Cloud-Bongos-Dev-Box-${version}-${arch}.${ext}
42
-
43
- dmg:
44
- artifactName: Cloud-Bongos-Dev-Box-${version}-${arch}.${ext}
45
- # On-brand install window (task 912). The backdrop
46
- # (build-resources/dmg-background.png + @2x, drawn by
47
- # scripts/gen-dmg-backdrop.py) guides the drag from the container (the app)
48
- # into Applications. iconSize + window + the contents coords MUST match
49
- # the icon-well centers the backdrop draws (LEFT 180,198 / RIGHT 480,198) — if
50
- # you move one, re-run the generator. The volume icon is the app icon (the
51
- # container). electron-builder auto-picks dmg-background@2x.png on Retina.
52
- #
53
- # task 1235: this electron-builder DMG is only an INTERMEDIATE. Its window
54
- # backdrop does NOT render on macOS >= Sonoma — electron-builder writes a
55
- # `pBBk` bookmark Finder can't resolve, so the install window shows up white.
56
- # The CI step "Apply install-window backdrop (dmgbuild)" re-packages the
57
- # signed+notarized .app out of this DMG into the FINAL DMG via dmgbuild
58
- # (scripts/apply-dmg-backdrop.sh + scripts/dmgbuild-settings.py), which writes
59
- # an alias-only .DS_Store that DOES render. Keep the coords below in sync with
60
- # dmgbuild-settings.py (currently identical: 180,198 / 480,198, 660x400, size 100).
61
- icon: build-resources/icon.png
62
- background: build-resources/dmg-background.png
63
- iconSize: 100
64
- window:
65
- width: 660
66
- height: 400
67
- contents:
68
- - x: 180
69
- y: 198
70
- type: file
71
- - x: 480
72
- y: 198
73
- type: link
74
- path: /Applications
75
-
76
- win:
77
- icon: build-resources/icon.png
78
- target:
79
- - target: nsis
80
- # x64 covers Intel/AMD PCs; arm64 is native for ARM Windows (Surface,
81
- # Snapdragon laptops, Parallels VMs on Apple-silicon Macs). x64 also
82
- # RUNS on arm64 via Windows emulation, so x64 stays the safe default
83
- # link; arm64 is the first-class build for those machines (#908).
84
- arch: [x64, arm64]
85
-
86
- nsis:
87
- oneClick: true
88
- perMachine: false
89
- runAfterFinish: true
90
- deleteAppDataOnUninstall: false
91
- # ${arch} suffix added in #908 when arm64 joined — two arches can't share
92
- # one filename. Must stay in lockstep with config/devbox-app.json assets.
93
- artifactName: Cloud-Bongos-Dev-Box-Setup-${version}-${arch}.${ext}
94
-
95
- publish: null