- β
- β
- August 27, 2026
-
π Console.dev newsletter PicoMQ rss
Description: Durable streams on object storage.
What we like: Each stream is independent and scales with the object store, so disks or capacity to manage. Benchmarked up to 100 MiB/s per stream. Metadata control plane independent from storage (SQL, either an ordered command log in Postgres or SQLite). The client is HTTP. One binary (Rust).
What we dislike: Not designed for very low latency - object storage commit often requires tens of milliseconds.
-
π Console.dev newsletter MicroLighter rss
Description: CSS syntax highlighter.
What we like: Lightweight, zero-dependency library for syntax highlighting. Uses the CSS highlight API with no runtime dependencies. Clean DOM, no markup (uses pre and code blocks). Auto-detects language or you can force it with a class.
What we dislike: Has bundled themes, but it requires some work and custom CSS variables to create custom themes.
-
π New Music Releases Above & Beyond - Quicksand (Donβt Go) (Ben Nicky remix) rss
Above & Beyond - a new release is available:
- 2026-08-27: Quicksand (Donβt Go) (Ben Nicky remix) (Single)
Amazon: Canada | Deutschland | France | United Kingdom | United States
Visit muspy for more information.
-
- August 26, 2026
-
π anthropics/claude-code v2.1.247 release
What's changed
- Added the
SendFeedbacktool: when something goes wrong in a session, Claude can draft a feedback report for you to review and send from/feedback(turn off with thefeedbackDraftssetting) - Added
{id, text, cooldownSessions, priority}entries,tipsFile, andlabeltospinnerTipsOverride, so organizations can rotate their own tips alongside the built-in ones - Added a tip on Bash permission prompts pointing to auto mode, with a one-keystroke "Yes, and switch to auto mode" option
- Added
/claude-api cost-optimizeto profile an existing project's Claude API spend and work through cost levers (caching, token hygiene, batch, effort, model choice) one measured change at a time - Updated the
/claude-apiskill with Admin API coverage (organization members, invites, workspaces, API keys, rate limit reports, workload identity federation, CMEK) - Fixed fast arrow-key + Enter sequences acting on the row above the one you navigated to in history search,
/config,/mcp,/skills, background tasks, and/model - Fixed sub-agents dying on a first-call model 404: they now use the session's fallback model chain, and the error returned to the parent includes the error type, status, request id, and model
- Fixed a hook or background agent that printed megabytes of error output being able to overflow the conversation and wedge the session on "Prompt is too long"
- Fixed Ctrl keyboard shortcuts not firing under non-Latin (e.g. Cyrillic) keyboard layouts in kitty-protocol terminals
- Fixed text like
<35;150;7Mbeing inserted into the prompt when a mouse report arrived split across reads right after the escape prefix - Fixed the Bash sandbox's after-command cleanup deleting a dotfile-managed
~/.claude/settings.jsonsymlink (nix/home-manager, stow) when it is repointed outside the sandbox's writable area - Fixed
/terminal-setupoverwriting your entire Zedkeymap.jsoninstead of merging in its keybinding - Fixed
/renamesilently confirming when the session registry could not be updated; it now says other sessions may still show the old name - Fixed
/compactand "Summarize from here" in sessions started with--agentsummarizing under the default system prompt instead of the conversation's own - Fixed a background session showing "openingβ¦" forever in
claude agentsafter its terminal host process died; the row now fails within seconds with the reason, and Enter restarts it - Fixed unbounded memory growth when a hook's or background task's output file could not be written; the file now notes where output was lost
- Fixed
/install-github-appover SSH: the copy shortcut now says how the sign-in URL was copied instead of always claiming success, and the URL appears immediately when no browser can open - Fixed shell commands carried over from the foreground logging an internal error or showing a misleading
[exited with code -1]line when they finish in background sessions - Fixed a version-less marketplace plugin's live cache directory being deleted and recreated on a second-scope install, which could disrupt a running session using it
- Fixed Remote Control sessions started with
/remote-controlnot reporting the working-tree diff to connected clients - Fixed self-hosted runner sessions reporting
runningbefore Claude Code had started, which could trigger a premature "Claude is waiting for your input" notification from the Claude desktop app - Fixed first-run setup exiting with "Unable to connect to Anthropic services" when managed settings configure Claude apps gateway sign-in and Anthropic endpoints are unreachable
- Fixed cloud sessions (Claude Code on the web, desktop and mobile apps) sometimes showing the previous permission mode when you switch modes right after sending a message
- Fixed cloud sessions going silent when the session's container restarts between turns while a background agent, shell, or monitor is still running β the resumed session now reports the lost work
- Improved plugin marketplace hardening: names containing control or invisible characters are rejected, and marketplace-supplied text in
/pluginandclaude pluginoutput is escape-safe - Improved Bedrock, Vertex, and Foundry sessions (and any with telemetry disabled): Claude is now told when a configured MCP server failed to connect, instead of concluding its tools don't exist
- Changed Sonnet 5's default auto-compact window to its full 1M context, so sessions on the 1M window now auto-compact at about 967K tokens instead of about 934K
- Changed cross-session peer messages to collapse by default to a one-line
Message from @<sender>: <first line>preview; Ctrl+O expands the full body - Changed terminal hyperlinks in rendered markdown: link targets that point at a network or automounter path, contain a control character, or lead with an invisible character now render as plain text
- Changed the prompt-footer PR badge to skip its GitHub re-check on terminal refocus when the last check is under a minute old
- Changed analytics to stay off from startup, not only after login, when managed settings force gateway login or a custom OAuth deployment is configured
- Changed Claude apps gateway sign-in requests to identify Claude Code (a
surface=claude_codedevice-authorization parameter and aclaude-code/<version>User-Agent) - Changed organization sign-in enforcement to exit at start when the administrator's managed settings cannot be read, even if host-supplied or per-user Windows registry settings exist
- Added the
-
π gildas-lormeau/single-file-cli v2.3.1 release
New features
- Crawls and batch captures (
--urls-file) now print their progress on stderr, e.g.[3/25] saved https://example.com (example.html)(ref #163, #23)
Fixes
- Fixed cross-origin (site-isolated) frames being saved empty with an extra 5s delay per capture. They are now captured like same-origin frames
- Fixed
--blocked-URL-pattern,--http-header,--emulate-media-feature, the user-agent emulation and--browser-ignore-insecure-certsnot being applied in cross-origin frames - Fixed
--blocked-URL-patternand--http-headernot being applied when resources are fetched outside the browser (e.g. when fetching a resource from the page fails due to CORS) - Fixed the invisible DEL character in the default value of
--filename-replaced-characterdisplayed by--help - Fixes from single-file-core 1.5.96 to 1.5.98, including: fixed broken references to SVG symbols with ids starting with a digit (fix gildas-lormeau/SingleFile#1936), fixed invalid nesting of BODY elements (fix gildas-lormeau/SingleFile#1954), removed FileReader usage to support Safari Lockdown Mode (fix gildas-lormeau/SingleFile#1973), fixed a memory leak when capturing pages repeatedly in the same tab
Co-authored by Claude (Claude Code)
- Crawls and batch captures (
-
π PrimeIntellect-ai/prime-agent Beta (v0.8.1-beta.553.1.bc0fa76) release
Automated beta build from
main(bc0fa7606abb3b7af0f765319518d255e6ae553d). -
π r/LocalLLaMA Can we reconsider the megathreads? rss
In the past during model releases there used to be tons of interesting discussions happening on this subreddit. However, the new rules of forcing everything into a single megathread almost completely killed off the discussions as far as I can tell. I get that some people didn't like seeing 10 posts with just the HF link but imo the change wasn't worth it.
Megathreads are bad for several reasons. Firstly, they make any topic be buried under all the comments with very few ways to find a specific discussion again in case you want to come back to it later. Secondly, comments are just not well suited for posting charts, tables and longer texts that are useful when discussing benchmarks or experiences with the new models. And lastly, megathreads themselves aren't that visible in the first place, I think most people dont even notice them most of the time (though admittedly this is a reddit problem not specific to this subreddit).
Just look at the two megathreads up right now, there is barely any activity going on in them and only a fraction of the comments in there have actual back and forth discussions happening.
submitted by /u/TKristof
[link] [comments] -
π r/LocalLLaMA Whoever the fuck predicted we would have gpt 5.5 performance in coding on consumer hardware a couple months ago now, i applaud you rss
Like wtaf? Qwen 3.8 27b is crazy. Can't wait for kimi k3 performance
submitted by /u/GrokiniGPT
[link] [comments] -
π MetaBrainz GSoC 2026: Bringing Internationalization (i18n) to BookBrainz rss
Introduction
Greetings, everyone!
I am Garv Thakre (@garvthakre:matrix.org on Matrix), an Agentic-AI FullStack Developer . This summer, I had the opportunity to participate in Google Summer of Code 2026 with MetaBrainz, where I worked on the internationalization (i18n) for BookBrainz.
I was mentored by Nicolas Pelletier (@monkey:chatbrainz.org on Matrix). This post summarizes my project, its outcomes, and my experience over the course of the program.
Project Overview
BookBrainz aims to collect information about every book ever written, but until now, the interface was only in English. Since books exist in thousands of languages, having an English-only UI made it tough for non-English contributors to navigate, read, or add metadata.
My main goal this summer was to get BookBrainz ready for translation and set up the foundation so the community can actually start localizing it. Here is what that involved:
- Client-side setup: Integrated
react-i18nextto handle translations dynamically across the UI. - Locale detection: Built middleware to detect the user's language based on browser headers, URL paths (like
/es/), or cookies. - Automate the workflow: Set up
i18next-parserto automatically extract translatable strings from TSX and JSX components and update JSON translation keys. - Weblate Integration: Configured the pipeline to sync our translation keys with the MetaBrainz Weblate instance, enabling the community to easily translate BookBrainz into multiple languages.
- Secure the codebase: Integrates a CI check to prevent hardcoded untranslated strings from being committed.
- Migrate key interfaces: Systematically refactored all core pages from user registration and search to detailed entity views and the complex Unified Form editor to make them translatable.
Project Deliverables & Milestones
1. Setting up the i18n infrastructure & automation
Before migrating pages, I needed an automated pipeline so developers wouldn't have to manage translation keys manually or worry about breaking localized strings.
react-i18nextintegration: Addedi18nextandreact-i18nextto the frontend, utilizing theuseTranslationhook for dynamic strings and the<Trans>component to handle inline formatting without chopping up sentences.- Automated string extraction: Configured
i18next-parserto scan our TypeScript and JavaScript files. It searches for translation keys (e.g.,t('key')) and automatically extracts them into our primary translation template (en/translation.json), sorting them alphabetically to avoid merge conflicts. - Locale detection middleware: Wrote middleware to determine the user's language preference by checking request headers, URL subdirectories (like
/es/), or cookies. - CI pipeline integration: Added a custom workflow in GitHub Actions that runs tests to ensure no translated keys are missing. If any raw, untranslated text is found in newly modified files, the CI build fails, protecting the codebase from future translation regression.
2. Migrating Core Layouts & Auth Pages
After completing the foundation, the next phase was migrating the most visible static content, navigation layouts, and user authentication components:
- Header & footer layouts: Refactored the main header, nav links, button bars, and footer so the base app shell pulls strings dynamically from our translation files and integrated i18next pluralization rules for active button bars.
- Static informational pages: Ported static informational pages like guidelines and "About" sections. Because these had long paragraphs, I broke them into clean, logical key structures rather than huge walls of text.
- User account workflows & error pages: Migrated login/registration pages, user profile edit pages, and core application error pages (like 404 and 500 errors), including localized validation checks.
3. Refactoring Entity Pages & Dynamic Relationships
BookBrainz revolves around connected metadata for various entities: Author, Work, Edition, Publisher, and Series. Migrating these details pages required refactoring complex dynamic structures:
- Entity display pages: Refactored the display components and metadata tables for all core entity types. This ensures fields like publisher details, release dates, and medium descriptions translate seamlessly based on the user's selected language.
- Relationship view components: Refactored how relationships are displayed (e.g., showing that a Work is "written by" an Author or an Edition is a "translation of" another).
- Dynamic content interpolation: Solved challenges around injecting variable metadata (like entity names, dates, or external identifier badges) into translated sentences without breaking grammatical order across different languages.
- Entity merge & comparison views: Localized the complex side-by-side metadata comparisons shown when merging duplicate works, editions, or author profiles.
- Search pages & search admin: Refactored search result displays, search input fields, filters, and the search administration interface.
- User annotations & identifiers: Migrated sections displaying user-submitted annotations and external identifiers (like Wikidata and MusicBrainz links).
4. Localizing the Unified Form Editor
The Unified Form Editor is BookBrainzβs heaviest componentβit handles multi- entity creation and editing across multiple tabs, making it the most complex part of the migration.
- Multi-tab interface: Refactored the entire editing flow, covering the Cover tab, Content tab, and the final Submission Summary screen.
- Interactive dynamic fields: Refactored complex interactive features, such as the dynamic ISBN input field validation, work-row additions, and author credit selectors.
- Create-entity modals: Localized helper modals (like the entity quick-creation popups and search-entity-create-select dropdowns) to guide contributors seamlessly as they input metadata.
- Deduplicating keys: Cleaned up overlapping translation keys across similar form inputs (like "Name", "Title", and "Role") to avoid redundant translation work on Weblate.
Next Steps
With the core internationalization architecture now mostly integrated into the codebase, these are the immediate next steps to complete:
- Completing Weblate integration: Fully sync the extracted
translation.jsonfile with the MetaBrainz Weblate platform. This will allow community translators to translate BookBrainz via Weblate. - Migrating remaining pages: Finish migrating the few remaining pages and older legacy components that haven't been fully refactored to use the translation pipeline yet
Pull Requests and Commits
You can view the full list of my pull requests, code contributions, and commits made during Google Summer of Code 2026 here:
- GitHub Link: My GSoC 2026 Pull Requests and Commits
Final Thoughts & Acknowledgements
This summer has been an incredibly rewarding journey. Working on Google Summer of Code with MetaBrainz has allowed me to dive deep into a large-scale React and TypeScript codebase, learn the complexities of designing and automating localization workflows, and participate in active open-source collaboration.
I want to extend my deepest gratitude to my mentor, Nicolas Pelletier aka Monkey , for his invaluable support, constructive feedback on my PRs, and patient guidance during our chats and code reviews. and really thankful for always answering my silly questions.
I would also like to thank the entire MetaBrainz community for creating such a welcoming and collaborative environment. I am excited to see BookBrainz support multiple languages soon and look forward to continuing my contributions to the project in the future!
REALLY THANKFUL AND WISHING GOOD LUCK TO THE WHOLE METABRAINZ TEAM.
- Client-side setup: Integrated
-
π r/LocalLLaMA zai-org/GLM-5.3-Flash Β· Hugging Face rss
| submitted by /u/coder543
[link] [comments]
---|--- -
π r/LocalLLaMA GLM-5.3-Flash: Frontier Intelligence, Flash Cost rss
submitted by /u/BriguePalhaco
[link] [comments] -
π gildas-lormeau/single-file-cli v2.3.0 release
SingleFile CLI 2.3.0
New features
- Added the
--crawl-save-archive-page-transitionsoption to control page transitions when navigating in multi-page archives. The possible values are "auto" (default, i.e. transitions run only when pages opt in via an@view-transitionCSS rule), "fade" (the previous behavior) and "none" - Added the weekday template variables, e.g.
{weekday-locale}and{weekday-short-utc}(fix gildas-lormeau/SingleFile#1948)
Behavior changes
- The process now exits with code 1 when at least one capture fails. Batches and crawls still complete, and the exit codes (0, 1, 255) are documented in the README
- Page transitions in multi-page archives now run only when pages opt in via CSS instead of always crossfading (see
--crawl-save-archive-page-transitionsabove)
Fixes
- Fixed saving pages enforcing Trusted Types via a Content Security Policy (fix #199, #24). This requires a browser based on Chromium 151 or newer,
--browser-bypass-CSPcan be used as a fallback with older versions - Fixed
--browser-remote-debugging-urlnot being recognized as an alias of--browser-server - Fixed a latent error when a capture was aborted while waiting for a timeout
- The Docker image now explicitly disables the single-process mode of the browser (it can still be overridden by passing
--browser-single-process) - Fixes from single-file-core 1.5.93 to 1.5.95, including: PDFs saved with
--embed-pdfare now also stored as the first entry of the zip content, fixed@importrewriting when saving original URLs (fix gildas-lormeau/SingleFile#1961), fixed a hang when processing stylesheets larger than 16MB (fix gildas-lormeau/SingleFile#1962), fixed identity mappings and special characters in filename replacements
Co-authored by Claude (Claude Code)
- Added the
-
π HexRaysSA/plugin-repository commits sync repo: ~222 changed rss
sync repo: ~222 changed ## Changes - [ApplyCalleeTypeEx](https://github.com/dump-guy/applycalleetypeex): - 1.0.0: metadata updated (platforms) - [AutoRE](https://github.com/a1ext/auto_re): - 2.3.0: metadata updated (platforms) - 2.2.0: metadata updated (platforms) - [BinSync](https://github.com/binsync/binsync): - 5.15.2: metadata updated (platforms) - 5.15.1: metadata updated (platforms) - 5.15.0: metadata updated (platforms) - 5.14.1: metadata updated (platforms) - 5.14.0: metadata updated (platforms) - 5.13.0: metadata updated (platforms) - 5.12.0: metadata updated (platforms) - [Binwalk](https://github.com/kevinmuoz/binwalk-reversing-plugin): - 0.0.1: metadata updated (platforms) - [CrystalRE](https://github.com/nico-posada/crystalre): - 1.3.0: metadata updated (platforms) - 1.2.1: metadata updated (platforms) - 1.1.0: metadata updated (platforms) - 1.0.0: metadata updated (platforms) - [DBImporter](https://github.com/hexrayssa/ida-dbimporter): - 0.0.2: metadata updated (platforms) - 0.0.1: metadata updated (platforms) - [EmuIt](https://github.com/azzonfire/emuit): - 0.8.1: metadata updated (platforms) - [FeelingLucky](https://github.com/terrynini/feelinglucky): - 1.0.3: metadata updated (platforms) - 1.0.2: metadata updated (platforms) - 1.0.1: metadata updated (platforms) - 1.0.0: metadata updated (platforms) - [HappyIDA](https://github.com/happyida/happyida): - 1.0.6: metadata updated (platforms) - 1.0.5: metadata updated (platforms) - 1.0.4: metadata updated (platforms) - 1.0.3: metadata updated (platforms) - 1.0.2: metadata updated (platforms) - 1.0.1: metadata updated (platforms) - 1.0.0: metadata updated (platforms) - [HashDB](https://github.com/oalabs/hashdb-ida): - 1.10.0: metadata updated (platforms) - [IDA-MCP](https://github.com/captain-ai-hub/ida-mcp): - 0.8.1: metadata updated (platforms) - 0.8.0: metadata updated (platforms) - 0.7.1: metadata updated (platforms) - 0.7.0: metadata updated (platforms) - 0.6.3: metadata updated (platforms) - 0.6.2: metadata updated (platforms) - 0.6.1: metadata updated (platforms) - 0.6.0: metadata updated (platforms) - [IDA-Theme-Explorer](https://github.com/kevinmuoz/ida-theme-explorer): - 1.0.3: metadata updated (platforms) - 1.0.2: metadata updated (platforms) - 1.0.0: metadata updated (platforms) - [IDAGuides](https://github.com/libtero/idaguides): - 1.3.0: metadata updated (platforms) - 1.2.0: metadata updated (platforms) - 1.1.1: metadata updated (platforms) - 1.1.0: metadata updated (platforms) - [IDAssist](https://github.com/symgraph/idassist): - 2.1.0: metadata updated (platforms) - 2.0.0: metadata updated (platforms) - 1.9.0: metadata updated (platforms) - 1.7.0: metadata updated (platforms) - 1.6.0: metadata updated (platforms) - 1.5.0: metadata updated (platforms) - 1.4.0: metadata updated (platforms) - 1.3.0: metadata updated (platforms) - 1.2.0: metadata updated (platforms) - [IDAssistMCP](https://github.com/symgraph/idassistmcp): - 1.4.0: metadata updated (platforms) - 1.3.0: metadata updated (platforms) - 1.2.0: metadata updated (platforms) - 1.1.0: metadata updated (platforms) - 1.0.3: metadata updated (platforms) - [IFL](https://github.com/hasherezade/ida_ifl): - 1.5.3: metadata updated (platforms) - [Patching](https://github.com/starsunyzl/idapatching): - 0.3.0: metadata updated (platforms) - [SigMaker](https://github.com/mahmoudimus/ida-sigmaker): - 1.14.3: metadata updated (platforms) - 1.14.2: metadata updated (platforms) - 1.14.1: metadata updated (platforms) - 1.14.0: metadata updated (platforms) - 1.13.0: metadata updated (platforms) - [Structline](https://github.com/libtero/structline): - 1.0.0: metadata updated (platforms) - [SuperHint](https://github.com/p05wn/superhint): - 1.2.2: metadata updated (platforms) - 1.2.1: metadata updated (platforms) - 1.0.0: metadata updated (platforms) - [Suture](https://github.com/libtero/suture): - 1.2.5: metadata updated (platforms) - 1.2.10: metadata updated (platforms) - 1.2.0: metadata updated (platforms) - 1.1.0: metadata updated (platforms) - 1.0.0: metadata updated (platforms) - [ZoomAllViews](https://github.com/dump-guy/zoomallviews): - 1.0.1: metadata updated (platforms) - [augur](https://github.com/0xdea/augur): - 0.9.3: metadata updated (platforms) - 0.9.2: metadata updated (platforms) - 0.9.1: metadata updated (platforms) - 0.9.0: metadata updated (platforms) - 0.8.1: metadata updated (platforms) - 0.8.0: metadata updated (platforms) - 0.7.5: metadata updated (platforms) - 0.7.4: metadata updated (platforms) - 0.7.3: metadata updated (platforms) - [bitopt](https://github.com/teflate/bitopt): - 1.0.1: metadata updated (platforms) - 1.0.0: metadata updated (platforms) - [bookmark-hints](https://github.com/williballenthin/idawilli): - 0.1.3: metadata updated (platforms) - 0.1.2: metadata updated (platforms) - [capa](https://github.com/mandiant/capa): - 9.4.0: metadata updated (platforms) - 9.3.1: metadata updated (platforms) - 9.3.0: metadata updated (platforms) - [clang-include](https://github.com/oxikkk/ida-clang-include): - 1.2.0: metadata updated (platforms) - 1.1.0: metadata updated (platforms) - 1.0.0: metadata updated (platforms) - [colorize-calls](https://github.com/williballenthin/idawilli): - 0.1.3: metadata updated (platforms) - 0.1.2: metadata updated (platforms) - [deREferencing](https://github.com/danigargu/dereferencing): - 2025.9.24: metadata updated (platforms) - [decode_instruction](https://github.com/milankovo/decode_instruction): - 1.0.0: metadata updated (platforms) - [diaphora](https://github.com/joxeankoret/diaphora): - 3.4.1: metadata updated (platforms) - 3.4: metadata updated (platforms) - [edit-function-prototype](https://github.com/oxikkk/ida-edit-function-prototype): - 1.0.0: metadata updated (platforms) - [extensible-hints](https://github.com/williballenthin/idawilli): - 0.1.3: metadata updated (platforms) - 0.1.2: metadata updated (platforms) - [funcfiletree](https://github.com/rand-tech/idaplugins): - 1.0: metadata updated (platforms) - [function-string-associate](https://github.com/oxikkk/ida-function-string-associate): - 1.0.1: metadata updated (platforms) - 1.0.0: metadata updated (platforms) - [gepetto](https://github.com/justicerage/gepetto): - 1.5.0: metadata updated (platforms) - [haruspex](https://github.com/0xdea/haruspex): - 0.9.3: metadata updated (platforms) - 0.9.2: metadata updated (platforms) - 0.9.1: metadata updated (platforms) - 0.9.0: metadata updated (platforms) - 0.8.1: metadata updated (platforms) - 0.8.0: metadata updated (platforms) - 0.7.5: metadata updated (platforms) - 0.7.4: metadata updated (platforms) - 0.7.3: metadata updated (platforms) - [hint-calls](https://github.com/williballenthin/idawilli): - 0.1.3: metadata updated (platforms) - 0.1.2: metadata updated (platforms) - [hrtng](https://github.com/kasperskylab/hrtng): - 3.9.108: metadata updated (platforms) - 3.9.105: metadata updated (platforms) - 3.8.94: metadata updated (platforms) - 3.8.88: metadata updated (platforms) - 3.7.74: metadata updated (platforms) - [iOSHelper](https://github.com/yoavst/ida-ios-helper): - 1.0.19: metadata updated (platforms) - 1.0.17: metadata updated (platforms) - [icp](https://github.com/rand-tech/idaplugins): - 1.3: metadata updated (platforms) - [ida-chat](https://github.com/tanu360/ida-chat-plugin): - 1.0.1: metadata updated (platforms) - 1.0.0: metadata updated (platforms) - [ida-codemode](https://github.com/hexrayssa/ida-codemode): - 0.6.1: metadata updated (platforms) - 0.6.0: metadata updated (platforms) - 0.5.3: metadata updated (platforms) - 0.5.2: metadata updated (platforms) - 0.5.1: metadata updated (platforms) - 0.5.0: metadata updated (platforms) - 0.4.1: metadata updated (platforms) - 0.4.0: metadata updated (platforms) - 0.3.2: metadata updated (platforms) - 0.3.1: metadata updated (platforms) - 0.3.0: metadata updated (platforms) - 0.2.0: metadata updated (platforms) - [ida-cyberchef](https://github.com/hexrayssa/ida-cyberchef): - 0.3.2: metadata updated (platforms) - 0.3.1: metadata updated (platforms) - 0.2.0: metadata updated (platforms) - 0.1.0: metadata updated (platforms) - [ida-nativeaot](https://github.com/dump-guy/ida-nativeaot): - 1.0.2: metadata updated (platforms) - 1.0.1: metadata updated (platforms) - 1.0.0: metadata updated (platforms) - [ida-nexus](https://github.com/hexrayssa/ida-nexus): - 0.7.0: metadata updated (platforms) - 0.6.2: metadata updated (platforms) - [ida-outliner](https://github.com/milankovo/ida_outliner): - 1.2.0: metadata updated (platforms) - 1.1.1: metadata updated (platforms) - 1.1.0: metadata updated (platforms) - 1.0.0: metadata updated (platforms) - [ida-security-scanner](https://github.com/symbioticsec/ida-security-scanner): - 0.0.1: metadata updated (platforms) - [ida-settings-editor](https://github.com/williballenthin/ida-settings): - 1.2.3: metadata updated (platforms) - 1.2.1: metadata updated (platforms) - 1.1.1: metadata updated (platforms) - 1.1.0: metadata updated (platforms) - 1.0.2: metadata updated (platforms) - 1.0.1: metadata updated (platforms) - 1.0.0: metadata updated (platforms) - [ida-taskr](https://github.com/mahmoudimus/ida-taskr): - 1.0.3: metadata updated (platforms) - [ida-terminal-plugin](https://github.com/hexrayssa/ida-terminal-plugin): - 0.0.6: metadata updated (platforms) - [idalib-rust-bindings](https://github.com/idalib-rs/idalib): - 0.9.0: metadata updated (platforms) - 0.8.1: metadata updated (platforms) - 0.8.0: metadata updated (platforms) - 0.10.0: metadata updated (platforms) - [idamagicstrings](https://github.com/joxeankoret/idamagicstrings): - 1.2.0: metadata updated (platforms) - [idasvg](https://github.com/chichou/idasvg): - 0.1.0: metadata updated (platforms) - [idavator](https://github.com/mahmoudimus/idavator): - 0.1.1: metadata updated (platforms) - [llm-explainer](https://github.com/pgarba/ida-llm-explainer): - 1.9.0: metadata updated (platforms) - 1.8.0: metadata updated (platforms) - 1.7.3: metadata updated (platforms) - 1.7.0: metadata updated (platforms) - 1.6.2: metadata updated (platforms) - 1.3.0: metadata updated (platforms) - [mcrit-ida](https://github.com/danielplohmann/mcrit-plugin): - 1.1.9: metadata updated (platforms) - 1.1.8: metadata updated (platforms) - 1.1.7: metadata updated (platforms) - [navigator](https://github.com/rand-tech/idaplugins): - 1.3: metadata updated (platforms) - [oplog](https://github.com/williballenthin/idawilli): - 0.3.0: metadata updated (platforms) - 0.2.0: metadata updated (platforms) - 0.1.3: metadata updated (platforms) - 0.1.2: metadata updated (platforms) - [rhabdomancer](https://github.com/0xdea/rhabdomancer): - 0.9.3: metadata updated (platforms) - 0.9.2: metadata updated (platforms) - 0.9.1: metadata updated (platforms) - 0.9.0: metadata updated (platforms) - 0.8.1: metadata updated (platforms) - 0.8.0: metadata updated (platforms) - 0.7.6: metadata updated (platforms) - 0.7.5: metadata updated (platforms) - 0.7.4: metadata updated (platforms) - 0.10.0: metadata updated (platforms) - [showcomments](https://github.com/merces/showcomments): - 0.6.0: metadata updated (platforms) - 0.5.1: metadata updated (platforms) - 0.5.0: metadata updated (platforms) - [tag-func](https://github.com/williballenthin/idawilli): - 0.1.3: metadata updated (platforms) - 0.1.2: metadata updated (platforms) - [tc_deer](https://github.com/arkup/tc_deer): - 0.1.3: metadata updated (platforms) - 0.1.2: metadata updated (platforms) - 0.1.0: metadata updated (platforms) - [unicorn-tracer-arm64](https://github.com/chenxvb/unicorn-trace): - 0.4.0: metadata updated (platforms) - 0.3.1: metadata updated (platforms) - 0.3: metadata updated (platforms) - 0.2: metadata updated (platforms) - 0.1: metadata updated (platforms) - [vt-ida-plugin](https://github.com/virustotal/vt-ida-plugin): - 1.0.8: metadata updated (platforms) - 1.0.7: metadata updated (platforms) - 1.0.6: metadata updated (platforms) - [vtable-context-tools](https://github.com/oxikkk/ida-vtable-tools): - 1.1.0: metadata updated (platforms) - 1.0.2: metadata updated (platforms) - 1.0.1: metadata updated (platforms) - 1.0.0: metadata updated (platforms) - [xray](https://github.com/hexrays-plugin-contributions/xray): - 2025.9.24: metadata updated (platforms) - [yarg](https://github.com/r0ny123/yarg): - 1.0.5: metadata updated (platforms) - 1.0.4: metadata updated (platforms) - 1.0.3: metadata updated (platforms) - 1.0.2: metadata updated (platforms) - 1.0.1: metadata updated (platforms) - [yarka](https://github.com/azzonfire/yarka): - 0.7.2: metadata updated (platforms) -
π jellyfin/jellyfin 12.0 RC6 release
π Jellyfin Server 12.0 RC6
We are pleased to announce the sixth release candidate preview release of Jellyfin 12.0!
This is a preview release, intended for those interested in testing 12.0 before its final public release. We welcome testers to help find as many bugs as we can before the final release.
As always, please ensure you stop your Jellyfin server and take a full backup before upgrading!
A note about versioning
Starting with this release, we are dropping the preceding
10.from our versioning. Thus,10.11.x->[10.]12.x=12.x. The reason is simple: at this point in the project, we don't envision a hard break in the API like we planned way back in the early days, and this version scheme was causing a lot of confusion amongst users about what a "major" release was. For more information, please see the RC1 release notes.What's new?
The main goal of this release has been performance.
10.11.0dropped a major backend rewrite, and while it was broadly functional, it had a lot of rough edges. This release seeks to polish out most of those rough edges and bring better performance to all users.There are many other small fixes, improvements, changes, and translations. See our draft release notes here or below for the full list of pull requests. You can also view the Web side changelog here.
Note: You must be on Jellyfin 10.10.7+ or 10.11.x (ideally, 10.11.11) before upgrading! If you are not, the upgrade will fail. Ensure you upgrade to one of these versions first!
Note: The initial load of Jellyfin 12.x will run a few migrations and will take several minutes. Please be patient and do not interrupt the process. You can leverage the (newly improved!) startup UI on your local network to see specific progress, or off-network to see general progress, by visiting the server URL in your web browser during startup.
Note: If you install the RC, you should disable all external plugins and reinstall using the unstable plugin repository, or plugins may fail to load and cause unintended side effects.
Installing
This preview release is distributed in all our traditional forms, though not automatically via our Apt repository or
latesttag.- For all non-Docker environments, you can find the files for manual download in our repository by selecting "Stable Preview" for your OS.
- For Docker, you can pull the
12.0-rc6orpreviewtags.
What's Changed (since
- Update dependency z440.atl.core to 7.16.0 by @renovate[bot] in #17551
- Fix FindArtists by @theguymadmax in #17604
- Update Microsoft to 10.0.11 by @renovate[bot] in #17615
- Fix unit test for localization of Artists in DE by @IDisposable in #17633
- Fix other two unit test for localization of Artists in DE by @IDisposable in #17637
- Recognize WEB-DL release tags in video names by @st7105 in #17636
- Update github/codeql-action action to v4.37.7 by @renovate[bot] in #17630
- Update dependency Microsoft.NET.Test.Sdk to 18.9.0 by @renovate[bot] in #17638
- Update dependency dotnet-ef to v10.0.11 by @renovate[bot] in #17614
- Fix large playlist persistence with WhereOneOrMany by @martin-77 in #17655
- Fix SQLite variable limit in child count batches by @martin-77 in #17658
- Update Microsoft to 5.9.0 by @renovate[bot] in #17665
- Prevent orphaned user permissions and preferences by @m0g3r in #17643
- Fix GitHub URL typo in CONTRIBUTORS by @FirmaSpring in #17659
- Use client-reported position for idle playback cleanup by @itsb in #17631
- More resilient MusicBrainz lookup by @Shadowghost in #17670
- Stop user updates from orphaning permission and preference rows by @Shadowghost in #17645
- Fix latest items for mixed libraries by @theguymadmax in #17678
- Allow direct play for HDHomeRun Live TV tuners by @theguymadmax in #17682
- Fix GHSA-wwwm-px48-fpvq by @crobibero in #17685
- Optimize query helper memory by @Shadowghost in #17607
- Safeguard against invalid provider ids by @Shadowghost in #17584
- Fall back to the ancestor filter when a view has no top parents by @Shadowghost in #17691
- Mark breakOnNonKeyFrames as XMLIgnore by @Shadowghost in #17698
- Look up people by item via the credit map instead of a full scan by @Shadowghost in #17700
- Fix English metadata blocking localized providers ranked below it by @Shadowghost in #17619
- Fix series merging leaking across libraries and under-counting merged children by @Shadowghost in #17693
- Fix person metadata not being fetched on demand or by the people task by @Shadowghost in #17702
- Update dependency UTF.Unknown to 2.7.0 by @renovate[bot] in #17697
- Say which image and item failed instead of logging a blank path by @Shadowghost in #17711
- Fix OMDB People handling by @Shadowghost in #17710
- Fix IsPlayed and IsUnplayed sorting for shows and collections by @LTe in #17713
- Stop deriving user view ids from their localized name by @Shadowghost in #17714
- Build a TMDb series cast from the aggregated credits by @Shadowghost in #17716
- Delete credits nothing maps to and bound item-by-name folder names by @Shadowghost in #17715
- Persist the refresh stamp so the people task stops redoing its work by @Shadowghost in #17709
New Contributors
- @st7105 made their first contribution in #17636
- @martin-77 made their first contribution in #17655
- @m0g3r made their first contribution in #17643
- @FirmaSpring made their first contribution in #17659
- @itsb made their first contribution in #17631
Full Changelog :
v12.0-rc5...v12.0-rc6 -
π smol-machines/smolvm smolvm v1.13.0 release
What's Changed
- Re-stage a damaged image-archive cache entry instead of trusting that the path exists by @BinSquare in #1058
- Fail when the release lookup fails instead of falling back to a hardcoded 0.1.1 by @NickyHeC in #1059
- Ship the guest Chromium wrapper in the desktop recipes with software WebGL enabled by @BinSquare in #1055
- Give a pack machine's first boot a start window that covers the layer unpack by @BinSquare in #1056
- Add SECURITY.md by @NickyHeC in #983
- Floor host loopback in the default local egress mode by @BinSquare in #1060
- Support nested machine checkpoints by @BinSquare in #1062
- Extract packed layers on the host when the pack predates in-guest unpacking, instead of handing its agent tars it cannot read by @BinSquare in #1064
- Release 1.13.0 by @BinSquare in #1063
Full Changelog :
v1.12.0...v1.13.0 -
π r/LocalLLaMA First serious confirmation. Ox Alpha is GLM-5.3-Flash rss
https://x.com/romanchernin/status/2092488160680751437?s=20
- Multimodal (Vision)
- 1M Tokens Context Window
- DeepSWE ~63%
Edit: He deleted it, screenshot in comments
submitted by /u/MrWidmoreHK
[link] [comments] -
π PrimeIntellect-ai/prime-agent v0.8.1 release
- Fixed syntax highlighting in the expanded python tool-call view: triple-quoted strings spanning multiple lines now keep their string color instead of only the first line.
- Changed the default RLM maximum recursion depth for new sessions from 1 to 2.
- Changed ACP prompt requests to resolve only after all causally admitted subagent and parent work has settled.
- Changed the Cloudflare AI Gateway default model to claude-sonnet-4.5 after the catalog dropped the gateway's workers-ai mirror ids.
- Fixed ACP assistant chunks to identify message boundaries across autonomous turns.
-
π Rust Blog Announcing our first Maintainers in Residence rss
We are very happy to announce the Rust Project's first round of Maintainers in Residence: Gen Li (@rami3l), Chris Denton (@ChrisDenton), Alejandra GonzΓ‘lez (@blyxyas), LeΓ³n Liehr (@fmease), and Maintainer Grant recipients: Jason Newcomb (@Jarcho) and Jonas BΓΆttiger (@joboet). These contributors will be funded for their
rust-langmaintenance activities for (at least) the following 12 months!The funding of the Maintainer in Residence (MiR) and Maintainer Grantee roles is possible thanks to generous donations to the Rust Foundation Maintainers Fund (RFMF) from Google, AWS, OpenAI, the Rust Project Leadership Council and also individual sponsors. We also want to thank the people who advocated for maintainer funding within their companies; Tyler Mandry from Google, Niko Matsakis and Jess Izen from AWS and Predrag Gruevski from OpenAI, and also the whole Rust Leadership Council and our funding advisors. If you would like to help us support even more Rust contributors, consider donating to RFMF.
The Rust Foundation has published a press release and a blog post, where you can learn more about the sponsors and the supported contributors.
Read more below to learn about the MiR program, how we chose the funded contributors, and of course who they are!
Background
The Maintainer in Residence program, established in RFC 3931, is designed to provide stable financial support for Rust contributors, so that they can truly focus on crucial maintenance activities. Currently, there are three categories of support that we offer:
- Full-time MiR: funded for 5 days/week of Rust Project work
- Half-time MiR: funded for ~2.5 days/week of Rust Project work
- Maintainer Grant: funded for ~1 day/week of Rust Project work
Funding for this program comes from the Rust Foundation Maintainers Fund, which was launched recently, and the whole program is managed by the Rust Funding team.
When deciding who to fund, we took a systematic approach. First, we looked at Rust teams to understand their maintenance baseline (the smallest number of maintainers they need to ensure a healthy long-term status of the given project or repository), and how far they currently are from that baseline. From there, we identified and prioritized Rust teams who were both critically underfunded, and have a high impact on the language and its users. These teams (in no particular order) were
rustdoc,rustup,cargo,compiler,libs,clippy,rustfmt,rust analyzerandmods.The next step was pairing these teams with maintainers looking for funding. And it turns out that finding such maintainers for some teams turned out to be much more difficult than we originally assumed! For example, some maintainers are already employed, some do not want to be funded, and while we did our best to promote our funding efforts, not everyone looking for funding actually asked us for it. We also realized that some teams on our list have essentially no active members, which makes it tricky to onboard new contributors, even if they would like to help out.
In the end, we decided to start by supporting six contributors, who will help maintain several critical Rust projects and teams and who could start immediately. However, we are not stopping there. Our funding efforts are ongoing, so stay tuned for more MiR announcements in the near future! If you would like to learn more about our process, check out our recent post.
And now, without further ado, let's meet our newly funded maintainers!
Gen Li (@rami3l)

Gen Li (@rami3l) is a full-time MiR focusing on Rustup.
He has been a Rustup team member since 2023 and its lead since 2025. He deeply cares about the facets of Rust that many might have taken for granted, and embodies all attributes we were looking for in a MiR: he wants to take on complex issues, continue mentoring, and work on important Rustup features, among many other things.
Turning volunteering into an actual job has really been an empowering experience so far! I finally have the bandwidth to take a careful look at my inbox and can actually read each message without the fear of missing crucial details while rushing prompt replies, which has really helped me retain the essential compassion as a maintainer. I also get to interact with regular contributors a lot more often. Finally, I can't wait to see what I can come up with in terms of Project Goals :)
Chris Denton (@ChrisDenton)

Chris Denton (@ChrisDenton) is a half-time MiR focusing on the standard library, compiler, Rustup and anything Windows- related.
For the past five years Chris has been bringing his deep knowledge of Windows to help Rust sustain and improve its great cross-platform support. He will be unblocking other contributors in various Windows use cases, performing refactoring and code reviews and implementing new features across several areas of the Project.
Even though it is still early days, I'm feeling pretty optimistic about the health of the Rust Project going forward, thanks to the recent funding efforts.
Alejandra GonzΓ‘lez (@blyxyas)

Alejandra GonzΓ‘lez (@blyxyas) is a half-time MiR focusing on Clippy.
She is a Clippy team member always keen on improving performance and helping new contributors. She will focus on making Clippy faster and also reviewing its pull requests, to help get the ~300 pull request backlog down. Additionally, she is excited to mentor people from the Rust for Linux project to work on Clippy, and fine tune the open peer review system that Clippy started using earlier this year.
Funding is the system that helps me pour my heart into a project without worrying about making ends meet. Having those needs met is a game-changer and boosts my productivity. One of the areas where I want to focus my efforts is mentoring new contributors. If new people coming is the lifeblood of a project, I want to be the cardiologist!
LeΓ³n Liehr (@fmease)

LeΓ³n Liehr (@fmease) is a half-time MiR focusing on rustdoc and the compiler.
He is a member of the rustdoc and compiler teams, who is usually working on the Rust type system or issues related to parsing. He will continue working on complex features that he started a few years ago, and also focus on general maintenance, code reviews, refactoring and mentoring.
Being funded to work on Rust means I can sustainably focus my time and energy on a project I call a passion of mine.
Jonas BΓΆttiger (@joboet)

Jonas BΓΆttiger (@joboet) is a maintainer grantee focusing on the standard library.
He is a musicology student from Germany. When he is not playing the Cello or reading about Fanny Hensel, he applies his research skills to ensure that programs written in Rust run quickly and soundly on all platforms, no matter how quirky the operating system may be. He loves helping contributors write excellent code that they can be proud of; and considers it to be just as much fun as writing it himself.
Getting funding for my work is a dream come true. It will allow me to continue doing the thing I love instead of worrying about whether I should rather invest all that time in a money-earning job with much less positive impact on the world around me.
Jason Newcomb (@Jarcho)

Jason Newcomb (@Jarcho) is a maintainer grantee focusing on Clippy.
He is primarily working on fixing bugs and making it easier to develop and contribute to Clippy. He is also focusing on making the review process as smooth as possible.
Being funded allows me to work on something I care about and want to work on instead of what will get me paid. I'm looking forward to seeing how this will impact Clippy and the Rust project in general.
Conclusion
The contributors presented above will be funded for the next 12 months, though of course we hope that we will be able to extend their support going further, as this program is designed to be for long-term stable maintenance funding. We are very excited about them; each one of them has been with the Project for years, and we are very glad that we can support their maintenance work! All of them have already signed their contracts, so they are already being funded as we speak.
While there are many other Rust contributors who are doing awesome work, and who would also deserve to get proper funding for it, we think that this is a great start. We hope that the awesome work done by the funded maintainers will allow us to promote this program, so that we can fund even more Rust contributors!
We would like to once again sincerely thank everyone who made this possible, especially our sponsors. If you would like to help us fund more maintainers, consider donating to RFMF. You can also sponsor individual Rust contributors directly.
-
- August 25, 2026
-
π IDA Plugin Updates IDA Plugin Updates on 2026-08-25 rss
IDA Plugin Updates on 2026-08-25
Activity:
- augur
- c5bb29eb: feat: use the -locked flag for cargo commands
- disrobe
- 87ba8f37: wasm: ratchet capability reachability ceiling
- 6795e4a7: annotate recovered wasm signedness in typescript
- 09d0a813: python: expose flutter engine symbol maps
- 8ba7a246: cli: read flutter engine maps from config
- 42e05c77: cache Flutter engine symbol summaries locally
- 8ba46797: wasm: keep native image parsing out of the browser graph
- f186d47e: flutter: apply build-id matched external symbol maps
- ba45d412: flutter: validate external engine symbol maps
- 0f42dd56: wasm: declare sandboxed recovery tests
- 98484e99: wasm: reject selector memory overlaps and bulk writes
- de71d6bc: wasm: recover immutable local-offset memory selectors
- 087723a0: native: prove elf unwind header auto routing
- 98db3292: native: seed aarch64 starts from elf unwind headers
- 0381cd6a: rar: reject undersized itanium filter blocks
- 6ecbc86a: binfmt: bound pmarc decoding and validate pm2 trees
- b0ad596d: python: publish 5,225 recovered 3.10 objects
- 60df9c29: python: recover shared returns after pre-3.11 exception handlers
- e5a91517: mba: satisfy the rule-pack iterator lint
- 88c8f128: mba: trace the peephole pack through wasm recovery
- c15d791f: mba: complete peephole rule table coverage
- haruspex
- ida-bochs-binaries
- ipyida
- 165c4c37: Add a ida-plugin.json file so the hcli repo finder robot picks up ourβ¦
- rhabdomancer
- 5e96cc17: feat: use the
--lockedflag forcargocommands
- 5e96cc17: feat: use the
- xrefgen
- 8139606d: Pin CI to Ubuntu 22.04 runners
- 6b38cc06: Cancel stale CI matrix runs
- 18067261: Canonicalize cached return summaries
- 1168619d: Remove stale string result taxonomy
- da171dc0: Publish corpus precision summaries
- 4ec9bdea: Harden incremental dataflow cache invalidation
- b4d55878: Fix typed architecture callsite classification
- bfedba31: Unify distributed configuration defaults
- d8facb68: Expand external corpus and incremental validation
- 492506b7: Document calibrated corpus coverage
- 0a07acd2: Add positive C++ corpus ground truth
- a1e5a77a: Clarify experimental WASM and heuristic similarity claims
- 4c71e26f: Verify incremental cache across IDB reopen
- cd171c8f: Add positive corpus ground truth fixtures
- 1d07fd12: Skip unavailable optional cross-target corpus builds
- dbcdcdbf: Verify incremental checker in release smoke
- 2fa93f37: Add IDA incremental equivalence verifier
- 350c4ad4: Type analyzer outputs as semantic results
- c17f1e04: Filter Hex-Rays fallthrough call targets
- 9e560582: Reject unresolved direct and zero call targets
- augur
-
π anthropics/claude-code v2.1.246 release
What's changed
- Added a startup warning for Bash allow rules with a wildcard before the subcommand (e.g.
Bash(git * main)), since they also match options inserted before the subcommand - Added an Auto mode tab to
/permissionsfor viewing and editing auto mode classifier rules - Added the turn's completion time to the end-of-turn duration line, e.g.
β» SautΓ©ed for 23s Β· done 6:05 PM - Fixed fullscreen mode showing a blank transcript after resizing the terminal and jumping to the bottom until the next keypress
- Fixed a severe transcript slowdown when a diff contained a very long single line (e.g. a base64 string); such lines now render truncated with a marker
- Fixed erratic fullscreen scrolling when positioned at an earlier message, including jump-to-bottom getting stuck mid-transcript
- Fixed background sessions failing to open after 45 seconds when Claude Code's starting directory had been deleted, the machine had slept, or the host is slow to start processes
- Fixed background sessions failing to open with "Couldn't start the background service β¦ EACCES" when another Claude Code process was re-installing the npm package at that moment
- Fixed markdown rendering being disabled for a whole message when its first 500 characters contained no markdown, and for
+/N)lists and setext headings - Fixed MCP tool calls interrupted by an incoming message in headless/remote sessions being reported to the model as "completed with no output" instead of an explicit interrupted error
- Fixed MCP tool arguments being sent as JSON strings when the parameter's schema is empty (
{}), instead of their real type - Fixed a command interrupted mid-run showing as "Ran 1 shell command" with no sign it was cut
- Fixed pressing β or running
/backgroundduring a dynamic workflow restarting its finished subagents; it now asks first and says how many subagents would restart - Fixed opening a just-started session in
claude agentswhile its worker was still booting (common on Windows) stopping it with "was stopped while the respawn was in flight" - Fixed
claude agentslisting a backgrounded named session twice; backgrounding the same conversation again now numbers the new row (e.g.my-session (2)) - Fixed the background retention sweep removing git worktrees under
.claude/worktrees/that you created yourself when an old background-session record pointed at them - Fixed auto mode tool calls being denied as "temporarily unavailable" on very large sessions by scaling the safety-check deadline with prompt size
- Fixed the plugin cache creating duplicate SHA-named directories for the same plugin
- Fixed plugin skills whose frontmatter
namealready includes the<plugin>:prefix showing it doubled in the slash menu (e.g./plugin:plugin:skill) - Fixed
claude plugin updatefailing for an installed plugin given its bare name (only the fully-qualified name worked) - Fixed plugin installation failing when
plugin.jsonwas saved with a UTF-8 byte-order mark (BOM) - Fixed
/reload-pluginsreporting 0 skills for plugins that define skills underskills/*/SKILL.md - Fixed hook error messages showing a literal
${CLAUDE_PLUGIN_ROOT}instead of the resolved plugin path - Fixed
/renamereplacing the theme's prompt border color (including a custom theme'spromptBorder) with the default cyan; the border now keeps your theme's color unless you pick one with/color - Fixed custom theme diff colors (
diffAdded/diffRemovedand their dimmed variants) being ignored in diffs and the/themepreview - Fixed a
keybindings.jsonbinding with an unknown action name silently deadening that key; it is now skipped so the default binding keeps working, and a warning is logged under--debug - Fixed
/statsactivity heatmap showing each day's activity one cell off (Sunday's count under Monday) in timezones east of UTC - Fixed
/forkfrom an already-forked or backgrounded session starting the new session with an empty conversation - Fixed prompts beginning with
/--(e.g. Lean doc comments) being rejected as an unknown slash command instead of being sent to Claude - Fixed the
@file picker staying open after the typed text stopped matching a real path - Fixed the status line's cost and duration resetting to zero after navigating to the agents view and back
- Fixed fullscreen mode moving keyboard focus onto the control under the pointer when you clicked the terminal window only to bring it back into focus
- Fixed path completion failing when the completion token or working directory contained a null byte
- Windows/macOS: Fixed headless sessions not cleaning up stale entries in
~/.claude/sessionsleft by sessions that exited uncleanly - Fixed the UI stopping with a render error on the first tool call when a third-party Anthropic-compatible endpoint (
ANTHROPIC_BASE_URL) streams atool_useblock without anid - Fixed the Write tool reporting "Out of memory" or freezing for a long time after overwriting a very large existing file, even though the file had been written
- Fixed
claude plugin install <name>exiting silently (or hanging in a terminal) instead of reporting an error when~/.claude/plugins/known_marketplaces.jsonis empty or corrupted - Fixed resumed sessions failing every turn with a 400 when the saved history contains tool blocks the Anthropic API does not accept (typically written by a third-party API proxy)
- Fixed
curl -fsSL https://claude.ai/install.sh | bashfailing with "Raw mode is not supported" for some Team/Enterprise users with server-managed settings - Fixed sessions that ended in plan mode resuming outside plan mode in the VS Code extension, and in
claude -p --continue/--resumewith a permission prompt tool, when no permission mode was set - Fixed the
Notificationhook not firing while the sandbox "Network request outside of sandbox" permission prompt is waiting - Fixed Bash permission checks to always require approval for malformed commands with a dangling
&&or||operator - Fixed
--strict-mcp-configsessions prompting to approve.mcp.jsonservers they would never load, which left background sessions waiting at startup - Fixed telemetry and metrics requests to Anthropic carrying the API key configured for a third-party gateway (
ANTHROPIC_BASE_URL); a credential is now only sent to its own host - Fixed a visible API error on the first prompt after idle when
apiKeyHelperreturns short-lived JWTs: an expired cached token is now refreshed before sending, and 401/403 auth errors retry quietly - Fixed memory growing with session length in the fullscreen and Ctrl+O transcript views: each rendered message row no longer retains a full copy of the transcript-wide tool lookups
- Fixed
/ultrareviewruns and cloud sessions launched at the same time from one repository (e.g. from several worktrees) sometimes starting with another launch's uncommitted changes - Fixed the task progress count (e.g.
3/5) shown for background cloud sessions such as/autofix-proccasionally missing a task - Fixed Remote Control sessions keeping their placeholder name in claude.ai and the Claude app until the second prompt; the auto-generated title now appears after the first prompt
- Fixed MCP tools marked
requiresUserInteractionstill offering "Yes, and don't ask again" in their permission prompt; the option wrote an allow rule the tool then ignored - Fixed the self-hosted runner ending its live sessions or exiting when a work-poll response is malformed (e.g. an intercepting proxy's HTML page); it now retries the poll
- Improved
/cd: the new directory's project settings, hooks,.mcp.jsonservers (behind the usual approval prompt), skills, and agents now take effect right after the move instead of on--resume - Improved Bash tool latency on bash shells by replaying snapshot functions without a base64 subshell per function
- Improved subagent results: a subagent that stops at its
maxTurnslimit now returns its output marked as partial, with a hint to continue it viaSendMessage, instead of appearing finished - Improved non-interactive sessions (
-p, SDK, cloud sessions) to automatically continue a response cut off mid-stream by a server error, connection loss, or stall instead of ending with an error - Improved attribution of usage telemetry to your organization for workload identity federation sessions, events sent while
apiKeyHelperruns at startup, and after a login token expired while idle - Changed
/code-reviewso Claude can also start it on its own on Bedrock, Vertex AI, and Foundry, through the Claude apps gateway, and when telemetry or non-essential traffic is disabled /goal: Changed idle sessions to start at most three check-ins on long-running background work per goal; your next message allows three more- Changed
claude installandclaude updateto defer a pending managed-settings consent prompt to the next interactive session instead of prompting mid-command - Changed OpenTelemetry plugin events for plugins synced from claude.ai:
plugin_id_hashnow reflects the plugin's real marketplace, andenabled_viaisadmin-installfor admin-installed plugins - Fixed the command sandbox's filesystem configuration not respecting
--setting-sources
- Added a startup warning for Bash allow rules with a wildcard before the subcommand (e.g.
-
π r/LocalLLaMA Qwen3.8-Flash-Next. This architecture could be surprisingly local-friendly once the weights drop. π rss
| Qwen3.8-Flash-Next (~125B-A6B + 51B n-gram) memory estimate: Ideal 4-bit quant β 82 GB
(58 GB main weights + 24 GB n-gram tables)
Real-world quants likely land in the 80β90 GB range. The big n-gram table is sparsely accessed β excellent candidate for system RAM offload. This architecture could be surprisingly local-friendly once the weights drop. submitted by /u/pmv143
[link] [comments]
---|--- -
π modem-dev/hunk v0.20.0 release
What's Changed
Hunk 0.20 makes it easier to install, keep current, and extendβwhile making everyday reviews faster and more precise.
Highlights
- Install Hunk on macOS and Linux with a checksum-verified curl installer, then keep npm, Homebrew, and curl installations current with
hunk update, by @benvinegar in #799 and #788. - Explore a searchable directory of 12 community extensions covering GitHub reviews, Mercurial, search, CODEOWNERS, commit-by-commit workflows, exports, and more, introduced by @benvinegar in #811, with catalog contributions from @phl28, @gentilfp, and @sadick254 in #822, #826, and #842.
- Build deeper integrations with exact selected-line context and immutable snapshots of reviewed files and saved notes, by @benvinegar in #779 and #833.
- Click exact diff linesβincluding blank linesβand open inline comments without shifting their target code, by @benvinegar in #840 and #809.
- Navigate and revisit highlighted diffs with less work, while
--fastnow offloads syntax highlighting for eligible files with 40 or more lines, by @benvinegar in #791, #803, and #810.
Release notes : https://hunk.dev/changelog/0.20/
Full Changelog :v0.19.0...v0.20.0 - Install Hunk on macOS and Linux with a checksum-verified curl installer, then keep npm, Homebrew, and curl installations current with
-
π @binaryninja@infosec.exchange Sidekick for everyone sounded better than Sidekick for some. Today we launched mastodon
Sidekick for everyone sounded better than Sidekick for some. Today we launched Sidekick Free! If you have an active Binary Ninja license, you now have Sidekick too. No extra purchase or signup needed. See what it can do: https://sidekick.binary.ninja/free
-
π r/LocalLLaMA Apple releases M5 ultra at 1.2TB/s bandwith rss
| lpddr5x probably, the m7 ultra if is using ddr6 should be at 1.8 Tb/s submitted by /u/Last-Owl-8342
[link] [comments]
---|--- -
π r/LocalLLaMA Apple introduces new Mac Studio with M5 Max and M5 Ultra - up to 512GB of unified memory rss
| submitted by /u/themixtergames
[link] [comments]
---|--- -
π r/LocalLLaMA Qwen 3.8 Flash Next day 0 support from unsloth rss
| Prepare your disk space guys submitted by /u/jacek2023
[link] [comments]
---|--- -
π modem-dev/hunk v0.19.1 release
What's Changed
Hunk 0.19.1 improves CPU compatibility, npm installation, and diff rendering.
Highlights
- Run x64 builds on pre-Haswell processors and conservative VM CPU models by @elucid in #797.
- Install cleanly from npm with executable platform binaries and without unnecessary Pierre dependencies for CLI-only users by @benvinegar in #844 and #847.
- Keep reviews fast and visually accurate by caching complex Unicode width measurements and preserving Git moved-line colors on wrapped rows by @benvinegar and @HackAttack in #800 and #812.
Release notes : https://hunk.dev/changelog/0.19/
Full Changelog :v0.19.0...v0.19.1 -
π r/LocalLLaMA Qwen3.8-Flash-Next tomorrow rss
| submitted by /u/rerri
[link] [comments]
---|--- -
π anthropics/claude-code v2.1.245 release
What's changed
- Fixed a crash on startup on Linux distributions that ship glibc 2.44 (for example Arch Linux, CachyOS and Fedora Rawhide)
-
π BarutSRB/OmniWM OmniWM v0.6.3 release
What's New Since 0.6.2
0.6.3 adds focus-without-raise, configurable fullscreen margins, Start at Login, Quake Terminal microphone support, and low-perturbation performance captures. It also hardens settings recovery, focus ownership, animation, lock- screen handling, Hidden Bar, and the AX apply path.
Before You Upgrade β Breaking Changes
- Your
settings.tomlis replaced with defaults on first launch unless you edit it first. 0.6.3 requires two new fields that a normal 0.6.2 file does not contain. Without them, OmniWM preserves the old file byte-for-byte assettings.toml.corruptorsettings.toml.corrupt.1, replaces the live file with full defaults, and starts from those defaults. Nothing is destroyed, but your configuration stops applying until you restore it.
To avoid the reset entirely, merge these values into the existing sections before upgrading:
[focus] raiseOnMouseFocus = true [gaps] fullscreenUsesOuterGaps = falseraiseOnMouseFocus = truekeeps the 0.6.2 hover behavior β the new default isfalse.fullscreenUsesOuterGaps = falsematches the new default and preserves existing fullscreen geometry.If 0.6.3 has already reset a normal 0.6.2 file, quit OmniWM, recover from whichever of
settings.toml.corruptorsettings.toml.corrupt.1contains the preserved file under your XDG config directory (normally~/.config/omniwm), add both fields, and restore the corrected file.-
Settings now use the complete current schema. Missing or decode-invalid required values no longer inherit defaults. 0.6.2 repaired absent keys and a few specific invalid values β many malformed TOML types already failed decoding there β so the practical change for anyone who hand-edits
settings.tomlis that a missing required key now invalidates the whole file and triggers the preserve-and-reset above. The hotkey list must contain every assignable action exactly once; unknown, unassignable, missing, or duplicate action IDs invalidate the file. Unknown non-hotkey extension keys at the top level and inside known tables remain diagnosed and preserved across successful saves; unknown keys nested inside arrays such asappRulesare diagnosed but may be dropped on save. A third distinct invalid file fails closed if both write-once recovery slots are already occupied. -
Focus Follows Mouse no longer raises windows by default. Hover focus now targets the specific window without deliberately activating its app, issuing AX Raise, or changing SkyLight ordering. Enable Raise Window When Focus Follows Mouse or set
focus.raiseOnMouseFocus = truefor the 0.6.2 full-fronting behavior. -
Overview keyboard navigation changed. Arrow keys navigate spatially. Left and Right stay inside the current workspace, moving between windows that share a row and wrapping at that row's ends. Tab and Shift-Tab now cycle forward and backward through all matching windows instead of acting as horizontal navigation.
-
IPC visibility is more exact. SkyLight ordered-out windows now report
isVisible: false/is-visible: falseand are excluded byquery windows --visible. Automation that treated visible-workspace membership as sufficient may receive fewer windows. -
Display query output gained a field.
query displaysadds thefullscreen-uses-outer-gapsdisplay field and itsfullscreenUsesOuterGapsJSON property, which thedisplay-changedsubscription payload carries as well. Full table, text, and TSV output gain aFULLSCREEN GAPScolumn, so positional parsers must update. This is additive on IPC protocol 11; no command path, query name, selector, or existing wire field was removed or renamed. -
Trackpad scroll sensitivity is normalized. Hand-edited values outside
0.1...100are clamped before use, whilenan,inf, and-infuse the default value of5. The normalized value is written on the next successful settings save. -
Direct
OmniWMIPCsource consumers have three removals.IPCWorkspaceSummary,IPCAutomationManifest.subscriptionDescriptor(for:), andIPCSocketPath.resolvedSecretPath(environment:fileManager:)are gone. The secret path can be composed withsecretPath(forSocketPath: resolvedPath(...)).OmniWMIPCis not published as a library product, so this does not change the shipped v11 wire protocol or normalomniwmctluse.
No hotkey action IDs or default bindings changed in 0.6.3. The config and runtime-state locations, IPC socket path, and CLI command paths are also unchanged, and OmniWM still requires macOS 26+ on Apple Silicon.
Headline Features
- Start at Login is now available under Settings β General β Startup. OmniWM mirrors the live macOS registration state, explains when approval is required, and links to Login Items. This is per-machine system state, not a portable TOML key. #593
- Fullscreen outer margins can be kept globally or per display for OmniWM Full Screen, Niri maximized layouts, and the Single Window βFull Screenβ fit. Workspace Bar reservations remain in effect; native macOS Full Screen is unchanged. The default is off, preserving previous fullscreen geometry once the settings file is updated or regenerated.
- Focus without raise lets Focus Follows Mouse change keyboard focus without intentionally bringing an obscured window forward. The new setting can restore the previous raise-and-front behavior. #602
- Performance Capture can be started from Diagnostics or the status menu, and Issue Reporting reflects a capture that is already running. It records bounded OmniWM-process CPU, energy, wakeup, I/O, and memory deltas alongside owner-local counters with low measurement perturbation, auto-stops after ten minutes, and retains the newest five performance captures. Problem captures also gain end-to-end frame lineage through intake, layout, AX writes, retries, and WindowServer observation.
- Quake Terminal microphone support lets hosted terminal apps request audio-input permission through OmniWM. macOS may show an OmniWM microphone prompt the first time a child app requests it;
omniwmctlremains unentitled. #597
Window Management and Focus
- Tiled windows dragged by their native title bar now return to their authoritative tile after mouse-up, including delayed AX and WindowServer echoes. Modifier-driven Niri interactions and remembered floating geometry remain intact. #561
- Temporarily hidden tiled windows reveal at the current accepted layout frame instead of stale historical geometry.
- Windows returned to tiled mode before quitting now remain tiled after restart while retaining remembered floating geometry for a later toggle.
- System-modal dialogs and hands-off application surfaces no longer trigger automatic focus recovery or get displaced by newly admitted floating windows. Focused dialogs also survive identity rekeys. #565 #577
- When a focused floating app quits, OmniWM restores the workspace's retained tiled focus without disturbing Niri viewport or Dwindle selection state.
- Background apps' stale AX focused-window callbacks can no longer steal focus from the actual frontmost app. Managed-focus retries are bounded and stale owned surfaces are retired. This is automatic; no per-app focus-stealing override was added. #594
- Private window activation now posts a complete synthetic click, preventing Ghostty from retaining a missing mouse-up and buffering rendering. #569
- Niri no longer snaps the viewport backward when the trailing column grows or leaves full-span mode. #580 #590
Overview, Animation, and Surfaces
- Overview transitions now use a display-link session on each participating display, reverse safely when toggled mid-transition, and close cleanly when display topology changes.
- Overview spatial navigation now respects visual rows and Niri column geometry, while Tab cycling stays linear across filtered results.
- Dwindle animations begin only after their matching layout plan is accepted, so stale or replaced plans cannot leave phantom motion running.
- Animation ticks avoid redundant AX size writes when trusted geometry confirms the size is unchanged. Border motion and size-preserving tab-rail moves are grouped into the display-link SkyLight transaction to reduce visual drift.
- Abandoned gestures settle and release their display-link sessions instead of leaving animation work alive.
Lifecycle, Responsiveness, and Settings
- Layout refresh and animation work pause while the screen is locked, then resume only after a usable post-unlock topology sample, protecting native-fullscreen and window state across lock and wake transitions.
- Trackpad frames are coalesced in a bounded mailbox and duplicate scroll delivery is removed, preventing burst input from accumulating amplified motion.
- Hidden Bar refreshes from app, display, activation, and panel lifecycle events instead of polling every second. It also discovers status items created by already-running apps and bounds unknown/open menu recovery.
- Prevent Sleep now holds one continuous assertion only for the enabled active user session, releasing it on disable or session resignation and reacquiring it on return.
- AX frame writes, notification queues, input queues, diagnostic storage, surface lifetimes, and focus retries are bounded and cleaned up deterministically under bursts and shutdown.
- Core runtime paths avoid redundant AX/Core Foundation bridging, specialize frame-only updates, reuse unchanged reconciliation snapshots, and cache Overview and layout work to reduce allocation and copy churn.
- The Diagnostics Private-API Probe now tests only eligible unmanaged foreign windows, confirms transaction movement through WindowServer, and restores a window only while its process, window ID, and observed origin still match.
- Symlinked
settings.tomlfiles now survive atomic saves and recovery while preserving the resolved regular-file target and permissions. Dangling, cyclic, and non-file targets fail closed. #583
CLI, Documentation, and Thanks
- The CLI reference now documents the complete existing command surface and clarifies layout-aware behavior. These documentation additions do not add or remove command paths.
- The documentation now links the community-maintained OmniWM Computer Use skill and OmniCast Raycast extension.
- The in-app and README credits now include crbelaus with BlueLabs affiliation, and ryoppippi (@ryoppippi) joins Omni Sponsors.
- Alexander Dergachev (@Cy6erBr4in) contributed Start at Login in #593, Yuri Chukhlib (@YuriNachos) contributed the Overview navigation foundation in #581, crbelaus (@crbelaus) contributed symlink-aware settings in #583, and Ngo Quoc Viet (@NgoQuocViet2001) completed the CLI reference in #579 and joins the contributor list.
Release Integrity
The OmniWM app is Developer ID signed, Apple-notarized, stapled, and Gatekeeper verified.
OmniWM-v0.6.3.zipSHA-256:ac3443418394c6f9ed1f9980d44a176ba2cf7aa576ccddcea67683f9e1ce2e25GhosttyKit.xcframework-v0.6.3.zipSHA-256:5a5c57b470ce184cfa57e13b59732cb7d367101934658b4f9e5cf32a282264bb
- Your
-
π gildas-lormeau/single-file-cli v2.2.2 release
SingleFile CLI 2.2.2
Fixes
- Fixed the Docker image build possibly embedding the previous npm version of the CLI because of an npm propagation delay. The build now installs the exact released version (the v2.2.1 image shipped with 2.2.0)
Co-authored by Claude (Claude Code)
-
π gildas-lormeau/single-file-cli v2.2.1 release
SingleFile CLI 2.2.1
Fixes
--browser-single-processis now enabled by default only on Windows. Current browsers on other platforms no longer support this mode, which made every capture on Linux pay a failed browser launch before the automatic fallback (up to 30 seconds with Chrome, and a wasted browser start on every run of the Docker image)
Co-authored by Claude (Claude Code)
-
π gildas-lormeau/single-file-cli v2.2.0 release
SingleFile CLI 2.2.0
New features
- Added
--crawl-save-archiveto save all the crawled pages into a single self-extracting ZIP file. The archive displays the pages with hash-based navigation, supports deep links to inner pages, and can be unzipped to browse the pages offline. It requires--compress-content - Added
--crawl-save-archive-dedupto deduplicate identical resources shared between pages in the archive - Added
--crawl-save-archive-mark-unarchived-linksto mark links pointing to pages not saved in the archive - Added
--crawl-save-archive-tocto store a table of contents page in the archive, accessible from the#sfz/?tocroute
CLI fixes and improvements
- Crawl options like
--crawl-no-parentor--crawl-max-depthnow fail with an error when--crawl-linksis not set. They were silently ignored before (#189 by @brasswood) - Clarified the syntax of
--filename-replaced-characterin the help message (#184 by @paraknell) - Digest template variables, e.g.
{url-href-digest-sha-1}, now work when saving pages served overhttp:(single-file-core#5)
Docker image
- The image is now based on
node:24-alpineand uses the Chromium version packaged by Alpine Linux. This fixes the "WebSocket is not available" error caused by the outdated Node.js version of the previous base image (#205 by @k1rinh) - The image is now built and published automatically when a release is published, for the
linux/amd64andlinux/arm64platforms, and tagged with the release version in addition tolatest
Co-authored by Claude (Claude Code)
- Added
-
π seanmonstar Micro: Using LLMs to find not-that-rock rss
Imagine someone tells you to get them a rock. You go find one, bring it back, and they reply βno, not that rockβ. They didnβt know exactly what they wanted, but they knew yours wasnβt it.
When writing, I always start by dumping a detailed outline with points and subpoints. And then, ugh, I feel a wall. How do I turn this into prose? I ask an LLM to try, I look at the ablated text, and I hate it. No, definitely not that rock. More like this.
-
π Filip Filmar Fuchsia Internals, Vol. I: The Graphics and Display Pipeline rss
Volume I of my Fuchsia Internals report series is the graphics and display pipeline, and it is a deliberate choice for the first deep-dive: graphics is a complete worked application that exercises nearly every kernel primitive at once. Fuchsia decomposes what Linux would put in a monolithic DRM/KMS subsystem into a set of cooperating user-space services that talk to each other over FIDL typed channels with zero-copy shared VMOs. The full PDF is linked at the bottom.
-
π Szymon Kaliski Play with Putty rss
Play with Putty is a research experiment in collaborative vibe coding β an exploration where multiple people, together with fast LLMs, iterate on multiplayer-first projects in real time:
We'll share more about this soon β for now you can sign up for the waitlist.
Made at Google Labs.
-
π Ampcode News Setup Without a Commit rss
You can now store scripts to set up orbs outside of your repository. Amp can store pre-clone and pre-setup scripts in your project settings and access them when spawning an orb.
The pre-clone setup script gives Amp anything it needs before it clones the repository:
- Install Git extensions that fetch files during checkout.
- Configure certificates for an internal Git server.
- Configure a network proxy needed to reach the Git server.
- Connect the orb to a private network with Tailscale (known issue: use
TAILSCALE_API_KEY, OIDC is not yet working with pre-clone scripts). - Install a credential helper required by the Git server.

The pre-setup script lets you work with orbs when you aren't ready to commit setup files to the repository. Amp agents and Puck can access the scripts and set them for you. Give Puck this prompt, or start a thread for the project with this prompt:

Amp will then inspect the repository and decide which work belongs before or after the clone. It will write and test the scripts, then save them in the project settings.
The scripts are also available on the project settings page, where you can review or edit them by hand.
-
- August 24, 2026
-
π IDA Plugin Updates IDA Plugin Updates on 2026-08-24 rss
IDA Plugin Updates on 2026-08-24
New Releases:
Activity:
- earthbreakers
- ida-nexus
- d2f4990f: Improve analysis lifecycle
- xrefgen
- ccc9afc9: Make installed IDA plugin find its core
- bb6081e5: Complete corpus ground-truth manifest
- 5ddb9120: Make IDA smoke tests runnable from wrappers
- d54c5f81: Add symbolic IDA corpus validation
- 1b34a973: Keep graph call resolution when skipping insights
- 8421eca0: Add reproducible multi-language corpus builder
- 4bf0c825: Make typed result roles authoritative
- f5bb252e: Add one-command IDA installer
- 3e4c981d: Gate full and incremental IDA equivalence
- b5b9cdfc: Harden IDA compatibility test mocks
- 3442a338: Add ARM64 negative corpus fixture
- 1e5aca0d: Use real trampoline and deterministic graph sources
- d36712d9: Add explicit analyzer result emitters
- 14484a4a: Complete release validation documentation
- d55a0618: Align effective analysis defaults
- 36112728: Add ground truth quality gates
- 7b706eb1: Make full analysis state deterministic
- 7e6b74fe: Preserve explicit analysis result semantics
- 10faf86d: Validate control flow at real callsites
- 4e4170fa: Align defaults and release configuration
-
π anthropics/claude-code v2.1.243 release
chore: Update CHANGELOG.md and feed.xml
-
π MetaBrainz Blocked ListenBrainz services/User Agent strings rss
Unfortunately some legitimate services got caught up in our recent attempts to mitigate (yet another) bot-net attack on ListenBrainz.
You may find that a service you use is now being blocked, including Navidrome. We have also had reports of multi- scrobbler submissions being blocked, and there may be other affected services that haven't yet been reported to us.
These services got caught up in recent blocks because they are/were not setting a proper user agent when calling the LB API.
Navidrome and multi-scrobbler are already pushing fixes!
If you are experiencing issues on another service, we would like to let you through, but without a user agent (UA) string we can't identify the service's traffic. Please ask your service to add a meaningful UA string (in a format like described in https://musicbrainz.org/doc/MusicBrainz_API/Rate_Limiting) so we can get you back up and running.
Implementing a good back off when they receive a 429 error will help avoid blocks too. For example, extending the waiting time between resubmissions, if the service repeatedly returns a 429. Note that some of the blocked services had this implemented already, but it can help.
Developers, you are always welcome to talk to us on the dev channel in ChatBrainz (Matrix/IRC/Discord) if you have any questions.
-
π r/LocalLLaMA Copilot you say? rss
| talking to any white collar employee submitted by /u/edge_compute_user
[link] [comments]
---|--- -
π smol-machines/smolvm smolvm v1.12.0 release
What's Changed
- Add an opt-in virtio-gpu scanout with a host-side VNC server and virtio-input so machines can run an interactive Linux desktop by @BinSquare in #1027
- Ship virtio-input-capable guest kernels and an input-enabled macOS libkrun by @BinSquare in #1043
- Harden forked workloads and add transactional embedded batch forking by @BinSquare in #1044
- Make large pack pushes reliable with upload-scoped timeouts and a chunked fallback by @BinSquare in #1045
- Rewrite a loopback proxy host to the host's outbound address so guests can reach it by @BinSquare in #1046
- Cut v1.12.0 with the display-capable libkrun and rebuilt platform libraries by @BinSquare in #1048
- Harden live fork execution for rollout sandboxes by @BinSquare in #1049
- Pack a machine created from a local image archive or rootfs directory by @BinSquare in #1047
- Pin the Vulkan driver on exec only when the container actually has the bundle by @BinSquare in #1052
- Bump the workspace crates to 1.12.0 so the library crates ship at the engine's version by @BinSquare in #1051
- Mount the bundled Vulkan driver into pod and overlay containers too by @BinSquare in #1053
- Boot a pod sandbox with a virtio-gpu device when the pod asks for one by @BinSquare in #1054
Full Changelog :
v1.11.1...v1.12.0 -
π MetaBrainz GSoC 2026: Playlists Sorting and Organization rss
Helloo Everyone!
My name is Yateen, a final year cse student at Indian Institute of Technology Jodhpur. My matrix username is (@yateen) and GitHub. I started open source at the beginning of this year. I was selected as a GSoC contributor and worked on the Playlists Sorting and Organization project. It was a wonderful experience working on a tech stack of React, Databases, APIs, Jest + Testing Library, etc. What was more amazing was to work under the mentorship of Ansh Goyal (Github), Monkey (Github) and Jade (Github) and be a part of the wonderful MetaBrainz team.Pre-selection Contributions
Before GSoC officially started, I contributed to ListenBrainz through several smaller PRs that helped me learn the codebase and review process. Firstly I started with exploring some small UI/UX issues such as preventing duplicate error toasts and fixing toast overlap with the YouTube player, accessibility improvements like adding aria-labels to icon-only playback buttons. Then I started solving tickets which are feature-oriented like including auto-save for settings, showing artist name relationships. This pre-selection period helped me get comfortable with ListenBrainz patterns and mentor feedback before taking on the larger GSoC features.
Project Overview
Over the summer I worked on the playlist features and improved the existing playlist structure. I shipped four related features that turn ListenBrainz playlists from a flat list into something you can search, tag, sort for listening, and import from MusicBrainz collections.
Feature 1 - Playlist Search
The first thing I tackled was search on the user playlists page. If you had a lot of playlists, finding one usually meant scrolling forever or jumping over to global search.
I started with a simple search bar wired to the existing user playlist search API: type at least three characters, hit search and get matching playlists back with pagination. But there was a problem with it especially once you mixed search with sorting and paging.
Ansh suggested to treat search like the rest of the playlists pag: put the query in the URL query parameters and load data through the route loader . The main issue now was the search results were automatically sorted before getting displayed with the existing sort option (Date Created, Date Modified, Title, etc.) which doesn't provide a good search experience. So I introduced a way for search results to default to βBest Match β while a search is active and later you can sort by date or title and get a consistent order across pages. I also added small but important pieces - loading state while rendering and empty messages when "No playlist found".
Feature 2-Tagging Playlists
Search helps when you remember a name. Tags help when you remember a use /category : gym, road trip, focus, whatever. ListenBrainz didnβt have real playlist tags yet. Playlists already had
additional_metadata, but we needed a proper structure to organize them with tags.On the backend , I added a
playlist_tagtable inadmin/timescale/create_tables.sql, with normalization (lowercase, trim whitespace, length limits). Each tag β€ 40 chars, you can add up to 25 tags per API call; a playlist can hold at most 50 tags overall, and only the playlist owner can add/remove. Collaborators can see tags but canβt edit them.Tags show up in playlist JSPF when we need them for the UI, and thereβs a sidebar endpoint that returns each tag with how many playlists use it, separately for owned vs collaborative playlists. Filtering supports multiple tags, and it works together with search.
Table
Table:
playlist.playlist_tagColumn| Type| Notes
---|---|---
id| SERIAL| Primary key
playlist_id| INT NOT NULL| FK to playlist.playlist(id), ON DELETE CASCADE
tag| TEXT NOT NULL| The tag string
created| TIMESTAMPTZ| Defaults to NOW()UNIQUE (playlist_id, tag)β same tag only once per playlistOn the frontend , you can add tags when creating or editing a playlist, see them on playlist cards and on the playlist page, and filter from a sidebar. Active tags filters are included in the URL (
?tag=β¦), so they combine cleanly with the search and sort features.Designing the UI for the tags sidebar was a bit challenging. I consulted with Aerozol, Ansh and Monkey and finally came up with a UI which reuses the existing components from Listenbrainz.
BEFORE :

Main playlist page without tags sorti ng
AFTER:

Playlists sorted by tags
Feature 3 - Sorting tracks inside a playlist
After search and tags, the next issue was browsing tracks inside a playlist. Tracks always showed in the saved order. That is fine for editing, but not always for listening. Sometimes you want AβZ, by artist, newest first, or shuffle, without changing the playlist forever.
So I built this only on the frontend. On the playlist page, there is a βSort by β menu next to Play all. Options are Default, Recently added, Title, Artist, and Shuffle. Default is the real saved order. Drag and drop works only in Default, while other sorts are temporary.
For Shuffle, if you add or remove a track, the list does not reshuffle again. Play all also uses the order you see on screen. This was a smaller feature than search or tags, but it made long playlists easier to use.

**Feature 4 - Importing Musicbrainz collections **
ListenBrainz already imported playlists from Spotify, Apple Music, and SoundCloud, but not from MB itself. The goal was to preview MusicBrainz collections in ListenBrainz and optionally save them as normal ListenBrainz playlists .
Recording collections first
We started with recording collections. Instead of calling the MusicBrainz web API, we read live from the MusicBrainz database using
MB_DATABASE_URI.On the backend:
GET /1/playlist/import/musicbrainz/collectionslists the logged-in userβs collections./collection/<mbid>/shows the collection page which follows the same SPA pattern as other ListenBrainz pages .GETreturns the HTML shell, andPOSTreturns the JSON data.- Public collections can be viewed by anyone. Private collections are only for the owner, checked with their MusicBrainz editor id.
On the frontend:
- A MusicBrainz option was added to the import modal. Clicking a collection opens a preview page where tracks load in pages of 100, with virtual scrolling for large collections. The page also supports cover art, Play all, and Save as playlist. Saving uses the existing playlist create API (
POST /1/playlist/create). - After mentor review, we improved the page to better match ListenBrainz patterns. The first page of data now loads through
RouteLoader, more tracks are fetched withuseInfiniteQueryinstead of a hand-written fetch loop.
Release Collections
Now on the preview page, a release collection does not show a flat list of tracks. It shows the releases themselves β title, artist, and cover art when available. Clicking a release opens the ListenBrainz release page at
/release/<mbid>/, so the user can explore that album in the normal ListenBrainz UI.Saving works a bit differently from recording collections. A release collection is not already a list of recordings, so the backend flattens each release into its tracklist. The frontend requests this with
?flatten=trackson the collection page. That query walks the MusicBrainz release β medium β track β recording path and returns normal recording rows. Those rows are then sent to the existing playlist create API, so the final result is a normal ListenBrainz playlist that you can play, edit, and manage like any other playlist.Testing
Writing tests was one of the biggest learning curves for me this summer. Before GSoC, I mostly checked features by hand and did not have a strong habit of adding tests. Working on ListenBrainz changed that. Mentors often asked for coverage of edge cases, auth rules, and validation paths, so writing tests became a normal part of finishing a feature.
For each feature I used a mix of both manual checks with automated tests:- Frontend tests in
Playlists.test.tsxfor playlist search. - Integration tests in
test_playlist_api.pyfor tags. - Frontend tests in
Playlist.test.tsxfor in-playlist sorting. - Integration tests in
test_musicbrainz_collections_import.pyfor MusicBrainz collections.
Overall GSoC Experience
GSoC with MetaBrainz was my first time working on a large open-source project with real users and a real review process. I learned a lot more than just writing features. Mentors pushed me to think about URL state, loaders, error codes, empty states, and tests β things I used to skip or only check by hand.
I would like to thank Ansh , Monkey , Jade for guiding me throughout the process . I learned professionalism from them and their dedication to their work motivates me to improve my own. I realized that handling such large organization with limited members requires high skills built on strong fundamentals and obviously a problem solving mindset is must . I would also like to thank Aerozol for helping me in UI related issues.
What feels most rewarding is knowing the work I shipped will remain in the project and will be used by users across the world.
My PR's around the GSoC period and Proposal can be found here - PRs
Post GSoC Plan
I plan to take a short break and then with fresh energy again start contributing to ListenBrainz and other MetaBrainz products. My next steps will likely include polishing the playlists further and solving other tickets so I stay active in the community (I love Monday meetings
). Long term, I
hope to keep growing as an open-source contributor and continue improving
ListenBrainz. -
π backnotprop/plannotator v0.27.8 release
Follow @plannotator on X for updates
Missed recent releases? Release | Highlights
---|---
v0.27.7 | Pi host crash fix on Windows, Call Flow tree cap, jj fork-point base, plannotator knowledge skill + llms.txt
v0.27.6 | Live app annotation lands on Pi, one interaction model for HTML pages (same-day patch on v0.27.5)
v0.27.5 | Annotate your running app, Agent TUI placement, collapsed lockfiles, VS Code theme fix, Pi fixes
v0.27.4 | Portable Guided Review exports, guides.show share links, guide CLI, favicon switcher, jj Call Flow
v0.27.3 | Folder watcher freeze fix on large repos, first SBOM-attested release pipeline
v0.27.2 | Mobile plan and code review, Codex CLI 0.147 fix, folder annotate cold-start, configurable markdown extensions
v0.27.1 | Open-in-editor launch fix, file headers respect Viewed/Git-add visibility toggles
v0.27.0 | Call Flow analysis, --tailscale remote reviews, review panel remembers your view, Pi rebuild (breaking command rename), focus-mode shortcut
v0.26.8 | Placed comment markers on HTML pages, shift-click multi-select, live app annotation
v0.26.7 | Pinpoint targets any element on HTML pages, smarter hover labels, zero-scan hit testing
v0.26.6 | Fixed empty environment variables in sandboxed sessions (Bun 1.3.14 builds)
v0.26.5 | HTML pinpoint element annotations, durable annotate submissions, installer fallback for old git, vim HUD cursor fixWhat's New in v0.27.8
A patch release with two quality-of-life fixes: Pi sessions stop losing their prompt cache when a plan finishes, and the thumbs-up returns to HTML annotation in a restrained form. Both came from user reports filed within the last week.
Pi keeps your prompt cache when a plan finishes
Finishing plan execution on Pi used to invalidate the LLM provider's prompt cache. Plannotator injects its plan instructions as conversation messages, and when the plan ended it deleted them from the middle of the chat history. Providers cache conversations front to back, so everything after the deleted message was re-billed at full uncached rates on the next turn. In the reporting user's session that meant re-paying for roughly 90 messages.
Plannotator no longer rewrites history. Old plan instructions stay where they are, and a note at the end of the conversation tells the model the plan is over and earlier instructions no longer apply. The phase instructions now state explicitly that they supersede anything Plannotator said before, so stale planning rules cannot keep steering the model. A regression test verifies each outgoing request extends the previous one byte for byte across the full planning, executing, and idle lifecycle.
Thanks @WinPooh32 for the report, and especially for attaching the exact before/after request payloads. They turned diagnosis into a five minute job.
- #1381 by @backnotprop, closing #1380 reported by @WinPooh32
The thumbs-up is back on HTML pages
v0.27.5 made HTML and live-app annotation comment-only: delete and label tools were markdown concepts that never fit arbitrary pages. That ruling had a side effect we did not intend to keep: there was no longer any one-click way to say "this part is good." Approving something meant opening the comment composer and typing it out.
Exactly one label affordance returns: the π "Looks good" button. Select text and it is in the toolbar; pinpoint-click an element and it is a one-click action in the comment composer (disabled once you start typing, so it can never discard a draft). Everything else about comment-only holds: no delete, no label picker, no label keyboard shortcuts, and the security clamp that stops a hostile page from forcing annotations through the bridge is untouched.
0ae40e73by @backnotprop, from a developer report
Additional Changes
- Embed picker seam for
@plannotator/uihosts: the/embedslash-menu picker (target list, empty states, kind-aware upload adapter, paragraph splice) is now a host-configurable extension in the published UI package, shipped to npm as@plannotator/ui@0.31.0with@plannotator/core@0.24.0. Plannotator's own apps are unaffected. #1382 by @backnotprop
Install / Update
macOS / Linux:
curl -fsSL https://plannotator.ai/install.sh | bashWindows:
irm https://plannotator.ai/install.ps1 | iexClaude Code Plugin: Run
/pluginin Claude Code, find plannotator , and click "Update now".Pi: Update
@plannotator/pi-extensionto 0.27.8 and restart Pi.OpenCode: Clear cache and restart:
rm -rf ~/.bun/install/cache/@plannotatorWhat's Changed
- fix(pi): append-only phase framing so plan transitions keep the prompt cache by @backnotprop in #1381
- feat(ui): add embed media picker seam by @backnotprop in #1382
- feat(annotate): restore a restricted thumbs-up on comment-only HTML surfaces by @backnotprop in
0ae40e73
Community
- @WinPooh32 reported the Pi cache invalidation in #1380 with the request payloads that made the diagnosis immediate
- The thumbs-up gap was reported directly by a developer using HTML annotation for report review
Full Changelog :
v0.27.7...v0.27.8 -
π r/LocalLLaMA Qwen 3.8 27B in 9th position on code arena. Gemma 4 31B is 80th. rss
submitted by /u/tarruda
[link] [comments] -
π r/LocalLLaMA Apple M5 Server rss
| Credit to Twitter Post submitted by /u/Rymssss
[link] [comments]
---|--- -
π r/LocalLLaMA I irradiated LLMs and found that they die really quickly rss
| I randomly bit flipped a llm to simulate what would happen if you ran your spark in low earth orbit i hope it's ok to share this here, I was told this community might enjoy it. submitted by /u/BenniJesus
[link] [comments]
---|--- -
π earendil-works/pi v0.84.3 release
New Features
- PowerShell tool β Use optional native PowerShell command execution on Windows. See PowerShell Tool.
- Safer managed updates β Stage, verify, and atomically activate updates for installer-managed installations. See Install and Manage.
- Model and thinking controls β Select thinking levels with
/thinking, search defaults, keep selections session-scoped, and persist them explicitly with Ctrl+S. See Models and Thinking.
Breaking Changes
- Renamed the inherited
GoogleThinkingLeveltype toGoogleApiThinkingLeveland addedResolvedGoogleThinkingLevelfor normalized adapter levels.
Added
- Added an optional
powershelltool for Windows, configurable throughdefaultToolsand the SDK. See PowerShell Tool. - Added a
/thinkingselector and searchable default choices to the model and thinking selectors; Ctrl+S saves the selected model as the global default. See Models and Thinking. - Added optional routing session IDs to exported compaction summary helpers so callers can preserve provider routing without enabling prompt cache writes.
- Added transcript usage notices for compaction and branch summaries when cache miss notices are enabled.
- Added
session_compact_failedextension events so compaction failures and aborts expose their reason, retry state, source, and error message to handlers (#8175). - Added inherited provider-neutral
toolChoicesupport to simple stream requests. - Added inherited automatic Anthropic server-side refusal fallback for supported first-party models, including returned-model usage pricing (#8017).
- Added inherited configurable OpenAI-compatible thinking-token budget fields for vLLM, Qwen/SGLang, and llama.cpp servers. See OpenAI Compatibility (#8275 by @bnsd55).
- Added inherited China-specific ZAI Coding Plan models, including GLM-4.6V vision support and API-equivalent usage cost estimates (#8220).
- Added inherited
deepseek-v4-pro-0813support to the Qwen Token Plan Individual catalog (#8194).
Changed
- Changed experimental installer-managed installations so
pi updatestages, verifies, and atomically activates the selected release in place. See Install and Manage. - Changed inherited built-in xAI models to use the Responses API with encrypted reasoning replay and made Grok 4.6 the default xAI model (#8124 by @Jaaneek).
- Changed inherited Anthropic, Azure OpenAI, Google, Mistral, and OpenAI adapters to send Pi's default
User-Agentunless overridden (#8305). - Changed Windows and WSL keybinding defaults to avoid terminal-reserved shortcuts for image paste, model cycling, editor undo, fullscreen transcript navigation and search, and message queueing (#8372).
- Changed Bun release archives to ship the native clipboard binary only inside the wrapper package, removing a duplicate platform package from each archive.
- Changed package resource glob expansion to use Node.js's built-in implementation with deterministic visible-path matching, reducing the installed runtime dependency tree.
- Changed the bundled Node.js runtime to load jiti only when importing an extension and Babel only when uncached source needs transformation, reducing CLI startup time and bundle size.
- Changed syntax highlighting to initialize only twenty common languages eagerly and defer the remaining grammars until after the initial TUI render, reducing CLI startup time.
- Changed the Node.js CLI and RPC entrypoints to load a bundled runtime, reducing startup filesystem reads while keeping the public library and legacy module paths on the modular runtime for normal dependency identity.
- Changed session sharing to render clickable terminal links, display only the canonical Radius artifact URL, and include the current system prompt and active tool definitions in Radius session shares.
Fixed
- Fixed failed extension factories leaving event subscriptions, provider registrations, and default flag state active (#8424 by @acmerfight).
- Fixed
models.jsontypings omitting the documented OpenAI-compatiblecompat.supportsFinishReasonprovider and model override (#8487 by @petrroll). - Fixed
/modeland/thinkingselections being persisted globally unless explicitly saved with Ctrl+S (#5263). - Fixed JSON and RPC
toolcall_startevents omitting the tool call id and name (#7953 by @christianklotz). - Fixed extensions failing to load when the Node.js CLI runs as a single-executable application (#8237).
- Fixed nested Markdown skills inside
.agents/skills/grouping directories not being discovered. - Fixed compaction and branch summarization requests exposing tools to providers.
- Fixed single-object
edittool inputs failing validation by accepting them as one-edit arrays in both coding-agent and harness edit tools (#7835). - Fixed root Markdown files such as
README.mdandAGENTS.mdin skill directories being reported as broken skills unless they declare valid skill frontmatter (#7805). - Fixed the default Cerebras model referencing an unavailable Z.AI model.
- Fixed inherited OpenAI-compatible Chat Completions reasoning replay to preserve and resend assistant-level
reasoning_detailsverbatim and in order (#7994). - Fixed inherited Anthropic server-side fallback responses being priced with the requested model instead of the returned fallback model (#8285).
- Fixed inherited GitHub Copilot login triggering model-policy rate limits by limiting policy updates, retrying model discovery once, and honoring server retry delays (#7850).
- Fixed inherited Amazon Bedrock dropping and failing to replay opaque redacted reasoning from non-Anthropic models (#8314 by @seiji).
- Fixed inherited Z.AI Coding Plan models deriving incomplete reasoning-effort metadata, including missing GLM-5.3 low, high, and max levels (#8336).
- Fixed inherited DeepSeek V4 Flash on OpenCode and OpenCode Go omitting its supported low thinking level (#8181 by @tianshuang).
- Fixed inherited Azure OpenAI Responses ignoring
toolChoicein provider-specific stream requests. - Fixed inherited Amazon Bedrock response hooks receiving only a synthesized request id instead of the raw response headers (#8234).
- Fixed inherited Kimi usage reporting so top-level
cached_tokenscount as cache reads instead of normal input tokens (#8075). - Fixed inherited Google custom models ignoring
thinkingLevelMap, which dropped extended thinking controls (#8135). - Fixed writes to
auth.jsonandmodels-store.jsonoverriding administrator-managed file permissions and ACLs (#7779). - Fixed UTF-8 BOM markers preventing frontmatter and user configuration files from loading (#8337).
- Fixed invalid settings files being easy to miss during interactive startup by rendering warnings with the file path inside the TUI (#7829).
- Fixed the subagent example repeatedly prompting before running project-local agents in trusted repositories (#8261).
- Fixed npm package update checks treating older registry versions as available updates, preventing
pi updatefrom downgrading already-newer installed packages (#8226). - Fixed built-in llama.cpp models disappearing from
/modelwhen/llamarefreshed a configured server underPI_OFFLINE, and included idle-sleptsleepingrouter models in the selectable catalog (#8167). - Fixed
pi.registerFlag()accepting default values that do not match the declared flag type (#8064). - Fixed Z.AI Coding Plan defaults referencing the removed GLM-5.1 model (#8096).
- Fixed repeated ambiguous truncated-response recovery being mislabeled as context overflow (#8130).
- Fixed duplicate fullscreen right-click paste in VS Code-based terminals on Windows (#8186).
- Fixed inherited padded text exceeding narrow terminal widths (#8252).
- Fixed inherited wrapped Markdown table links leaking color into borders and neighboring cells, including tables inside blockquotes (#8335).
- Fixed llama.cpp login guidance to direct users to
/llamabefore/modelwhen no local models are loaded (#8203). - Fixed hung pi.dev model catalog requests consuming the entire refresh deadline without retrying (#8198).
- Fixed inherited Xiaomi model catalogs listing shut-down MiMo V2 models in
/modeland--list-models(#8187). - Fixed branch summary entries recording the navigation destination in
fromIdinstead of the pre-navigation source leaf. - Fixed threshold auto-compaction being skipped when providers omit streaming usage data (#8328).
- Fixed dash-prefixed prompts being parsed as options by supporting
--as an end-of-options delimiter (#7269).
-
π r/LocalLLaMA Xiaomi AI Cube announced with 1.2TB/s memory bandwidth rss
| Xiaomi announced a prototype for their Xiaomi AI Cube. 3 chip system:
- Xiaomi Xuanjie O3
- Xiaomi Xuanjie O100
- Xiaomi Xuanjie D100 The specs are impressive, but a bit confusing. The D100 chip (originally for their EVs) supports up to 160GB of RAM, but O100 has the 1.22TB/s memory bandwidth. Perhaps the 1.22TB/s figure is for SRAM? Hard to say definitively. Source: https://www.ithome.com/0/993/546.htm submitted by /u/Mysterious_Finish543
[link] [comments]
---|--- -
π HexRaysSA/plugin-repository commits sync repo: +1 plugin, +1 release rss
sync repo: +1 plugin, +1 release ## New plugins - [ida-func-call-rank](https://github.com/uky007/ida-func-call-rank) (0.1.1) -
π smol-machines/smolvm smolvm v1.11.1 release
What's Changed
- Carry a machine's remote volumes on serve API execs so a bucket is present for API-driven sessions by @BinSquare in #1039
- Remove a previous install's bundled agent rootfs so an upgrade cannot keep booting the old agent by @BinSquare in #1040
- Bind a machine's overlay and remote volumes to one call so launch and exec sites cannot set one without the other by @BinSquare in #1041
- Bump the workspace to 1.11.1 by @BinSquare in #1042
Full Changelog :
v1.11.0...v1.11.1 -
π MetaBrainz GSoC 2026: Compose Multiplatform Migration of ListenBrainz-Android rss
Hi everyone,
I'm Nirvan Jain (nirvan_jain on IRC, nirvan73 on GitHub), Iβm currently a pre-final year student at IIIT Jabalpur. This summer I was offered this opportunity to work with MetaBrainz through Google Summer of Code on migrating the ListenBrainz android app to Kotlin Multiplatform and Compose Multiplatform, so that most of the same codebase can eventually run on iOS under the mentorship of Jasjeet Singh (jasje on IRC).
This post covers what the project was, everything I worked on, the parts that went wrong, what's still left, and what the summer was actually like.
How I got here
I started contributing to ListenBrainz in December 2025. It was the first external open source project I'd worked on. Everything before that was coursework, side projects, or intra-college events.
My first PRs were small work which helped me a lot to understand the codebase from the ground, the shimmer effect across the Feed and Profile tabs, then extending search to cover playlists, artists, albums and tracks, plus some bug fixes. Small changes, but they taught me the codebase and how review works when nobody knows you and the code has to stand on its own.
I picked ListenBrainz because music is a constant in my day, whether I'm coding or not, and because I like that it treats your listening history as something you own.
The Problem
ListenBrainz has an Android app but no iOS version. A previous Swift attempt just duplicated the codebase, so every bug fix had to be written twice.
This project solves that by migrating to Kotlin Multiplatform, one shared codebase for both platforms. A large part of the work is replacing Android- only libraries with multiplatform equivalents across navigation, dependency injection and paging. Media playback is the harder case. ExoPlayer and WorkManager are tied too closely to Android to share, so both go behind common interfaces, with ExoPlayer on Android and AVPlayer on iOS underneath.
Getting this foundation right is what makes the rest cheap. Once it's in place a feature or a bug fix is written once, instead of the same business logic being implemented twice and two apps being kept in sync by hand.
One thing genuinely can't move. The notification listener that reads what's playing in Spotify depends on an Android-only permission, and iOS has no equivalent to offer. Those screens stay Android-only. Everything else runs from one codebase on both platforms.
Project overview
ListenBrainz is a platform for tracking your listening history, sharing what you're into, and building a community around music. The Android app is its mobile face, and this project was about rebuilding its foundations so that face isn't Android-only forever.
The main goals were:
- Shared logging with Kermit - Replacing the Android-only logger, with file writing and log submission split across platform implementations (#742)
- Realtime events in the shared module - Moving off the Android-only socket.io-client so listen and playing_now work from commonMain on both platforms (#731)
- ViewModels, repositories and the BrainzPlayer & ListensSubmission database into shared - Roughly twenty separate migrations, on top of the KMP lifecycle dependencies (#743 and #744 through #765)
- A shared work manager - with listen submission and its data models and utilities moved into the shared module (#767)
- Permissions in shared - with configuration for both Android and iOS (#770)
- Screen migration - Starting with onboarding, which is where I am now
Each of these gets its own section below, with what broke, what review caught, and where I diverged from the original proposal.
Community bonding
I spent bonding mostly auditing rather than coding. The shared module scaffold and the DataStore work already existed, so the useful question wasn't how to start but what exactly was still Android-only and what would replace each thing.
That meant going through the dependency list one by one. The logger, socket.io, WorkManager, ExoPlayer, Accompanist, Lottie, the shimmer library, the WebView clients, the paging setup. For each one: is there a KMP-compatible replacement, does it need an interface with two implementations, or can it simply not exist on iOS and therefore has to stay Android-only forever?
I also discussed with my maintainer and agreed on a migration order during this period. We settled on logging and sockets first, then ViewModels, then services and background work, then UI, so that each layer already had its dependencies migrated by the time it needed them.
Coding Period
Shared Logging: replacing the Android logger with
Where it started
The app used
com.limurse.logger(Logger-Android) behind a thinLoginterface:// app/util/Log.kt β before interface Log { fun e(message: Any?, tag: String? = null) fun d(message: Any?) fun w(message: Any?) companion object : Log { override fun e(message: Any?, tag: String?) = Logger.e(tag, msg = message.toString()) override fun d(message: Any?) = Logger.d(msg = message.toString()) override fun w(message: Any?) = Logger.w(msg = message.toString()) } }Two problems. It's a JVM library, so it can't cross into
commonMain. And becauseLogis acompanion objectcalled statically from many files, every single one of those files had a hard, untestable dependency on Android. This one had been started by another contributor PR - #728 before I picked it up, the Kermit swap and a first pass at file logging existed.What I did was take it apart and rebuild the layering, because the first version had every platform's DI wiring duplicated and the file writer had almost all of its logic sitting in
androidMaineven though most of it was plain Kotlin.The interface stays, the backend changes
The first decision was to keep the
Loginterface and its companion. It's called from everywhere, changing the call sites would have made the diff unreadable and the review impossible. SoLogmoved toshared/util/Log.kt, kept its shape, gainedi/v/logand athrowableparameter, and started delegating to a KermitLoggerpulled out of Koin.interface Log { fun e(message: Any?, tag: String? = null, throwable: Throwable? = null) fun d(message: Any?, tag: String? = null) // w, i, v, log ... companion object : Log, KoinComponent { private val logger: Logger = get() override fun e( message: Any?, tag: String?, throwable: Throwable? ) { logger.withTag(tag ?: "ListenBrainz").e(throwable) { message.toString() } } // ... } }KoinComponent on the companion is what makes a static-looking API injectable. The object stays a singleton, but what it is now decided by DI, per platform.
Splitting the file writer
The old file writer was one Android class doing five things: formatting timestamps, collecting device metadata, serialising writes, formatting log lines, and actually touching the filesystem. Only the last one is platform- specific.
So
SharedFileLogWriteris an abstract class incommonMainthat extends Kermit's LogWriter and does everything except the write. Click to see the implementationabstract class SharedFileLogWriter(private val buildConfig: BuildInfo): LogWriter() { private val loggerQueue = Channel<String>(capacity = Channel.UNLIMITED) protected fun initBlock() { loggerScope.launch(Dispatchers.IO) { for (entry in loggerQueue) writeLineToFile(entry) } } override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) { val level = when (severity) { /* Verbose -> "VERBOSE", ... */ } writeToFile(message, tag, level) throwable?.let { writeToFile(it.stackTraceToString(), tag, level) } } protected abstract suspend fun writeLineToFile(entry: String) }The
Channelis the interesting bit. Logging happens on whatever thread the caller is on, and file I/O has to be serialised or you get interleaved half- lines. An unlimited channel consumed by a singleDispatchers.IOcoroutine gives you a non-blocking log() call and a strictly-ordered writer, with no locks.As for the iOS implementation, I haven't added it in this PR yet. I wanted to get the base shared setup merged first so the rest of the PRs isn't blocked on moving logger-dependent files into the shared module. Once every file involving logger in their code is migrated over, Iβll follow up with the actual iOS file writer in a separate PR.
I made one
BuildInfo, a plain data class which consists of -> application id, version code, version name, build type, bound in DI by the app. SincecommonMaincannot seeBuildConfig, so anything that wants build metadata takes aBuildInfoinstead.Log submission
"Submit logs" means:- zip everything in the log directory. I have created an interface named
LogSubmitter, a contract in common which only have one method as:-interface LogSubmitter { suspend fun submitLogs() }AndroidLogSubmitteris one of the extension ofLogSubmitterin androidMain which zips the.txtfiles, exposes the archive through FileProvider, and fires anACTION_SENDchooser. Two review-driven fixes landed here: -- Passed the
PlatformContextasapplicationContextthrough the parameters of the class - Handled thread switching explicitly, file compression runs on
Dispatchers.IO, while building and launching the chooser intent switches back towithContext(Dispatchers.Main)
The iOS side (
IosLogSubmitter,IosFileLogWriter) is not implemented yet and will be added in a follow-up.The DI shape, and what review changed
My first version had a
SharedAppModule.android.ktand aSharedAppModule.ios.ktfor all the platform specific modules, each defining a full Koin module. Review corrected this:- it means every new binding has to be added twice, and the two modules drift. The fix was to have one module incommonMainunderplatformModuleand make only the factoriesexpect/actuallike provideLogger. Click to see the example of the same// commonMain/Platform.kt expect fun provideLogger(buildInfo: BuildInfo): Logger expect fun provideLogSubmitter(buildInfo: BuildInfo): LogSubmitter // commonMain/di/SharedAppModule.kt val platformModule = module { single<Logger> { provideLogger(get<BuildInfo>()) } single<LogSubmitter> { provideLogSubmitter(get<BuildInfo>()) } // ... } // androidMain/Platform.android.kt actual fun provideLogger(buildInfo: BuildInfo): Logger { val writers = mutableListOf(platformLogWriter()) applicationContext.getExternalFilesDir(null)?.let { dir -> val logDir = File(dir, ANDROID_LOG_DIR_NAME).apply { mkdirs() } writers.add(AndroidFileLogWriter(logDir.path, buildInfo)) } return Logger( StaticConfig( minSeverity = Severity.Debug, logWriterList = writers ), tag = "ListenBrainz" ) } // iosMain/Platform.ios.kt actual fun provideLogger(buildInfo: BuildInfo): Logger { val writers = mutableListOf(platformLogWriter()) (NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, true ).firstOrNull() as? String)?.let { writers.add(IosFileLogWriter(it, buildInfo)) } return Logger( StaticConfig( minSeverity = Severity.Debug, logWriterList = writers ), tag = "ListenBrainz" ) }Same module, same binding, one line of difference per platform. This became the template for every other platform-backed dependency in the project -RemotePlaybackHandler, PermissionHandler, ListensRepository, the Room builder.
Platform.ktis now the single file where you can read off everything the shared module needs a platform to supply.Realtime Events in the Shared Module
"Listening Now" is fed by a Socket.IO connection to
listenbrainz.orgthat pushes two events,listenandplaying_now. The existing implementation usedio.socket:socket.io-client, which is JVM-only and pulls in org.json:// before β app module private val socket: Socket = IO.socket( "https://listenbrainz.org/", IO.Options.builder().setPath("/socket.io/").build() ) socket.on("playing_now") { json.decodeFromString<Listen>(it[0] as String) }Attempt one: Engine.IO by hand
Ktor's websocket client is multiplatform, so my first instinct was to drop the Socket.IO library entirely and talk the protocol directly. Socket.IO over websockets is really Engine.IO framing:
My first implementation did it the hard way. I wrote the
Engine.ioandSocket.ioprotocol handling by handβ¦. on top of ktor-client-websockets.- manual handshake with the 40 frame to open the session
- heartbeat by answering every incoming 2 with a 3
- and event subscription parsing JSON payloads out of the frames myself.
Click to see the implementation
// the version that worked, and that I threw away :( httpClient.webSocket("wss://listenbrainz.org/socket.io/?EIO=4&transport=websocket") { send(Frame.Text("40")) send(Frame.Text("""42["json",{"user": "$username"}]""")) for (frame in incoming) { val data = (frame as? Frame.Text)?.readText() ?: continue when { data == "2" -> send(Frame.Text("3")) // heartbeat data.startsWith("42") -> { val array = json.parseToJsonElement(data.removePrefix("42")) as JsonArray when (array[0].jsonPrimitive.content) { "playing_now", "listen" -> trySendBlocking( json.decodeFromString<Listen>(array[1].jsonPrimitive.content) ) } } } } }It connected. It received listens. It was also, on reflection a bad idea, reimplementing a wire protocol inside an application repository means the app now owns a protocol implementation it has to maintain and debug and keep in sync with a spec it doesn't control. Thats why I have to switch to using a KMP SocketIO - OSS library.
Attempt two:
I switched to
com.piasy:kmp-socketio, which is a real Socket.IO client for KMP and crucially lets you hand it your own KtorHttpClient, so realtime traffic goes through the same configured, logged, engine-agnostic client as everything else. Click to see the implementationclass SocketRepositoryImpl( private val httpClient: HttpClient, private val json: Json, private val logger: Log = Log, ) : SocketRepository { override fun listen(usernameProvider: suspend () -> String) = callbackFlow { val username = usernameProvider() val options = IO.Options().apply { httpClient = this@SocketRepositoryImpl.httpClient transports = listOf("websocket") } var activeSocket: Socket? = null IO.socket("https://listenbrainz.org", options) { socket -> activeSocket = socket socket.on(Socket.EVENT_CONNECT) { socket.emit("json", buildJsonObject { put("user", username) }) } listOf("playing_now", "listen").forEach { event -> socket.on(event) { data -> runCatching { val payload = data.firstOrNull()?.toString() ?: return@on trySendBlocking(json.decodeFromString<Listen>(payload)) }.onFailure { logger.e("SocketRepository: $event error ${it.message}") } } } socket.open() } awaitClose { activeSocket?.close() } } }The
callbackFlow+awaitCloseshape survived the rewrite unchanged, which is the nice thing about having had a decent boundary in the first place,SocketRepository.listen()returns aFlow<Listen?>, and neither the ViewModel nor the UI ever knew which library was underneath.KMP Lifecycle, ViewModels and Repositories
This is where most of the raw hours went and it's the least interesting part to write about, which is exactly why it's worth writing about. This is the bulk of the project by volume: ~20 PRs, one feature each.
The dependency swap that unlocks everything
AndroidX lifecycle ships two artifact families:
lifecycle-viewmodel-ktx(Android-only) andlifecycle-viewmodel(multiplatform since 2.8). They have the same API. Switching the whole project to the base artifacts is a three- line diff in the version catalog and is the entire technical prerequisite for shared ViewModels.The KMP lifecycle dependencies had to land first so migrated ViewModels had a ViewModel base and a viewModelScope that exist on both platforms. Then, one at a time: Settings, Artist, Album, Song, Playlist ,etc ViewModels, the remote playback handler, the BrainzPlayer database, and SocialRepository.
One PR each, about twenty of them.
After migrating the viewmodels, repositories and network services to shared module, they needed to be wired up through Koin. I organized these dependencies into dedicated shared modules so the platform
appmodule could easily consume them without caring about their internal package structure:SharedViewModelModule-> Registers all shared ViewModels.SharedRepositoryModule-> Binds the shared repository layer.SharedNetworkServiceModule-> Configures shared API clients and network services.SharedAppModule-> Handles core utility implementations (like RemotePlaybackHandler).
Retrofit to Ktorfit, OkHttp to engine-agnostic
Services became Ktorfit interfaces, which look almost identical:
interface ListensService { @GET("user/{user_name}/listens") suspend fun getUserListens( @Path("user_name") username: String, @Query("count") count: Int, @Query("max_ts") maxTs: Long? = null, ): Listens @POST("submit-listens") suspend fun submitListen(@Body body: ListenSubmitBody?): PostResponse }I created an
expect funof the engine with its platform-specificactual funimplementation. Click to preview// commonMain expect fun getPlatformNetworkEngine(): HttpClientEngineFactory<*> expect fun configPlatformEngine(config: HttpClientEngineConfig, context: PlatformContext) // androidMain β OkHttp, plus Chucker in debug builds actual fun getPlatformNetworkEngine(): HttpClientEngineFactory<*> = OkHttp actual fun configPlatformEngine(config: HttpClientEngineConfig, context: PlatformContext) { if (config is OkHttpConfig && BuildKonfig.DEBUG) { config.addInterceptor(ChuckerInterceptor(context)) } } // iosMain β Darwin actual fun getPlatformNetworkEngine(): HttpClientEngineFactory<*> = DarwinThe awkward cases
Not everything I migrated went cleanly. Those are the parts I found interesting, so I'm giving them the most space here.
String resources in ViewModels
Several ViewModels emit user-facing success messages by resource id, and
commonMainhas noR. I could have movedres/, but that's a much larger change than I wanted to make inside a feature PR, so I wrote small provider interfaces keyed by enum instead:// shared/util enum class StringResource { TRACK_ADDED_SUCCESSFULLY, PLAYLIST_DUPLICATED_SUCCESSFULLY, /* ... */ } interface StringProvider { fun getString(res: StringResource): Int }The app implements it as a one-line when mapping enum to
R.string.*, and I bound it in Koin. I wrote three of these:StringProvider,DrawableProvider,ArrayProvider. I made them deliberately boring. They let me migrate a feature today and let someone migrate the resources later, on their own schedule.Repositories that really are platform-specific
ListensRepositoryneedsgetPackageLabel(pkgName), which turnscom.spotify.musicinto "Spotify". That's aPackageManagercall with no iOS analogue.Rather than leak it into common, I kept the interface common and picked the implementation with an expect fun, so I ended up with an
AndroidListensRepositoryImpland anIosListensRepositoryImplsharing a common parent. I did the same thing for RemotePlaybackHandler, which is Spotify App Remote on Android and a stub I wrote on iOS.The BrainzPlayer database
My proposal listed the local databases as a migration target, and i did the work. Room Multiplatform, schema in
commonMain, builder behindexpect. The PR consists the moving of four entities, four DAOs,TypeConverterandTransformeracross, and deleting the app-side database and converter files outright.The boundary turned out narrower then I expected, Only the builder is platform-specific. The driver, the migration list and
build()all stay in common DI, so the part I'd most hate to see diverge across platforms is written exactly once.// commonMain - the entire platform surface of the database expect fun getBrainzPlayerDatabase(context: PlatformContext): RoomDatabase.Builder<BrainzPlayerDatabase> single<BrainzPlayerDatabase> { getBrainzPlayerDatabase(get()) .setDriver(BundledSQLiteDriver()) .addMigration(Migrations.MIGRATION_1_2,Migrations.MIGRATION_2_3) .build() }Android supplies a
ContextandgetDatabasePath().absolutePath. iOS supplies a path fromNSFileManager. One line of diff , each platform.BundledSQLiteDriver()in common means both platforms ship the same SQLite built. This is the same "one module incommon, only the factories areexpect/actual", temp late I settled on during the logging migration, and it held up on a much heavier target.Room's KMP mode also made me do something I'd never done on Android, The database object needs a generated constructor. Click to preview
@Database(entities = [SongEntity::class, AlbumEntity::class, ArtistEntity::class, PlaylistEntity::class], version = 3) @TypeConverters(TypeConverter::class) @ConstructedBy(BrainzPlayerDatabaseConstructor::class) abstract class BrainzPlayerDatabase : RoomDatabase() { /* ... */ } @Suppress("KotlinNoActualForExpect") expect object BrainzPlayerDatabaseConstructor : RoomDatabaseConstructor<BrainzPlayerDatabase>That
@Suppressisn't style. KSP generates theactual, but the Kotlin compiler goes looking for it before KSP has run.A drawable resource living in a database column
The interesting problem in this PR was
PlaylistEntity.art. It was an@DrawableRes Int, andcommonMainhas noR:// shared β no idea what a drawable is val art: String = "ic_queue_music" // app fun getPlaylistArtMapper(art: String): Int = when (art) { ... }That's the same resource-indirection trick as my
StringProviderandDrawableProvider, but with two costs those don't carry. The column is persisted, so changing its type forced a schema migration. And it's stringly- typed, so the compiler stops checking my work. Both costs came due. The migration showed up in review, the lost type safety showed up right after.SQLite can't
ALTER COLUMN, soMIGRATION_2_3rebuilds the table. The part I actually thought about is that it back-fills the new keys from the row ids rather than defaulting every playlist to the generic icon, and then repairssqlite_sequencesoAUTOINCREMENTdoesn't restart into ids that still exist.
Click to see the SQLite codeINSERT INTO `PLAYLISTS_TEMP` (`id`,`title`,`items`,`art`) SELECT `id`, `title`, `items`, CASE WHEN `id` = -1 THEN 'ic_queue_music_playing' WHEN `id` = 0 THEN 'ic_liked' ELSE 'ic_queue_music' END FROM `PLAYLISTS`Where my plan changed
Two weeks after this merged, the plan changed underneath it, Since the local music player used ExoPlayer, an android specific component and was tightly coupled to UI components and viewModels that shouldn't have been concerned with, complicating our migration to CMP.
So my migration turned into a deletion. including the database I had just finished moving. That meant the app also had to clean up after itself for users upgrading from a version that had it:
private fun cleanupBrainzPlayerResources() { context.getDatabasePath("brainzplayer_database") .takeIf { it.exists() } ?.let { context.deleteDatabase("brainzplayer_database") } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { (getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager) ?.deleteNotificationChannel("Music") } }Shared work manager
This was the one of the trickiest part of my project and the PR for the same is under review and not merged yet , because listen submission is the one piece of the app that is inherently Android (it works by listening to other apps' media notifications) and yet almost none of its logic actually is.
Here's the pipeline I ended up with:
ListenSubmissionService (app, NotificationListenerService β Android-only entry point) ListenSessionListener (shared/androidMain - MediaSessionManager callbacks) ListenServiceManagerImpl (shared/androidMain β whitelist) ListenSubmissionState (shared/androidMain β timers, builds PlayingTrack, schedules work) ListenSubmissionWorker (shared/androidMain β KMP worker: POST, or persist for retry)I left only the first box in
:app, and only becauseNotificationListenerServicehas to be declared in the app manifest. I moved everything downstream of it.From androidx.work to KmpWorkManager
For background work I replaced Android's WorkManager with KmpWorkManager, updated ListenSubmissionWorker to match, and removed the native WorkManager DI wiring. This is one of the places where i diverged from my proposal, which described hand-rolling a
BackgroundTaskSchedulerinterface withWorkManageron Android andBGTaskScheduleron iOS. Using an existing KMP library meant less code to write and less to maintain for the same result.I annotate my workers and let KSP discover them:
@Worker("ListenSubmissionWorker") class ListenSubmissionWorker : AndroidWorker, KoinComponent { private val appPreferences: AppPreferences by inject() private val repository: ListensRepository by inject() private val pendingListensDao: PendingListensDao by inject() override suspend fun doWork(input: String?, env: WorkerEnvironment): WorkerResult { /* ... */ } }I schedule by string name and JSON payload, because a KMP scheduler can't take a
Class<*>or an androidxData:scheduler.enqueue( id = "listen-${playingTrack.id}-${System.currentTimeMillis()}", trigger = TaskTrigger.OneTime(initialDelayMs = 0), workerClassName = "ListenSubmissionWorker", inputJson = Json.encodeToString(ListenWorkerInput(playingTrack, ListenType.SINGLE)), constraints = Constraints(requiresNetwork = true), )so my input model is just:
@Serializable data class ListenWorkerInput( val track: PlayingTrack, val listenType: ListenType )plus an explicit
KmpWorkManager.initialize(context, AndroidWorkerFactoryGenerated())alongside startKoin initialising KMP WorkManager.Then
ListenSubmissionStatemoved into the shared module under androidMain, rewired to use the shared notification manager and shared work manager, with the data models and utility functions it depends on coming across with it.ListenSubmissionServicein the app module was updated to consume the shared utilities and services, and the Koin registry updated accordingly.Permissions in the shared module
The PR for the same is under review and not merged yet. Last year's contributor built a
PermissionEnumthat put all permission logic in one place: title, rationale, permanently-declined copy, image,minSdk,maxSdk, and the raw permission string. I think it's a genuinely good design, and it made the onboarding screens trivial to write. It's also, top to bottom, Android:enum class PermissionEnum( val permission: String, // "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" val image: Int, // R.drawable.* val minSdk: Int, // Build.VERSION_CODES val maxSdk: Int? = null, )Every field except the copy is Android-specific. I couldn't make a single shared enum work, and I didn't want to duplicate the whole thing per platform.
Splitting the enum without losing the enum
What I settled on was making the contract an interface, and letting each platform contribute its own enum implementing it. Click to see the implementation
// commonMain interface AppPermission { val id: String val title: String val permanentlyDeclinedRationale: String val rationaleText: String val image: DrawableResource // enum, not an Int } // commonMain β permissions that exist everywhere enum class SharedPermissionEnum(..) : AppPermission { SEND_NOTIFICATIONS( id = "send_notification", title = "Send Notifications", rationaleText = "Needed to send updates on activity, recommendations, and system alertsβ¦", image = DrawableResource.IC_NOTIFICATION, ) } // androidMain β permissions that only exist here enum class AndroidPermissionEnum( ..., val systemPermission: String, val minSdk: Int, val maxSdk: Int? = null ) : AppPermission { READ_NOTIFICATIONS(systemPermission = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE", minSdk = 33, ..), BATTERY_OPTIMIZATION(systemPermission = "android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS", minSdk = 23, ..), }I made
imageaDrawableResourceenum resolved by theDrawableProvider, so my shared code can name an icon without knowing what anR.drawableis. That left me one problem.SEND_NOTIFICATIONSlives in common but still needs an Android manifest string and aminSdkon Android.
I solved it with an extension inandroidMainthat supplies the Android facts for shared constantsThe handler
I moved everything behavioural behind one interface:
interface PermissionHandler { fun getAllRelevantPermissions(): List<AppPermission> fun getPermissionsForPermissionScreen(): List<AppPermission> fun isPermissionApplicable(permission: AppPermission): Boolean suspend fun isGranted(permission: AppPermission): Boolean fun storageKey(permission: AppPermission): String suspend fun requestPermission( permission: AppPermission, activity: Any? = null, permissionRequestedOnce: List<String> = emptyList(), dangerousPermissionLauncher: (permission: String) -> Unit = {}, ): Boolean? }activity: Any?is the one compromise in my whole design, and I want to be upfront about it.commonMaincannot nameActivity, and Android's rationale APIs (shouldShowRequestPermissionRationale) genuinely require one. So my Android implementation casts (activity as? Activity) and degrades gracefully to aFLAG_ACTIVITY_NEW_TASKintent when it's null.I kept all of last year's special cases in the Android implementation, including the two "permissions" that aren't runtime permissions at all.
My iOS handler is much smaller, and that's the point. It only has to answer for the permissions iOS actually has, which is just
SEND_NOTIFICATIONSsince iOS sandbox security and privacy rules don't allow the other permissions anyway.One detail which is
storageKey(). Whether a permission has been requested once is persisted in DataStore, and the obvious key is the enum constant's name, which means renaming a constant would silently reset everyone's onboarding state. On Android I use the system permission string instead, which is stable by definition. On iOS I use the explicitidfield, and that's the only reason I putidon the interface at all.Screen migration: onboarding
I'm currently working through the UI layer starting with onboarding.
Onboarding is a reasonable place to start for two reasons. It's the first thing a user sees, so regressions are visible immediately and get caught fast.
The back half is different. Listen submission setup and the third-party app selector both depend on NotificationListenerService, so by the same reasoning as above those screens stay Android-only and won't exist in an iOS build. The shared onboarding graph walks both platforms through the first three screens, Android then hands off to its own two, and iOS ends the flow there.
A side quest: token login
While working on the auth screens, I added a direct-token login path alongside the existing WebView flow. Due to ongoing server-side auth migrations, we needed a more direct and temp, resilient fallback while keeping the door open for multiplatform support. Click to see the implementation
fun submitToken(onLoginFinished: () -> Unit) { val token = uiState.value.token.trim() if (token.isBlank()) return setError("Token cannot be empty") if (uiState.value.loginState is TempLoginState.VerifyingToken) return viewModelScope.launch { val result = withContext(ioDispatcher) { listensRepository.validateToken(token) } val validation = result.data if (result.isSuccess && validation?.valid == true) { appPreferences.username.set(validation.username ?: "") appPreferences.lbAccessToken.set(token) onLoginFinished() } else { setError(validation?.message ?: "Invalid token. Please check and try again.") } } }What's left
I'd rather say this plainly than bury it. My proposal was ambitious and several sections of it are still open:
- iOS file logging and log submission are
TODO(). The shared machinery (queueing, formatting, startup metadata, theLogSubmittercontract) is all done and platform-neutral, the two iOS leaves are stubs. - System bar control away from
accompanist-systemuicontroller. - Browser and external URL handling via
expect/actual. - Lottie to Compottie.
- Shimmer to a KMP shimmer implementation.
- Onboarding screen migration and all other composable screens migration to CMP, started but not complete.
- Testing migration to Kotlin Test with shared tests in commonTest
Two reasons for the gap. The foundational work, logging, sockets, ViewModels, notification and work manager, permissions, took considerably longer than I estimated, largely because each piece went through multiple review rounds that improved it but slowed it down. And the OAuth login change arrived mid-project and cost time I hadn't planned for.
Post-GSoC plan
I 'm not going anywhere. The unfinished list above is my roadmap, roughly in this order.
-
The UI dependency cluster:- WebView, system bars, browser handling, Lottie, shimmer. These are individually small and mostly independent, so they can be done steadily instead of needing a large block of time.
-
Then finishing the screen migration, continuing from onboarding through the home navigation shell, settings, dashboard and feed.
-
Then the testing migration, moving platform-independent tests into commonTest so the shared module has an actual safety net. This one matters most for whoever picks the project up after me. A migration without tests is a liability handed to the next person.
-
And eventually the real OAuth login flow, replacing the temporary token-paste screen with something users shouldn't have to put up with.
Outside the migration I still want to build the playlist sorting feature from my proposal, and keep fixing bugs.
What I learned
The clever solution was usually the wrong one. My instinct on the socket migration was to build the impressive thing, hand-rolled protocol handling and all. The right answer was the boring maintainable one, and I now read the urge to be clever as a sign I haven't thought hard enough about who maintains this in two years.
Almost everything I actually learned came out of review. Thread safety, DI hygiene, why println doesn't belong in production code. Having changes requested three times on one PR taught me more than any PR that merged first try, though getting comfortable with that, treating requested changes as information rather than as a verdict, took a few weeks.
Final Thoughts
I am truly grateful for this amazing opportunity and thanks Jasjeet for his constant guidance and reviewing an enormous amount of my code carefully and for pushing back every time I was overcomplicating something. A fair amount of this post is his review comments with more words around them.
More than anything, this project showed me the gap between code that works and code that lasts. I learned to think in terms of clean contracts, edge cases, and long-term maintainability rather than quick fixes. It gave me real confidence in navigating complex codebases, embracing tough reviews, and contributing to industry-scale projects with purpose.
And Finally, thanks to the MetaBrainz community for their support. This was my first serious open source project and it's a welcoming place to have started. I'll be around well past this summer.
-
π smol-machines/smolvm smolvm v1.11.0 release
What's Changed
- Carry remote volumes on the embedded machine spec so SDK machines can mount buckets by @BinSquare in #1034
- Mount remote volumes for runs without a persistent overlay so ephemeral runs see their bucket by @BinSquare in #1036
- Carry a machine's remote volumes on every exec so the bucket is present whichever container serves the session by @BinSquare in #1037
- Bump the workspace to 1.11.0 by @BinSquare in #1038
Full Changelog :
v1.10.1...v1.11.0 -
π Armin Ronacher Anger, Anxiety and Agency rss
Sean Goedecke wrote a post arguing that you should never be angry at work β a post with which I strongly agree. Anger can be a useful signal, but being angry at work rarely improves the situation. More often, it makes life worse for the people around you, many of whom have no more power over the source of your anger than you do. I did learn that lesson, but it did not come naturally. One thing in particular that I learned is that in a company there is a shared vision, and if you don't agree with it and are not in a position to change it, you should not start a mutiny, not even a small-scale one. Nothing good comes from that.
In the discussion around that topic, one of the most upvoted comments on the Lobsters thread asked a question I had to think about quite a bit:
How can you work in tech right now and not be angry?
In the context of the thread, this was clearly also about AI and agents. For me, the emotions I would expect in tech vis-a-vis these new developments are disorientation and anxiety, but not anger.
Anxiety as an emotion does not require someone to blame. Right now, I find it reasonable to feel anxious about an uncertain future. Who knows what our professions will turn into and what kind of world my kids will find themselves in when they enter the workplace? And if you've been in the industry for a long time, will the skills you've spent years acquiring still matter?
But anger is different from anxiety because anger needs to be directed somewhere. The feeling of anger suggests that somebody or something is doing something to you.
Who are you going to be angry at and why are you angry in the first place? One narrative that is pretty pervasive is that if AI will usher in productivity gains, those gains are going to benefit companies rather than employees. And well at least someone at Meta wants that. Yet I also find that plenty of people in leadership positions express doubt about AI. They see that an increasing share of their costs is being funneled directly to some large AI labs. They express worries about what will happen to their data and whether these large companies will step into their space instead of being partners.
My answer to the question of how you can not be angry in tech is that it's by no way the most only possible feeling. First of all, instead of being angry, you can simply be unsure. The feeling of uncertainty is a much more productive emotional state because it can lead to curiosity. Even if you don't find what's happening right now exciting, you can at least find it interesting. We have access to magic machines, and we can poke at them and see what happens. The second way is to feel genuine excitement. Once you move beyond curiosity, you can come away with a newfound feeling of power and freedom. A lot of the gains from AI aren't turning into productivity gains that are reflected in company profits but they're showing up instead in the number of side projects shipped by everybody not on their company's time.
The fact that this is happening shows us that owners and founders don't necessarily know what will happen. Ownership comes with agency, but it does not provide foresight, and this change is disorienting for everybody. I engage with plenty of people who project confidence in public and are much less certain in private. Many of them are placing bets, but they are talking with confidence about those bets, trying to keep their business afloat while the ground moves under them. They experience that uncertainty from a position where they can act on it, and they are often standing somewhere with a megaphone to get others on their side to improve their odds.
I feel that contradiction myself: I am simultaneously tremendously excited, but I am also unsure what will happen next. I do not know what it will mean to be a programmer in the future, and, as the owner of a company, I am also not sure where the high ground will be when this all settles. Much of what I learned over the years is changing rapidly, including ideas I considered fundamental to my craft and business. Some days that feels liberating, but on others I wake up feeling like the ground is crumbling beneath me.
Anxiety is an uncomfortable emotion because it acknowledges that you do not know what will happen and might not be able to stop it. On the other hand, anger can feel more actionable because, instead of saying "I don't know," you already have someone to blame. It turns a loss of control into a comforting story with a villain. But I feel that particularly when it comes to AI, it's easy to pick the wrong villain because of how disruptive the change is for everyone. Your engineering manager or leadership team might themselves feel uncertain about their future and just try to bolster their own confidence by projecting clarity and certainty.
That does not mean there are no villains. When this all plays out, some will profit and many will not. I'm afraid we're completely ignoring the impact this has on society at large, the climate, and the balance of the world as a whole. As excited as I am about the technology, I worry about Europe's lack of ambition and growing dependence on other countries. I have a lot of complex thoughts about what we're doing as an industry right now.
I don't know what the future of this industry will look like, and I don't know who will benefit from it and I don't think I'm alone with that. However I can only urge anyone who feels anger and looks for a villain right to instead remain curious instead. To be curious enough to understand what is changing, excited enough to experiment with it. And then, from what we learn, earn the right to decide when resistance is warranted and where to direct it.
-