Public: anyone can read this; the crew can change it.
forge.json's app.looks lists every top-level page of the forge #2752
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/2735-forge-json-s-app-looks-lists-every-top-l → main 3 commits fork 1 thread · 1 unresolved
3 files
changed +10
−12
docs/APPS.md +1 −1
| @@ -790,7 +790,7 @@ When a deploy comes up green the forge takes a picture of it — every page | ||
| 790 | 790 | (390×844), a laptop's (1280×800), and a thumb's (200×125, desktop's own |
| 791 | 791 | aspect, small), and keeps the pictures beside the commit they are of, so a |
| 792 | 792 | person judges a change from what it is rather than from what it says. |
| 793 | `app.looks` may name at most three pages: a browser start per picture per | |
| 793 | `app.looks` may name at most 24 pages: a browser start per picture per | |
| 794 | 794 | width is the heaviest thing the forge does, and more is a manifest error |
| 795 | 795 | rather than a silent, slower deploy. The pull page shows the phone and |
| 796 | 796 | desktop pair under the checks, with the commit and a word when the head has |
src/apps/manifest.ts +3 −2
| @@ -68,8 +68,9 @@ const READY_DEFAULT = 30; | ||
| 68 | 68 | const READY_MAX = 600; |
| 69 | 69 | const COMMAND_MAX = 1_000; |
| 70 | 70 | /** More than this many pages is a manifest error: a browser start per |
| 71 | * picture per width is the heaviest thing the forge does. */ | |
| 72 | const LOOKS_MAX = 3; | |
| 71 | * picture per width is the heaviest thing the forge does. Room for every | |
| 72 | * top-level page of the forge itself. */ | |
| 73 | const LOOKS_MAX = 24; | |
| 73 | 74 | const LOOK_PATH_MAX = 200; |
| 74 | 75 | |
| 75 | 76 | /** |
test/apps-adversarial.test.ts +6 −9
| @@ -389,19 +389,16 @@ describe("manifest: parseManifest edge cases", () => { | ||
| 389 | 389 | if (result.ok) expect(result.value.looks).toEqual(["/"]); |
| 390 | 390 | }); |
| 391 | 391 | |
| 392 | test("app.looks names up to three pages", () => { | |
| 393 | const result = parseManifest( | |
| 394 | JSON.stringify({ app: { run: "x", looks: ["/", "/board"] } }), | |
| 395 | undefined, | |
| 396 | ); | |
| 392 | test("app.looks names up to 24 pages, enough for every top-level page of the forge", () => { | |
| 393 | const looks = Array.from({ length: 24 }, (_, i) => `/p${i}`); | |
| 394 | const result = parseManifest(JSON.stringify({ app: { run: "x", looks } }), undefined); | |
| 397 | 395 | expect(result.ok).toBe(true); |
| 398 | if (result.ok) expect(result.value.looks).toEqual(["/", "/board"]); | |
| 396 | if (result.ok) expect(result.value.looks).toEqual(looks); | |
| 399 | 397 | }); |
| 400 | ||
| 401 | test("app.looks with more than three paths is refused", () => { | |
| 398 | test("app.looks with more than 24 paths is refused", () => { | |
| 402 | 399 | const result = parseManifest( |
| 403 | 400 | JSON.stringify({ |
| 404 | app: { run: "x", looks: ["/", "/a", "/b", "/c"] }, | |
| 401 | app: { run: "x", looks: Array.from({ length: 25 }, (_, i) => `/p${i}`) }, | |
| 405 | 402 | }), |
| 406 | 403 | undefined, |
| 407 | 404 | ); |
new above
offline
Nit: the blank line between the two tests was dropped. Put it back to match the rest of the file.