<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://noctcore.github.io/showcase-kit/changelog/</id>
  <title>@noctcore/showcase-kit releases</title>
  <subtitle>Every release of @noctcore/showcase-kit, from its CHANGELOG.md.</subtitle>
  <link rel="self" type="application/atom+xml" href="https://noctcore.github.io/showcase-kit/changelog.xml"/>
  <link rel="alternate" type="text/html" href="https://noctcore.github.io/showcase-kit/changelog/"/>
  <updated>2026-09-27T14:27:49Z</updated>
  <author><name>Shironex</name></author>
  <entry>
    <id>tag:noctcore.github.io,2026-09-24:showcase-kit/changelog/0.3.0</id>
    <title>@noctcore/showcase-kit 0.3.0</title>
    <updated>2026-09-27T14:27:49Z</updated>
    <link rel="alternate" type="text/html" href="https://noctcore.github.io/showcase-kit/changelog/#v0.3.0"/>
    <content type="html">&lt;h3&gt;Minor changes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/noctcore/showcase-kit/pull/12&quot;&gt;#12&lt;/a&gt; &lt;a href=&quot;https://github.com/noctcore/showcase-kit/commit/dcbeac868e2713422a5ea9e7f9249258599003b9&quot;&gt;&lt;code&gt;dcbeac8&lt;/code&gt;&lt;/a&gt; More looks for the hero, the frames and the README snippet. Every new option defaults to the look you have today, so an existing config renders the same images byte for byte.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hero layouts&lt;/strong&gt;: &lt;code&gt;hero.layout&lt;/code&gt; picks the composition: &lt;code&gt;stack&lt;/code&gt; (the default, as before), &lt;code&gt;spotlight&lt;/code&gt; (one large straight window running off the edges), &lt;code&gt;split&lt;/code&gt; (one window in perspective), &lt;code&gt;row&lt;/code&gt; (up to four windows under centered text), &lt;code&gt;mosaic&lt;/code&gt; (a tilted wall of windows) and &lt;code&gt;centered&lt;/code&gt; (text first, one window rising from the bottom). &lt;code&gt;hero.shots&lt;/code&gt; takes as many shots as the layout shows and defaults to that many of the first shots.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Frame styles&lt;/strong&gt;: &lt;code&gt;frame.style&lt;/code&gt; also takes &lt;code&gt;browser&lt;/code&gt; (a toolbar with an address bar, whose text is the new &lt;code&gt;frame.address&lt;/code&gt;, &lt;code&gt;&apos;{url}&apos;&lt;/code&gt; by default), &lt;code&gt;windows&lt;/code&gt; (a Windows title bar) and &lt;code&gt;terminal&lt;/code&gt; (a terminal tab; in tty mode the bar takes the terminal background). tty mode refuses &lt;code&gt;browser&lt;/code&gt;, and cdp mode needs an &lt;code&gt;address&lt;/code&gt; without &lt;code&gt;{url}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Backgrounds&lt;/strong&gt;: &lt;code&gt;frame.background&lt;/code&gt; and &lt;code&gt;hero.background&lt;/code&gt; also take &lt;code&gt;{ type: &apos;mesh&apos;, colors }&lt;/code&gt;, &lt;code&gt;{ type: &apos;dots&apos;, color, dot, spacing }&lt;/code&gt; and &lt;code&gt;{ type: &apos;noise&apos;, from, to, angle, amount }&lt;/code&gt;, a gradient with a film grain that is the same on every run.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;README layouts&lt;/strong&gt;: &lt;code&gt;showcase readme --layout &amp;lt;name&amp;gt;&lt;/code&gt; prints &lt;code&gt;table&lt;/code&gt; (the default, as before), &lt;code&gt;rows&lt;/code&gt;, &lt;code&gt;featured&lt;/code&gt;, &lt;code&gt;details&lt;/code&gt; or &lt;code&gt;list&lt;/code&gt;, all built from HTML that GitHub keeps in a README. &lt;code&gt;--cols&lt;/code&gt; applies to &lt;code&gt;table&lt;/code&gt; and &lt;code&gt;featured&lt;/code&gt;. The library&apos;s &lt;code&gt;readmeSnippet&lt;/code&gt; takes the same &lt;code&gt;layout&lt;/code&gt; option.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Patch changes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/noctcore/showcase-kit/pull/9&quot;&gt;#9&lt;/a&gt; &lt;a href=&quot;https://github.com/noctcore/showcase-kit/commit/cbe7e61740e3475d1d3d04b98fb7328b349980cb&quot;&gt;&lt;code&gt;cbe7e61&lt;/code&gt;&lt;/a&gt; Terminal apps: a shot no longer catches a frame the app is still drawing. A terminal can hand one write over in pieces (a macOS pty passes 1024 bytes at a time), so the &lt;code&gt;waitFor&lt;/code&gt; text could be on screen before the rest of its frame, and the shot came out cut off, with different bytes from run to run. Before every shot the kit now waits until the screen has not changed for 100 ms, which adds about 100 ms to each shot. An app that redraws the same frame on a timer settles at once. An app whose screen never stops changing (a clock, a spinner) is shot after at most 1 s, or sooner when the shot&apos;s &lt;code&gt;timeouts.shotMs&lt;/code&gt; runs out, with a warning; give it a frozen mode for captures, as the terminal determinism guide describes. Trailing separators in a CDP url, &lt;code&gt;outputs.portfolio&lt;/code&gt; and shim arguments are now trimmed in linear time, with the same results as before.&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry>
  <entry>
    <id>tag:noctcore.github.io,2026-09-24:showcase-kit/changelog/0.2.0</id>
    <title>@noctcore/showcase-kit 0.2.0</title>
    <updated>2026-09-26T21:49:07Z</updated>
    <link rel="alternate" type="text/html" href="https://noctcore.github.io/showcase-kit/changelog/#v0.2.0"/>
    <content type="html">&lt;h3&gt;Minor changes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/noctcore/showcase-kit/commit/33abe3853910d13dcae2b1f5862bb962e6f5742a&quot;&gt;&lt;code&gt;33abe38&lt;/code&gt;&lt;/a&gt; In url mode, a &lt;code&gt;nav&lt;/code&gt; path that starts with &lt;code&gt;/&lt;/code&gt; (&lt;code&gt;&apos;/docs/&apos;&lt;/code&gt;, or &lt;code&gt;{ goto: &apos;/docs/&apos; }&lt;/code&gt;) now resolves under the target url&apos;s path instead of its origin: with &lt;code&gt;url: &apos;https://x.io/app/&apos;&lt;/code&gt; or &lt;code&gt;&apos;https://x.io/app&apos;&lt;/code&gt; it visits &lt;code&gt;https://x.io/app/docs/&lt;/code&gt;. Configs that worked around this by repeating the base path (&lt;code&gt;&apos;/app/docs/&apos;&lt;/code&gt; with &lt;code&gt;url: &apos;https://x.io/app/&apos;&lt;/code&gt;) should drop the prefix. The base directory is the url&apos;s path; a last segment with a dot names a file and is dropped, like a relative link, so with &lt;code&gt;url: &apos;http://localhost:5173/index.html&apos;&lt;/code&gt;, &lt;code&gt;&apos;/about&apos;&lt;/code&gt; visits &lt;code&gt;http://localhost:5173/about&lt;/code&gt;. A trailing slash always means a directory (&lt;code&gt;https://x.io/v1.2/&lt;/code&gt;). &quot;Starts with &lt;code&gt;/&lt;/code&gt;&quot; is read the way the url parser reads it: a &lt;code&gt;goto&lt;/code&gt; that starts with a backslash (&lt;code&gt;&apos;\docs&apos;&lt;/code&gt;), or with a slash or backslash after leading spaces, tabs or control characters (&lt;code&gt;&apos; /docs&apos;&lt;/code&gt;), gets the same rule. So do protocol-relative spellings (&lt;code&gt;&apos;//host/x&apos;&lt;/code&gt;, &lt;code&gt;&apos;\\host/x&apos;&lt;/code&gt;, &lt;code&gt;&apos; //host/x&apos;&lt;/code&gt;): they no longer visit another host but stay on the target origin (&lt;code&gt;https://x.io/app//host/x&lt;/code&gt;). Every other &lt;code&gt;goto&lt;/code&gt; resolves exactly as in 0.1.1, with &lt;code&gt;new URL(goto, url)&lt;/code&gt;: &lt;code&gt;&apos;#/settings&apos;&lt;/code&gt; and &lt;code&gt;&apos;?tab=2&apos;&lt;/code&gt; keep the url&apos;s file (&lt;code&gt;http://h/app/index.html#/settings&lt;/code&gt;), &lt;code&gt;&apos;docs/&apos;&lt;/code&gt; and &lt;code&gt;&apos;../x&apos;&lt;/code&gt; resolve from the url as written, &lt;code&gt;&apos;https://other.dev/x&apos;&lt;/code&gt; is left alone, and a scheme with a relative path is relative when it matches the url&apos;s scheme (&lt;code&gt;&apos;https:docs&apos;&lt;/code&gt; with &lt;code&gt;url: &apos;https://x.io/app/&apos;&lt;/code&gt; visits &lt;code&gt;https://x.io/app/docs&lt;/code&gt;). With a url at the origin root (&lt;code&gt;http://localhost:5173&lt;/code&gt;), a root-relative path such as &lt;code&gt;&apos;/about&apos;&lt;/code&gt; visits the same page as before.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A url-mode config that repeats the url&apos;s base path in a &lt;code&gt;nav&lt;/code&gt; path (&lt;code&gt;&apos;/app/docs/&apos;&lt;/code&gt; or &lt;code&gt;{ goto: &apos;/app/docs/&apos; }&lt;/code&gt; with &lt;code&gt;url: &apos;https://x.io/app/&apos;&lt;/code&gt;) now visits &lt;code&gt;https://x.io/app/app/docs/&lt;/code&gt;. Drop the prefix and write &lt;code&gt;&apos;/docs/&apos;&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/noctcore/showcase-kit/commit/3274ec390186247d2f014b40c7b8e7f3cc4fa394&quot;&gt;&lt;code&gt;3274ec3&lt;/code&gt;&lt;/a&gt; New &lt;code&gt;outputs.readme: false&lt;/code&gt; for portfolio-only configs (&lt;code&gt;frame&lt;/code&gt; and &lt;code&gt;all&lt;/code&gt; skip the README images; portfolio and hero still render from the raw captures) and &lt;code&gt;outputs.portfolio.gallery: false | &apos;&amp;lt;path&amp;gt;.json&apos;&lt;/code&gt; to skip or relocate &lt;code&gt;showcase.gallery.json&lt;/code&gt;, for example out of a web root. &lt;code&gt;PortfolioResult.galleryFile&lt;/code&gt; is now &lt;code&gt;undefined&lt;/code&gt; when the gallery is skipped.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;TypeScript: &lt;code&gt;ResolvedConfig&lt;/code&gt;&apos;s &lt;code&gt;outputs.readme&lt;/code&gt; is now &lt;code&gt;string | false&lt;/code&gt; and &lt;code&gt;PortfolioResult.galleryFile&lt;/code&gt; is &lt;code&gt;string | undefined&lt;/code&gt;, so code that uses either as a &lt;code&gt;string&lt;/code&gt; stops compiling until it handles the new case.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/noctcore/showcase-kit/commit/07f120a3ccaab4dc85f779a7e07e5e7eb80179f1&quot;&gt;&lt;code&gt;07f120a&lt;/code&gt;&lt;/a&gt; Terminal clips: a tty config can list &lt;code&gt;clips&lt;/code&gt;, short animated recordings that &lt;code&gt;showcase record&lt;/code&gt; (and &lt;code&gt;showcase all&lt;/code&gt;) writes to &lt;code&gt;outputs.clips&lt;/code&gt; (default &lt;code&gt;assets/showcase/{lang}/{id}.{ext}&lt;/code&gt;). Each clip starts a fresh app and runs its &lt;code&gt;steps&lt;/code&gt; (&lt;code&gt;{ keys }&lt;/code&gt;, &lt;code&gt;{ type, delayMs? }&lt;/code&gt;, &lt;code&gt;{ waitFor }&lt;/code&gt;, &lt;code&gt;{ sleep }&lt;/code&gt;) on the kit&apos;s own frame clock at &lt;code&gt;fps&lt;/code&gt; (default 10), merges frames that did not change, and is framed like the README images with one frame render per clip. It ends &lt;code&gt;tailMs&lt;/code&gt; (default 1500) after the last step, at &lt;code&gt;durationMs&lt;/code&gt; (default 60000) or at &lt;code&gt;maxFrames&lt;/code&gt; (default 300 frames after merging, each held in memory until the clip is encoded), whichever comes first; the last two warn and still write what was recorded. The app may exit during the tail (a CLI that prints and exits, or a last step that quits it), which ends the clip on its last screen; exiting before the steps are done fails the clip. Most TUIs clear the screen when they quit, so leave the quit key out of the steps: the kit quits the app with &lt;code&gt;quitKey&lt;/code&gt; after the tail. Formats default to lossless animated WebP plus GIF; &lt;code&gt;&apos;mp4&apos;&lt;/code&gt; is opt-in and needs &lt;code&gt;ffmpeg&lt;/code&gt; on PATH. &lt;code&gt;showcase readme&lt;/code&gt; lists clips after the shots, and says why instead of printing an empty table when &lt;code&gt;outputs.readme&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt; and &lt;code&gt;--only&lt;/code&gt; names only shots. Clips in url and cdp mode are refused until web clips arrive in v0.3. New exports: &lt;code&gt;record&lt;/code&gt; and &lt;code&gt;encodeAnimation&lt;/code&gt; (frames plus delays in, WebP, GIF or MP4 out). &lt;code&gt;encodeAnimation&lt;/code&gt; refuses input it cannot encode with a &lt;code&gt;ShowcaseError&lt;/code&gt; and splits a delay longer than sharp&apos;s 65535 ms per frame into repeats that add up to it. For MP4, &lt;code&gt;ffmpeg&lt;/code&gt; is looked up in absolute PATH entries only, Ctrl+C stops it and removes its temporary folder, and an encode that runs over 5 minutes is stopped with an error.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/noctcore/showcase-kit/commit/1d571faa780bdaa6aca881786ac5db82ec395b2a&quot;&gt;&lt;code&gt;1d571fa&lt;/code&gt;&lt;/a&gt; Terminal apps: &lt;code&gt;target.mode: &apos;tty&apos;&lt;/code&gt; runs a TUI or CLI in a pseudo terminal and captures its screen into the same raw, framed, portfolio, hero and README outputs as web apps. Shots press &lt;code&gt;keys&lt;/code&gt; (or run a &lt;code&gt;nav&lt;/code&gt; function with the terminal session), wait for &lt;code&gt;waitFor&lt;/code&gt; text and can &lt;code&gt;restart&lt;/code&gt; the app; &lt;code&gt;ready&lt;/code&gt; is text on screen; a new &lt;code&gt;terminal&lt;/code&gt; block sets the theme, font, line height, padding and cursor, with JetBrains Mono bundled. Web-only keys (&lt;code&gt;viewport&lt;/code&gt;, &lt;code&gt;colorScheme&lt;/code&gt;, &lt;code&gt;css&lt;/code&gt;) are rejected in tty mode and tty-only keys in url and cdp mode. &lt;code&gt;showcase init --tty&lt;/code&gt; writes a starter config. Needs &lt;code&gt;@lydell/node-pty&lt;/code&gt; (or &lt;code&gt;node-pty&lt;/code&gt;) as an optional peer and Node, not the Bun runtime. The terminal engine is exported for scripts: &lt;code&gt;openTtySession&lt;/code&gt;, &lt;code&gt;renderTtyScreen&lt;/code&gt;, &lt;code&gt;resolveTerminalOptions&lt;/code&gt;, &lt;code&gt;parseKeys&lt;/code&gt;, &lt;code&gt;DARK_THEME&lt;/code&gt;, &lt;code&gt;LIGHT_THEME&lt;/code&gt; and &lt;code&gt;TERMINAL_DEFAULTS&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Types: &lt;code&gt;ShowcaseConfig&lt;/code&gt; is now &lt;code&gt;WebConfig&lt;/code&gt; or &lt;code&gt;TtyConfig&lt;/code&gt; (&lt;code&gt;defineConfig&lt;/code&gt; picks one from &lt;code&gt;target.mode&lt;/code&gt;), and &lt;code&gt;ResolvedConfig&lt;/code&gt; is &lt;code&gt;ResolvedWebConfig | ResolvedTtyConfig&lt;/code&gt;; narrow with &lt;code&gt;isTtyConfig(config)&lt;/code&gt; before reading web-only fields such as &lt;code&gt;viewport&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;TypeScript: code that reads a web-only field (&lt;code&gt;viewport&lt;/code&gt;, &lt;code&gt;colorScheme&lt;/code&gt;, &lt;code&gt;css&lt;/code&gt;) from a &lt;code&gt;ResolvedConfig&lt;/code&gt;, for example the result of &lt;code&gt;loadConfig&lt;/code&gt;, stops compiling. Narrow it first: &lt;code&gt;if (!isTtyConfig(config)) { ... }&lt;/code&gt;. A config file for url or cdp mode written with &lt;code&gt;defineConfig&lt;/code&gt; needs no change.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Patch changes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/noctcore/showcase-kit/commit/67be194cd790682e3e5a979a5914f36212b36ba7&quot;&gt;&lt;code&gt;67be194&lt;/code&gt;&lt;/a&gt; Terminal apps: &lt;code&gt;target.inheritEnv&lt;/code&gt; controls which of your environment variables the app gets (&lt;code&gt;true&lt;/code&gt; by default; &lt;code&gt;false&lt;/code&gt; or a list of names keeps tokens and home paths out of an app whose screen becomes a committed image, while &lt;code&gt;PATH&lt;/code&gt; and on Windows &lt;code&gt;PATHEXT&lt;/code&gt;, &lt;code&gt;SystemRoot&lt;/code&gt; and &lt;code&gt;ComSpec&lt;/code&gt; are still inherited so it can start). A CLI that prints its screen and exits at once is now captured instead of failing with &quot;exited before&quot;. Arguments passed through a Windows &lt;code&gt;.cmd&lt;/code&gt; or &lt;code&gt;.bat&lt;/code&gt; shim that contain &lt;code&gt;&quot;&lt;/code&gt; or &lt;code&gt;%&lt;/code&gt; are refused with a clear error (cmd.exe cannot pass them), and trailing backslashes arrive intact. &lt;code&gt;renderTtyScreen&lt;/code&gt; checks the theme of the look it is given. &lt;code&gt;openTtySession&lt;/code&gt; returns before Windows reports the app&apos;s PID, so Ctrl+C requests the terminal&apos;s teardown even that early.&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry>
  <entry>
    <id>tag:noctcore.github.io,2026-09-24:showcase-kit/changelog/0.1.1</id>
    <title>@noctcore/showcase-kit 0.1.1</title>
    <updated>2026-09-24T14:06:52Z</updated>
    <link rel="alternate" type="text/html" href="https://noctcore.github.io/showcase-kit/changelog/#v0.1.1"/>
    <content type="html">&lt;h3&gt;Patch changes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/noctcore/showcase-kit/commit/f39d6b37cb0a6123d3166f3918f3c296c8cfab03&quot;&gt;&lt;code&gt;f39d6b3&lt;/code&gt;&lt;/a&gt; Stopping a started command on Linux and macOS no longer waits the full two second grace period and then sends a needless SIGKILL: it now returns as soon as the process tree has exited on SIGTERM. When the host exits without calling &lt;code&gt;stop()&lt;/code&gt;, the process group is killed with SIGKILL right away instead of blocking the exit for two seconds.&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry>
  <entry>
    <id>tag:noctcore.github.io,2026-09-24:showcase-kit/changelog/0.1.0</id>
    <title>@noctcore/showcase-kit 0.1.0</title>
    <updated>2026-09-24T13:37:58Z</updated>
    <link rel="alternate" type="text/html" href="https://noctcore.github.io/showcase-kit/changelog/#v0.1.0"/>
    <content type="html">&lt;h3&gt;Minor changes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;First release: the &lt;code&gt;showcase&lt;/code&gt; CLI and a typed config API that capture an app&apos;s views (url mode in headless Chromium, or cdp mode for Electron and WebView2), frame them into README images, export exact-size 16:9 portfolio images with a gallery JSON, print a README image table, render a hero banner, and generate web, Electron and Tauri icon sets.&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry>
</feed>
