Skip to content

fix(apps): require shipped default app icons#262

Open
HamedMP wants to merge 3 commits into
mainfrom
mat-32-default-app-logos
Open

fix(apps): require shipped default app icons#262
HamedMP wants to merge 3 commits into
mainfrom
mat-32-default-app-logos

Conversation

@HamedMP
Copy link
Copy Markdown
Owner

@HamedMP HamedMP commented May 30, 2026

Summary

  • Add the Profile default app manifest icon mapping to the committed profile asset.
  • Tighten default app manifest validation so missing icon fields fail, not only unknown icon strings.
  • Keep describeUnknownError fallback diagnostics tied to the original value type when string coercion itself throws, with a regression test for the Greptile feedback item.

Tests

  • node scripts/build-default-apps.mjs home/apps
  • bun run test -- tests/gateway/apps.test.ts tests/gateway/default-icons.test.ts tests/shell/error-boundary-utils.test.ts
  • bun run test -- tests/shell/error-boundary-utils.test.ts
  • bun run typecheck
  • bun run check:patterns (warnings only)
  • bun run test

Generic Icons Retained

  • home/apps/games/** default game manifests intentionally continue to use the shared game-center icon.
  • home/apps/symphony/matrix.json intentionally continues to use the existing shared code icon.

Invariants

  • Source of truth: default app matrix.json icon slugs are canonical for launch metadata, and committed files under home/system/icons/ are canonical for shipped icon assets.
  • Lock/transaction scope: no database writes, filesystem mutations at runtime, or critical sections are introduced.
  • Acceptable orphan states: no new orphan runtime state is possible; a manifest referencing a missing or absent icon now fails the app manifest test before shipping.
  • Auth source of truth: unchanged; icon asset resolution continues through the existing gateway/shell paths.
  • Deferred scope: no new icon generation system, Gemini regeneration changes, route behavior changes, or non-icon default app behavior changes.

Summary:
- Add the Profile manifest icon mapping to the committed profile asset.
- Tighten the default app manifest test so missing icon fields fail.
- Replace a pre-existing bare catch flagged by the pattern scanner.

Rationale:
- Default app icons should resolve deterministically from shipped assets
  instead of relying on per-user regeneration paths.
- The previous validation only caught invalid string icons, not missing
  icon fields.

Tests:
- node scripts/build-default-apps.mjs home/apps
- bun run test -- tests/gateway/apps.test.ts tests/gateway/default-icons.test.ts
- bun run typecheck
- bun run check:patterns
- bun run test
@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 30, 2026

MAT-32

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Repo admins can enable using credits for code reviews in their settings.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
matrix-os-www Ready Ready Preview, Comment May 30, 2026 1:21am

Request Review

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 30, 2026

Greptile Summary

This PR fixes the profile app's missing icon field and hardens the manifest validation test so any future app that ships without an icon declaration fails immediately rather than silently passing.

  • Adds \"icon\": \"profile\" to home/apps/profile/matrix.json; profile.png is already committed under home/system/icons/, so the new test passes.
  • Tightens tests/gateway/apps.test.ts to flag manifests where icon is absent (not just where the icon name is unknown), closing the prior gap.
  • Converts the bare catch in error-boundary-utils.ts to catch (stringifyError) with void stringifyError to satisfy the linter, and adds a targeted Vitest test covering that code path.

Confidence Score: 5/5

All changes are additive, narrowly scoped, and backed by confirmed asset presence and new test coverage.

The manifest fix is confirmed correct (profile.png exists), the tightened validation only catches genuinely missing icons, and the error-boundary-utils change is behaviorally identical to the original with a new test proving the fallback path. No logic changes affect runtime paths beyond error description.

No files require special attention.

Important Files Changed

Filename Overview
home/apps/profile/matrix.json Adds missing icon: "profile" field; corresponding profile.png asset is confirmed present in home/system/icons/.
tests/gateway/apps.test.ts Tightens icon validation so manifests without an icon field (not just unknown icons) now fail the test; games and symphony intentionally use shared icons that remain shipped.
shell/src/lib/error-boundary-utils.ts Replaces bare catch with catch (stringifyError) + void stringifyError to satisfy the no-unused-vars linter rule; runtime behavior is unchanged.
tests/shell/error-boundary-utils.test.ts New test that exercises the stringify-throws fallback path in describeUnknownError using Symbol.toPrimitive; correctly asserts the typeof error return value.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Test: visit home/apps/**/matrix.json"] --> B{"manifest.icon is string?"}
    B -- "No (new check)" --> C["push 'missing icon' → test FAILS"]
    B -- "Yes" --> D{"shippedIcons.has(manifest.icon)?"}
    D -- "No" --> E["push icon name → test FAILS"]
    D -- "Yes" --> F["OK — continue"]
    G["profile/matrix.json\n icon: 'profile'"] --> D
    H["home/system/icons/profile.png"] --> I["shippedIcons Set"]
    I --> D
Loading

Reviews (2): Last reviewed commit: "fix(shell): keep error fallback tied to ..." | Re-trigger Greptile

Comment on lines +19 to 21
} catch (stringifyError) {
if (stringifyError instanceof globalThis.Error) return stringifyError.name;
return typeof error;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Fallback describes the stringify error, not the original error

When String(error) throws and the caught exception is an Error, the function now returns stringifyError.name (e.g. "TypeError") — which names the stringify failure, not the original error argument. A caller reading that string would reasonably assume they're learning about the original error. The previous fallback typeof error was agnostic about both, so the semantic shift is small and this code path is extremely rare in practice, but stringifyError.name could mislead diagnostics downstream if it ever fires.

Prompt To Fix With AI
This is a comment left during a code review.
Path: shell/src/lib/error-boundary-utils.ts
Line: 19-21

Comment:
**Fallback describes the stringify error, not the original error**

When `String(error)` throws and the caught exception is an `Error`, the function now returns `stringifyError.name` (e.g. `"TypeError"`) — which names the *stringify failure*, not the original `error` argument. A caller reading that string would reasonably assume they're learning about the original error. The previous fallback `typeof error` was agnostic about both, so the semantic shift is small and this code path is extremely rare in practice, but `stringifyError.name` could mislead diagnostics downstream if it ever fires.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

HamedMP added 2 commits May 30, 2026 03:12
Summary:
- Add a regression test for describeUnknownError when string coercion
  itself throws.
- Return the original value type in that fallback path instead of the
  stringify failure name.

Rationale:
- Greptile flagged that returning the stringify failure's Error.name can
  mislead diagnostics by implying it describes the original thrown value.
- The generic typeof fallback preserves the previous agnostic behavior
  while still satisfying the no-bare-catch scanner rule.

Tests:
- bun run test -- tests/shell/error-boundary-utils.test.ts
- node scripts/build-default-apps.mjs home/apps
- bun run test -- tests/gateway/apps.test.ts tests/gateway/default-icons.test.ts tests/shell/error-boundary-utils.test.ts
- bun run typecheck
- bun run check:patterns
- bun run test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant