You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Console PWA manifest: declare the branded icon's real type and offer 192/512 PNG icons so a branded Console stays installable #29332
This was found in the acceptance review of #29326 (card #29155). It predates that PR: main has the same code.
The Console's web app manifest declares its icon as type: 'image/svg+xml', sizes: 'any' (ui/apps/console/src/main.tsx, the manifest block). The favicon <link> a few lines earlier already tells SVG from PNG.
When Setup branding sets a PNG or ICO favicon, the manifest mis-declares it. Such a favicon is also likely below Chrome's 144 px minimum for the install prompt. So a branded Console may not be installable, although card #29155 asks for the branded icon.
Ask
Derive the manifest icon type and sizes from the configured branding asset, as the favicon link does.
When the branded asset is not SVG and not at least 192 px, add 192 px and 512 px PNG icons to the manifest. Use the platform default icons, or a server-rendered resize if one exists. Say which in the PR.
Keep start_url and scope as they are.
Acceptance
A unit test covers the manifest for SVG, PNG and ICO branding, and for no branding.
A Playwright or CDP reading shows no manifest installability errors with a PNG favicon configured.
Read fresh. The Console PWA manifest declares any branded icon as SVG, so a PNG or ICO branding can break installability. p3 kept. The card had no state (H13).
⛔ Not a claim. Reserved by domain:ui#3 (assignee set; pm:queue kept), agreed with domain:ui#4. This card edits the Console manifest block in ui/apps/console/src/main.tsx, which PR #29326 (#29155, Tier H, awaiting the maintainer) also rewrites, so the seat dispatches it after PR #29326 lands and keeps that PR's absolute start_url, scope and icon URLs as Ask 3 says.
Claim: PM loop round 17 · 2026-11-02T13:44Z
Session: session_01QsR2jSqNEXXfJECHQqN7mG (card thread, os-dev); dispatched by seat session session_01QsR2jV4dWohojjbTJTQq5m
Account: zhuangjianguo
Branch: claude/project-thread-vmwtew (platform-assigned to the card thread; it can push only this branch)
Worktree: objectstack-issue-29332
Domain: domain:ui
Seat: domain:ui#3
File surface: ui/apps/console/src/main.tsx (the manifest block), a small console-local helper beside it for the icon entries, default icon assets under ui/apps/console/public only if new PNG sizes must be added (named in the report first), their tests, and a changeset (stop on breach; explain in the report). @object-ui/mobile (generatePWAManifest) is out of surface.
Container & model: S, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: open — recorded at review
Thread-read: 6577820333
Premise: holds (at origin/main838a802b: ui/apps/console/src/main.tsx builds the runtime manifest through generatePWAManifest with every icon declared sizes: 'any', type: 'image/svg+xml' (~:177-178), while the favicon link at ~:146 already tells SVG from PNG; ui/apps/console/public holds only favicon.svg).
Serial constraints cleared: PR #29326 (#29155) landed as b7720782, as agreed with domain:ui#4; its absolute start_url, scope and icon URLs stay as they are. No in-flight claim of seats 1-5 names ui/apps/console/src/main.tsx.
{
"issue": 29332,
"status": "done",
"branch": "claude/project-thread-vmwtew",
"pr": "https://github.com/objectstack-ai/objectstack/pull/29405",
"head": "1b6eb74f",
"session": "session_01QsR2jSqNEXXfJECHQqN7mG",
"premise_still_valid": true,
"summary": "The Console runtime manifest icons are built by a console-local helper (ui/apps/console/src/pwaManifestIcons.ts): SVG or no branding keeps one image/svg+xml 'any' entry; a raster favicon (PNG, ICO, WebP, JPEG, GIF, AVIF) declares its own MIME type and its measured WIDTHxHEIGHT, and is left out when its type is unknown or it cannot be measured (error, zero size, 10 s timeout). Without a square raster of at least 192 px, the new platform defaults public/icon-192.png and icon-512.png (rendered from public/favicon.svg with Chromium; seat approved before adding) are appended. main.tsx removes the static manifest synchronously as before and injects the Blob manifest from injectPwaManifest without await, so the measurement never holds first paint; start_url, scope and absolute icon URLs unchanged. @object-ui/mobile untouched.",
"tests": "pnpm --dir ui exec vitest run apps/console/src/pwaManifestIcons.test.ts: 23/23 passed (at 29065950 and again at 1b6eb74f). Ablation via scripts/ablation-replace.mjs, anchor 'const type = iconTypeOf(src);' -> 'const type: string | undefined = SVG_TYPE;' (anchor 1->0, replacement 0->1, blob 12d7f20e -> 2837356e): 6 failed / 17 passed (small PNG, large PNG, non-square PNG, ICO, unmeasurable, unknown type red; none and SVG green); restored, blob equals HEAD, git diff HEAD empty. turbo run type-check --filter=@object-ui/console: 71/71. eslint on the three ts/tsx files: exit 0. CDP installability (full Chromium, launchPersistentContext channel chromium, vite build served under /console/ with base tag, stubbed /api/v1/runtime/config): before (main manifest block) 32 px PNG -> installabilityErrors no-acceptable-icon (minimum-icon-size-in-pixels 144); after -> [] with icons 32x32 PNG + 192x192 + 512x512; 256 px PNG, SVG and none -> [] both sides. Probe script: /mnt/project-files/issue-29332/installability-probe.mjs.",
"gates": "dispatch-gates --commands at 29065950: 33 derived, 33 run, all exit 0 (incl. check-sdui-manifest exit 0, pnpm --dir ui exec vitest run scripts/ 169 passed 2 skipped files, lock VERDICT command-exit 0); --ran reconciliation: 0 NOT-MEASURED, 0 UNRUN. PR-body gates on the final body: check-changeset-no-major 0, check-adr-0087-registration 0, check-closing-keyword-parity 0, check-partof-closing-keyword 0. ui check:new-line-citations: 0 new. CI check-runs: in_progress at report time (re-runs are the seat's).",
"line_budget": "card size S; diff vs main +339/-30 over 6 files (2 binary PNGs counted 0): helper 134, test 163, main.tsx +32/-30, changeset 10. Under the 3000 human-merge threshold.",
"files_changed": [
".changeset/29332-console-pwa-manifest-icons.md",
"ui/apps/console/public/icon-192.png",
"ui/apps/console/public/icon-512.png",
"ui/apps/console/src/main.tsx",
"ui/apps/console/src/pwaManifestIcons.ts",
"ui/apps/console/src/pwaManifestIcons.test.ts"
],
"deviations": [
"Unknown-type and unmeasurable raster favicons are left out of the manifest (defaults stand in) rather than declared image/png, because generatePWAManifest defaults a missing type to image/png and @object-ui/mobile is out of surface.",
"Full dogfood battery not run: no ! in the title and Clause-② carries no (narrowing) arm."
],
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "4 — mcp__github__issue_read x3 (get, get_comments x2), mcp__claude-code-remote__get_session x1; no GitHub MCP write",
"api_writes": "2 — relay pr_create (PR 29405), this report via post-stamped; plus git push (not REST)",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: none · noted in PR Acceptance notes, not filed: the favicon link in main.tsx and index.html labels every non-SVG favicon image/png (ICO included); browsers sniff favicon bytes, nothing visible follows."
]
}
Landed: PR #29405 merged at 2026-11-02T14:46Z as 1d03901c. Fixes #29332 closed this card; pm:dispatched removed. Delivered: the Console's runtime PWA manifest declares a raster branding favicon with its real MIME type and measured size, keeps the single SVG any entry for an SVG or default favicon, and adds the default icon-192.png / icon-512.png whenever no square raster of at least 192 px is present, so a small PNG branding installs (Chrome no-acceptable-icon gone). The manifest lands after measurement, off the first-paint path. Nothing left on this card.
Activity
objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: p3 kept ·
pm:queue· 2026-11-02T13:02Z⛔ Not a claim.
Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m
⛔ Not a claim. Reserved by
domain:ui#3(assignee set;pm:queuekept), agreed withdomain:ui#4. This card edits the Console manifest block inui/apps/console/src/main.tsx, which PR #29326 (#29155, Tier H, awaiting the maintainer) also rewrites, so the seat dispatches it after PR #29326 lands and keeps that PR's absolutestart_url,scopeand icon URLs as Ask 3 says.objectstack-fleet commentedon Nov 2, 2026
domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m
Claim: PM loop round 17 · 2026-11-02T13:44Z
Session:
session_01QsR2jSqNEXXfJECHQqN7mG(card thread, os-dev); dispatched by seat sessionsession_01QsR2jV4dWohojjbTJTQq5mAccount:
zhuangjianguoBranch:
claude/project-thread-vmwtew(platform-assigned to the card thread; it can push only this branch)Worktree:
objectstack-issue-29332Domain:
domain:uiSeat:
domain:ui#3File surface:
ui/apps/console/src/main.tsx(the manifest block), a small console-local helper beside it for the icon entries, default icon assets underui/apps/console/publiconly if new PNG sizes must be added (named in the report first), their tests, and a changeset (stop on breach; explain in the report).@object-ui/mobile(generatePWAManifest) is out of surface.Container & model: S,
mode:thread,model: default tier (dispatch-gates --tier: no path-derived mandate),effort: highClause-②: no
Metadata-protocol: none
Responsibility:
open — recorded at reviewThread-read: 6577820333
Premise: holds (at
origin/main838a802b:ui/apps/console/src/main.tsxbuilds the runtime manifest throughgeneratePWAManifestwith every icon declaredsizes: 'any',type: 'image/svg+xml'(~:177-178), while the favicon link at ~:146 already tells SVG from PNG;ui/apps/console/publicholds onlyfavicon.svg).Serial constraints cleared: PR #29326 (#29155) landed as
b7720782, as agreed withdomain:ui#4; its absolutestart_url,scopeand icon URLs stay as they are. No in-flight claim of seats 1-5 namesui/apps/console/src/main.tsx.objectstack-fleet commentedon Nov 2, 2026
domain:ui#3 · zhuangjianguo · session_01QsR2jSqNEXXfJECHQqN7mG
os-dev-report
{ "issue": 29332, "status": "done", "branch": "claude/project-thread-vmwtew", "pr": "https://github.com/objectstack-ai/objectstack/pull/29405", "head": "1b6eb74f", "session": "session_01QsR2jSqNEXXfJECHQqN7mG", "premise_still_valid": true, "summary": "The Console runtime manifest icons are built by a console-local helper (ui/apps/console/src/pwaManifestIcons.ts): SVG or no branding keeps one image/svg+xml 'any' entry; a raster favicon (PNG, ICO, WebP, JPEG, GIF, AVIF) declares its own MIME type and its measured WIDTHxHEIGHT, and is left out when its type is unknown or it cannot be measured (error, zero size, 10 s timeout). Without a square raster of at least 192 px, the new platform defaults public/icon-192.png and icon-512.png (rendered from public/favicon.svg with Chromium; seat approved before adding) are appended. main.tsx removes the static manifest synchronously as before and injects the Blob manifest from injectPwaManifest without await, so the measurement never holds first paint; start_url, scope and absolute icon URLs unchanged. @object-ui/mobile untouched.", "tests": "pnpm --dir ui exec vitest run apps/console/src/pwaManifestIcons.test.ts: 23/23 passed (at 29065950 and again at 1b6eb74f). Ablation via scripts/ablation-replace.mjs, anchor 'const type = iconTypeOf(src);' -> 'const type: string | undefined = SVG_TYPE;' (anchor 1->0, replacement 0->1, blob 12d7f20e -> 2837356e): 6 failed / 17 passed (small PNG, large PNG, non-square PNG, ICO, unmeasurable, unknown type red; none and SVG green); restored, blob equals HEAD, git diff HEAD empty. turbo run type-check --filter=@object-ui/console: 71/71. eslint on the three ts/tsx files: exit 0. CDP installability (full Chromium, launchPersistentContext channel chromium, vite build served under /console/ with base tag, stubbed /api/v1/runtime/config): before (main manifest block) 32 px PNG -> installabilityErrors no-acceptable-icon (minimum-icon-size-in-pixels 144); after -> [] with icons 32x32 PNG + 192x192 + 512x512; 256 px PNG, SVG and none -> [] both sides. Probe script: /mnt/project-files/issue-29332/installability-probe.mjs.", "gates": "dispatch-gates --commands at 29065950: 33 derived, 33 run, all exit 0 (incl. check-sdui-manifest exit 0, pnpm --dir ui exec vitest run scripts/ 169 passed 2 skipped files, lock VERDICT command-exit 0); --ran reconciliation: 0 NOT-MEASURED, 0 UNRUN. PR-body gates on the final body: check-changeset-no-major 0, check-adr-0087-registration 0, check-closing-keyword-parity 0, check-partof-closing-keyword 0. ui check:new-line-citations: 0 new. CI check-runs: in_progress at report time (re-runs are the seat's).", "line_budget": "card size S; diff vs main +339/-30 over 6 files (2 binary PNGs counted 0): helper 134, test 163, main.tsx +32/-30, changeset 10. Under the 3000 human-merge threshold.", "files_changed": [ ".changeset/29332-console-pwa-manifest-icons.md", "ui/apps/console/public/icon-192.png", "ui/apps/console/public/icon-512.png", "ui/apps/console/src/main.tsx", "ui/apps/console/src/pwaManifestIcons.ts", "ui/apps/console/src/pwaManifestIcons.test.ts" ], "deviations": [ "Unknown-type and unmeasurable raster favicons are left out of the manifest (defaults stand in) rather than declared image/png, because generatePWAManifest defaults a missing type to image/png and @object-ui/mobile is out of surface.", "Full dogfood battery not run: no ! in the title and Clause-② carries no (narrowing) arm." ], "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "4 — mcp__github__issue_read x3 (get, get_comments x2), mcp__claude-code-remote__get_session x1; no GitHub MCP write", "api_writes": "2 — relay pr_create (PR 29405), this report via post-stamped; plus git push (not REST)", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "carrier: none · noted in PR Acceptance notes, not filed: the favicon link in main.tsx and index.html labels every non-SVG favicon image/png (ICO included); browsers sniff favicon bytes, nothing visible follows." ] }objectstack-fleet commentedon Nov 2, 2026
domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m
Landed: PR #29405 merged at 2026-11-02T14:46Z as
1d03901c.Fixes #29332closed this card;pm:dispatchedremoved. Delivered: the Console's runtime PWA manifest declares a raster branding favicon with its real MIME type and measured size, keeps the single SVGanyentry for an SVG or default favicon, and adds the defaulticon-192.png/icon-512.pngwhenever no square raster of at least 192 px is present, so a small PNG branding installs (Chromeno-acceptable-icongone). The manifest lands after measurement, off the first-paint path. Nothing left on this card.