Skip to content

Images: 80 posts ship 1.6 MB PNG covers (mobile LCP ≈ 8 s on slow 4G), 120 marketing pages eager-load a 1.7 MB hero, and 209 posts use an SVG og:image that social networks cannot show #220

Closed

Description

@objectstack-fleet

Found by the seat's site-wide audit of www.objectos.ai on 2026-10-06 (production build of main @ 53764e0). The measurements used Playwright Chromium at 390×844 with 4× CPU throttling and a slow-4G profile. Priority: P1. HTML, CSS and JS are already lean (no web fonts, about 2 KB of inline JS, 5–7 KB of gzipped CSS, CLS 0), so images are almost the whole cost.

Findings

1. Blog covers

  • 80 posts use a PNG cover of 1.5–1.9 MB at 1672×941, and it is the LCP element. Another 50 use JPGs of 240–370 KB.
  • Card thumbnails use the full-size file too, so a full scroll of the blog index downloads about 18 MB in en and zh-Hans.
  • Measured LCP:
    • /en/blog/ai-agent-workbench/ (PNG cover): 8.2 s;
    • the same template with an SVG cover: 0.74 s.
  • Converted with sharp, a cover drops to about 52 KB as a 1200-wide WebP, or about 11 KB at card size.
  • Cause: src/layouts/BlogPost.astro:26-34,165-176 and src/components/ArticleCard.astro:26-33 use the raw cover.src.

2. Marketing hero image

  • 120 marketing pages eager-load /images/objectos-home-hero.png (1,732,355 bytes, confirmed by the seat), which renders at only 415×340.
  • /en/ai/ has an LCP of 8.8 s at 1366 on slow 4G. As WebP it is about 32 KB.
  • Cause: src/components/MarketingEvidencePage.astro:40-48.
  • The same image is the hero on home and on all 15 marketing pages, and in dark mode it stays a glaring white block.

3. Social share images

  • On 209 posts (41 of them English), og:image is an SVG. X, LinkedIn, Facebook and Slack show no image card, which works against the AGENTS.md goal of distributing posts as threads.
  • BlogPosting.image is the same SVG (BlogPost.astro:34,108).
  • 531 pages share the generic 1.69 MB og:image.

Done looks like

  • Covers: generated through astro:assets (<Image> / getImage) as WebP or AVIF with srcset and sizes, in the post header and in card thumbnails.
  • Hero: moved into src/assets and rendered through <Image> with sizes, lazy where it is below the fold. A dark-mode treatment (a dark variant or a muted overlay) is the dev's call, stated in the PR.
  • Social images: a 1200×630 raster (PNG or JPG) per post for og:image, twitter:image and BlogPosting.image, generated at build time from the cover, with og:image:width, og:image:height and og:image:alt.
  • Before/after table in the PR: bytes per template and LCP on the same profile, for home, pricing, platform, the blog index and 2 PNG-cover posts.
  • Browser check: the six viewports per AGENTS.md, covers looked at for quality loss.
  • Gates: green.
  • No content edits.

Surface

src/layouts/BlogPost.astro, src/components/{ArticleCard,MarketingEvidencePage,MarketingHome}.astro, src/assets/** (the moved hero), an OG-image build step, and astro.config.mjs if image service config is needed.

Order

After the indexing card.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop, repo:www.objectos.ai seat
    Session: session_01FeA1nwBz1ohH65dvffUGKr
    Account: hotlong (the seat's linked user, as GET /user answers it; always the card's assignee)
    Branch: claude/pm-dispatch-objectos-ju9td1, the session's one designated push branch for this repo. The card's order is "after the indexing card", so it is staged on #219's local branch staged/issue-219, which sits on stack/www-wave1. At push time only this card's own commits are replayed (rebase --onto).
    Worktree: www-issue-220
    Domain: n/a (single-lane repo)
    Seat: repo:www.objectos.ai (objectstack-ai/objectstack#12224)
    File surface: the card's own Surface section:

    • src/layouts/BlogPost.astro;
    • src/components/{ArticleCard,MarketingEvidencePage,MarketingHome}.astro, image markup only;
    • src/assets/**, for the moved hero;
    • an OG-image build step;
    • astro.config.mjs, image-service hunks only, kept separate from the markdown: key.

    Make no content edits. Stay out of #223's layout CSS, and keep the hero's dark-mode treatment to the image itself.
    Stop on breach and explain in the report.
    Container & model: M, mode:subagent, model: default.
    Clause-②: no
    Thread-read: none
    Serial constraints cleared: no. Pushes are serial on the one branch, and this card follows #219.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 220,
      "status": "staged",
      "branch": "staged/issue-220",
      "worktree": "/home/user/www-issue-220",
      "base_sha": "5d685cf995e2d09a7f3a699d1d06e6148b733877 (staged/issue-219 head, on stack/www-wave1)",
      "final_commit": "bec5251e3794e9ebe0e15ee7309ae23a0d70770d",
      "commits": [
        "76563bc perf(images): serve raster blog covers through astro:assets as WebP with srcset",
        "8c49132 feat(seo): render a 1200x630 JPEG share image per post from its cover",
        "2221e0e perf(images): move the hero into src/assets, serve it through Image, dim it in dark mode",
        "bec5251 perf(images): size card thumbnails for the width object-fit draws them at"
      ],
      "pr": null,
      "pr_body_draft": "/tmp/claude-0/-home-user/2224823d-3484-535e-94a5-c071ba6af395/scratchpad/issue-220/pr-body.md (first line: Fixes #220)",
      "session": "session_01FeA1nwBz1ohH65dvffUGKr",
      "premise_still_valid": true,
      "summary": "Raster covers (80 PNG + 50 JPG posts; 17 unique files) now go through astro:assets as WebP with widths and sizes in the post header (eager, fetchpriority high), ArticleCard thumbnails (feature card eager) and the home latest-posts grid; SVG covers keep a plain img on the original. The hero moved to src/assets and renders through the Image component (WebP 400-1586w): eager on the 120 marketing evidence pages, where it is in the first screen at all six viewports and the LCP element on a desktop, and lazy on home; in dark mode it is dimmed on the image itself (brightness 0.6, contrast 1.12). A build step (scripts/og-images.mjs, run in pnpm build after astro build) renders one 1200x630 JPEG per cover for og:image, twitter:image and BlogPosting.image, with width/height/alt. SVG text is drawn with bundled OFL faces and a cmap glyph gate fails the build on any character no face has. Premise verified: 80 PNG-cover posts, a 1,732,355 B hero, and 209 posts with an SVG og:image; the card's line numbers had moved after #219, but the code it describes was still there.",
      "files_changed": [
        "package.json (og:images script, build chain, 7 devDependencies)",
        "pnpm-lock.yaml",
        "scripts/og-images.mjs (new: OG build step)",
        "scripts/lib/og-image.mjs (new: shared URL rule)",
        "scripts/lib/og-fonts.mjs (new: bundled faces, fonts.conf, cmap glyph gate)",
        "public/images/objectos-home-hero.png → src/assets/objectos-home-hero.png (git mv)",
        "src/layouts/BlogPost.astro",
        "src/components/ArticleCard.astro",
        "src/components/MarketingHome.astro",
        "src/components/MarketingEvidencePage.astro",
        "src/layouts/Base.astro (DEFAULT_IMAGE block only; outside the card Surface, see deviations)"
      ],
      "before_after": {
        "profile": "Playwright Chromium; phone rows 390x844 at 3x, desktop rows 1366x625; 4x CPU throttle; DevTools Slow 4G (562.5 ms RTT, 1.44 Mbps down, 675 kbps up); cold cache; LCP = median of 3 runs. Bytes = encodedDataLength from a local python static server (no gzip, so HTML/CSS uncompressed); no-scroll = everything the load started incl. lazy images in Chrome's load-in distance, full scroll = after scrolling to the bottom. before = 5d685cf, after = bec5251, measured back to back under one verify lock on a shared 4-core box (load avg about 10).",
        "rows": [
          "home /en/ | LCP 1944 → 1916 ms (text both) | no-scroll 1,821,615 → 170,412 B | full scroll 1,835,942 → 184,739 B",
          "pricing /en/pricing/ | LCP 1560 → 1548 ms (text) | 46,504 → 46,534 B | same",
          "platform /en/platform/ | LCP 1796 → 1808 ms (text) | 1,805,784 → 129,837 B | same",
          "blog index /en/blog/ | LCP 2708 → 1808 ms (SVG feature cover both) | 142,787 → 148,368 B | 18,826,110 → 1,167,398 B",
          "post /en/blog/ai-agent-workbench/ (PNG cover) | LCP 9956 → 1700 ms (PNG → WebP) | 1,685,249 → 120,959 B | same",
          "post /en/blog/ai-expense-audit/ (PNG cover) | LCP 11120 → 1752 ms (PNG → WebP) | 1,903,685 → 135,214 B | same",
          "platform @1366x625 | LCP 2060 → 1928 ms (h1) | 1,805,784 → 92,303 B | same",
          "ai /en/ai/ @1366x625 | LCP 10620 → 1964 ms (hero PNG → hero WebP) | 1,804,910 → 91,429 B | same"
        ],
        "build_time": "pnpm build wall, cold Astro image cache both, shared box: 87.5 s → 108.4 s (astro image generation 0.6 s → 6.3 s; og-images.mjs 14.3 s for 87 images in 3 workers); warm-cache rebuild 90.0 s",
        "dist_size": "57,657,630 B / 1,082 files → 68,197,374 B / 1,321 files: +6.05 MB cover WebP variants (143), +5.46 MB share JPEGs (87; median 52 KB, max 152 KB), +0.4 MB hero variants, -1.73 MB hero PNG. 18.86 MB of original raster covers (17 files) stay in dist, referenced by no page (Astro keeps content-collection image originals)"
      },
      "og_raster_checks": [
        "87 share images, all 1200x630 JPEG (step 4 of the script plus an independent sharp metadata pass: 0 wrong), 5.46 MB total",
        "glyph gate: 70 SVG covers, 721 distinct drawn characters, all covered; its first run on this tree found U+21B6 and U+2298, so Noto Sans Math was added",
        "gate can fail: a synthetic SVG with Hangul and Thai reported those 6 code points and passed CJK, check mark and an entity-encoded emoji; on a copy of dist, og:image:width 1201 and an unmapped share URL made the step exit 1 with 3 issues",
        "looked at full size: zh-Hans/zh-Hant cover.svg rasters of ai-wrote-your-app-dare-to-merge, beyond-agentforce-copilot-open-runtime, natural-language-to-app-metadata, airtable-omni-vs-governed-ai-app-platform, self-hosted-ai-app-platform (1.6:1); ja/ko use cover-en.svg (AGENTS.md: translated locales reuse the English cover): why-ai-agent-pilots-fail-four-layers (circled digits, U+3000), when-ai-agent-deletes-production-database (no-entry sign, collision emoji, check mark), automation-governed-flow-changes (bottom caption kept). All 87 in six contact sheets. No tofu anywhere",
        "no SVG cover has Japanese or Korean text today; kana and Traditional Chinese are covered (checked), Hangul is not, so a future Korean-text SVG cover fails the build naming its code points",
        "emoji are monochrome (Noto Emoji): COLRv1 colour emoji decode but cairo draws nothing",
        "SVG covers are drawn whole at 1120x630 and widened by repeating edge columns (two covers have a caption in the bottom 23px a centre crop would cut; no cover draws in its outer 40px); PNG/JPG covers are centre-cropped",
        "in-process parallel SVG text rendering crashed (SIGSEGV or SVG rendering failed in 4 of 6 runs); three worker processes rendering one image at a time passed 5 of 5"
      ],
      "tests": "All at bec5251 (tree identical to the last build). pnpm check: 'Result (150 files): 0 errors, 0 warnings, 0 hints'. pnpm content:lint: 'content lint passed (339 files, 44 glossary terms checked)'. pnpm content:lint --published: same line. pnpm build (cold cache, under os-verify-lock, VERDICT command-exit 0): BUILD_EXIT=0, including 'svg-text-fit: OK ... (112 SVGs, 2244 text boxes, tolerance 2px, 1 allowlisted)', 'share images: 87 rendered at 1200x630 (5.2 MB, 14.3 s, 3 workers) for 879 pages; 125 bundled font files, no uncovered glyph', 'content lint --dist passed (478 built blog pages checked)', 'content lint --dist links passed (93199 internal links in 880 built pages resolve to built files)'. pnpm seo:smoke: 'SEO smoke test passed (870 HTML pages checked; 569 sitemap URLs against 301 noindexed pages; 5424 canonical/hreflang annotations; 15654 prose blocks language-checked; 93189 internal links redirect-checked)'. pnpm svg:lint: 'svg-text-fit: OK'. objectstack scripts/check-nul-bytes.mjs run from the www worktree: 'OK (scanned 621 text file(s) ... no raw ASCII control bytes)'. Negative proofs: glyph gate on a synthetic SVG (6 code points reported); og-images.mjs on a mutated dist copy (exit 1, 3 issues). WebP quality: 1280w cover vs the original resized to 1280, PSNR 39.06 dB, 1:1 crop shows no visible difference. No repo test suite exists in www; www has no scripts/pm/dispatch-gates.mjs, so the gate list was derived by hand from package.json and .github/workflows/cloudflare-pages.yml (check, content:lint --published, build, seo:smoke).",
      "screenshots": "/tmp/claude-0/-home-user/2224823d-3484-535e-94a5-c071ba6af395/scratchpad/issue-220/shots/after/: 36 states (six viewports x PNG-cover post /en/blog/ai-agent-workbench/, /en/blog/, /en/ x light, dark), each NAME-WxH-THEME-first.png and -full.png after scrolling every lazy image into view; report.json records 0 unloaded images and 0 px horizontal overflow in all 36. Close-ups: cover-closeup-ai-expense-audit-1920/390.png, blog-index-raster-card-*.png (1366 light, 1920 dark, 390 dark, 360 light), thumb-1366-before-vs-after.png, home-hero-media-*.png, ai-hero-panel-*.png. OG contact sheets: /tmp/claude-0/-home-user/2224823d-3484-535e-94a5-c071ba6af395/scratchpad/issue-220/og-check/sheet-0..5.jpg. Covers looked at for quality loss: none visible.",
      "deviations": [
        "Base.astro edited, outside the claimed Surface: moving the hero (card Done) removes /images/objectos-home-hero.png, which DEFAULT_IMAGE named as every non-post page's og:image. Replaced with getImage of the moved asset at 1200x630 JPEG (94 KB). Only the frontmatter DEFAULT_IMAGE block changed; it is in the same commit as the move (2221e0e), so the two replay together. staged/issue-218's Base.astro hunks are CSS tokens only and do not overlap",
        "ClusterPage.astro not touched although its reading-path cards are card thumbnails: it is outside the Surface and staged/issue-218 holds edits to it. Reported below as a finding",
        "New files outside the listed component files, all part of 'an OG-image build step': scripts/og-images.mjs, scripts/lib/og-image.mjs, scripts/lib/og-fonts.mjs, and the package.json build-chain line",
        "7 new devDependencies: wawoff2 (MIT; the FreeType in sharp's libvips reads neither WOFF2 nor WOFF, measured), @fontsource-variable/arimo, @fontsource/cousine, @fontsource-variable/noto-sans-sc, @fontsource/noto-sans-symbols-2, @fontsource/noto-sans-math, @fontsource-variable/noto-emoji (OFL-1.1; each needed by at least one character in today's covers). sharp was already a dependency",
        "astro.config.mjs untouched (no image-service config needed); no markdown key added or altered; no content edits (git diff 5d685cf..HEAD -- content astro.config.mjs is empty); no layout CSS changed: the only CSS added is the dark-theme filter on the two hero images",
        "Not pushed and no PR, per the staged-mode dispatch. That conflicts with agent-contract rule 1 (push the empty branch before editing); I followed the dispatch",
        "status 'staged' is not one of the contract's status values; used as the dispatch asked",
        "commit trailers are the model-free pair (Co-Authored-By: Claude, Claude-Session) per the agent contract and the sibling staged branches, not the harness reminder's model-named Co-Authored-By",
        "measurements and build times are shared-box readings (load avg about 10 on 4 cores); the before run used the same box and lock, back to back",
        "one background job was started (a 5-run stability loop the shell moved to background); I stopped it by its own PIDs. All static servers I started are stopped (ports 4801/4802 closed). Worktree kept as instructed"
      ],
      "mcp_calls": "0",
      "api_writes": "1 - the os-dev-report comment on objectstack-ai/www.objectos.ai#220, via scripts/pm/with-fleet.sh --via dispatch (one repository_dispatch POST to objectstack-ai/objectstack, which executes POST /repos/objectstack-ai/www.objectos.ai/issues/220/comments as objectstack-fleet[bot]). Reads only otherwise: GET issues/220 and its comments; npm registry reads for the new packages",
      "open_questions": [],
      "out_of_scope_findings": [
        "class: a · reach: public door - GET /en/ai-native-app-platform/ (built dist at bec5251) serves img src /_astro/cover.BauJbMSI.jpg, cover.ChJFVxqy.jpg, cover.Dn04X1um.jpg, cover.rFSi4jxB.jpg (original JPGs, 240-370 KB each, about 1.1 MB) in 180x190 reading-path card slots; 40 cluster pages use src/components/ClusterPage.astro coverSrc() on the raw cover · evidence: ClusterPage.astro lines 36-39 and 96-104 still use the original cover src; same defect as #220 finding 1 (card thumbnails) but the file is outside #220's Surface and staged/issue-218 edits it · suggested as a sub-issue of #220 · dedupe words: ClusterPage cover thumbnail, cluster page original JPG, reading-path article-card image, astro:assets ClusterPage",
        "carrier: 承接者:无 · noted, not filed - 17 original raster covers (18.86 MB) stay in dist/_astro, referenced by no page after this change; Astro keeps the originals of content-collection images (vite-plugin-assets marks query-string imports as referenced). Dead weight in the deploy, no wrong answer at a public door",
        "carrier: #218 (staged/issue-218 adds the dark-theme --proof-* overrides) · noted, not filed - on this base the marketing hero panel's HUMAN label (--proof-blue #3157d8) is dark blue on the dark panel in dark mode, seen in ai-hero-panel-390x844-dark.png",
        "carrier: #223 (layout CSS) · noted, not filed - the home hero's media-note overlay stays a near-white box in dark mode; with the hero now dimmed it stands out more. It is layout CSS, which this card stays out of"
      ]
    }
  3. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report-addendum

    {
      "issue": 220,
      "status": "staged",
      "addendum_to": "os-dev-report https://github.com/objectstack-ai/www.objectos.ai/issues/220#issuecomment-6020532870",
      "branch": "staged/issue-220",
      "worktree": "/home/user/www-issue-220",
      "previous_tip": "bec5251e3794e9ebe0e15ee7309ae23a0d70770d",
      "final_commit": "95ada6245124b95e856bc5f01c7d0a2e7768c6e0",
      "new_commit": "95ada62 perf(images): serve cluster reading-path thumbnails through astro:assets",
      "pr": null,
      "session": "session_01FeA1nwBz1ohH65dvffUGKr",
      "summary": "Folded in the first out-of-scope finding, as the coordinator asked. The reading-path cards in src/components/ClusterPage.astro (40 cluster pages) now serve a raster cover through the astro:assets Image component as WebP, 400-1080w; SVG covers keep the plain img. sizes = '(max-width: 640px) calc(100vw - 2rem), 400px'. It names the drawn width, the same way as the ArticleCard commit: above 640px the image is a 180px column (150px at 641-900px) as tall as the card's text, measured at 190-227px; object-fit: cover fills it by height, so the cover is drawn 304-364px wide. On a phone the card stacks and the 16:9 image is drawn at the column width. Only the frontmatter (the import, and a width list replacing coverSrc) and the card markup change; there is no CSS change.",
      "files_changed": [
        "src/components/ClusterPage.astro"
      ],
      "replay_with_218": "git merge-tree --write-tree staged/issue-218 staged/issue-220 exits 0 with tree 1b733e9ad9c636ec39712b51632611912a5cef62. That merged ClusterPage.astro carries both #218's dark kicker colour (#3fbf8f) and this card's CARD_WIDTHS. #218's ClusterPage hunks are CSS around line 151; this card's are the import at line 2, the frontmatter at lines 34-49 and the card markup at lines 100-127, with no overlap. The whole-branch merge-tree also covers the other files both branches touch (Base.astro, BlogPost.astro, MarketingHome.astro, MarketingEvidencePage.astro), all clean",
      "numbers": {
        "profile": "same as the os-dev-report: Playwright Chromium, phone 390x844 at 3x / desktop 1366x625, 4x CPU, DevTools Slow 4G, cold cache; LCP is the median of 3 runs; bytes from a local static server with no gzip. before = bec5251 (ClusterPage unchanged since 5d685cf), after = 95ada62, back to back under the verify lock",
        "cluster /en/ai-native-app-platform/ phone": "no-scroll 903,617 → 230,655 B; full scroll 1,182,014 → 282,059 B; LCP 1688 → 1680 ms (text)",
        "cluster /en/ai-native-app-platform/ @1366x625": "no-scroll 1,182,014 → 124,226 B; full scroll same; LCP 1848 → 1828 ms (h1)",
        "dist": "68,197,374 → 68,235,078 B, 1,321 files both: the cards reuse WebP variants the ArticleCard thumbs already emit; the growth is srcset bytes in the HTML",
        "build": "pnpm build 90.5 s wall with a warm image cache (shared box); og-images 13.3 s"
      },
      "gates": "At 95ada62. pnpm check, under the lock: 'Result (150 files): 0 errors, 0 warnings, 0 hints'. pnpm build, under the lock, VERDICT command-exit 0, BUILD_EXIT=0; it includes 'svg-text-fit: OK ... (112 SVGs, 2244 text boxes, tolerance 2px, 1 allowlisted)', 'share images: 87 rendered at 1200x630 (5.2 MB, 13.3 s, 3 workers) for 879 pages; 125 bundled font files, no uncovered glyph', 'content lint --dist passed (478 built blog pages checked)' and 'content lint --dist links passed (93199 internal links in 880 built pages resolve to built files)'. pnpm seo:smoke: 'SEO smoke test passed (870 HTML pages checked; 569 sitemap URLs against 301 noindexed pages; 5424 canonical/hreflang annotations; 15654 prose blocks language-checked; 93189 internal links redirect-checked)'. pnpm content:lint and pnpm content:lint --published: 'content lint passed (339 files, 44 glossary terms checked)'. pnpm svg:lint: 'svg-text-fit: OK'. check-nul-bytes: 'OK ... no raw ASCII control bytes'. The four original JPGs are now referenced by 0 built pages (they were referenced by 8-40 before).",
      "screenshots": "/tmp/claude-0/-home-user/2224823d-3484-535e-94a5-c071ba6af395/scratchpad/issue-220/shots/cluster/: /en/ai-native-app-platform/ at 1366x625 and 390x844, light and dark, full page (*-after-*-full.png) plus the reading-path section before and after (*-reading-path.png), all after scrolling every lazy image into view. 0 unloaded images and 0 px horizontal overflow in all 8. The card image boxes are unchanged (180x227 desktop, 356x200 phone). card-image-before-vs-after-1366/390.png compare the first card's image side by side and show no visible loss. One artifact: in the 1366 section screenshots the sticky site header overlaps the section's heading; it comes from the element capture, not the page",
      "pr_body_draft": "/tmp/claude-0/-home-user/2224823d-3484-535e-94a5-c071ba6af395/scratchpad/issue-220/pr-body.md, updated: covers bullet, before/after cluster rows, browser check, gates at 95ada62, and a ClusterPage acceptance note with the merge-tree proof; first line still Fixes #220",
      "deviations": [
        "ClusterPage.astro was outside the claimed Surface. It was added at the coordinator's request; the replay overlap with #218 was checked by merge-tree, see replay_with_218",
        "Not pushed, no PR, no other branch touched. git merge-tree --write-tree writes objects only, no refs"
      ],
      "mcp_calls": "0",
      "api_writes": "1 - this addendum comment on #220 via scripts/pm/with-fleet.sh --via dispatch (one repository_dispatch to objectstack-ai/objectstack, executing POST /repos/objectstack-ai/www.objectos.ai/issues/220/comments as objectstack-fleet[bot])",
      "open_questions": [],
      "out_of_scope_findings": []
    }
  4. added a commit that references this issue on Oct 15, 2026
    311a349
  5. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed and live · 2026-10-15T12:22Z


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions