🏡


to read (pdf)

  1. I don't want your PRs anymore
  2. JitterDropper | OALABS Research
  3. DomainTools Investigations | DPRK Malware Modularity: Diversity and Functional Specialization
  4. EXHIB: A Benchmark for Realistic and Diverse Evaluation of Function Similarity in the Wild
  5. Neobrutalism components - Start making neobrutalism layouts today

  1. June 12, 2026
    1. 🔗 syncthing/syncthing v2.1.2-rc.1 release

      Major changes in 2.1

      • Devices and folders can now be grouped in the GUI by setting the new
        group attribute.

      • HTTP and HTTPS proxies with support for CONNECT can now be used, in
        addition to the existing support for SOCKS proxies (the environment
        variable all_proxy=https://...).

      • Block indexing can be turned off for folders where it's more desirable to
        optimise for reduced database size and overhead than minimal transfer
        size (the blockIndexing attribute on folder configuration).

      • GUI login session duration can be configured to be longer or shorter than
        the default one week, or set to infinitely long. The cookie path can also
        be adjusted. (The sessionCookieDurationS and sessionCookiePath
        attributes in the GUI configuration.)

      This release is also available as:

      • APT repository: https://apt.syncthing.net/

      • Docker image: docker.io/syncthing/syncthing:2.1.2-rc.1 or ghcr.io/syncthing/syncthing:2.1.2-rc.1
        ({docker,ghcr}.io/syncthing/syncthing:2 to follow just the major version)

      What's Changed

      Fixes

      • fix: on Windows don't allocate console if not opened inside one by @Shablone in #10726
      • fix(connections): do not report connection metrics for self (ref #10509) by @calmh in #10724
      • fix: let umask do the thing by @calmh in #10723
      • fix(fs, model): improve symlink resilience in file shortcut by @calmh in #10739
      • fix(protocol): always expect & validate block hash in requests by @calmh in #10738
      • fix(protocol): be more stringent about blocks in non-file entries by @calmh in #10737

      Other

      • chore(syncthing): open URLs via Windows API instead via cmd.exe by @Shablone in #10712
      • chore(db, model): separate methods to drop a device vs its files by @imsodin in #10480
      • build(deps): update dependencies by @calmh in #10740

      New Contributors

      Full Changelog : v2.1.1...v2.1.2-rc.1

    2. 🔗 anthropics/claude-code v2.1.175 release

      What's changed

      • Added enforceAvailableModels managed setting — when enabled, the availableModels allowlist also constrains the Default model (a Default that would resolve to a disallowed model now falls back to the first allowed model), and user or project settings can no longer widen a managed availableModels list
    3. 🔗 anthropics/claude-code v2.1.174 release

      What's changed

      • Added wheelScrollAccelerationEnabled setting to disable mouse-wheel scroll acceleration in fullscreen mode
      • Fixed the /model picker hiding the model family that Default resolves to — Opus now appears as its own row on Max/Team Premium/Enterprise plans, Sonnet on Pro/Team plans, and Opus on pay-as-you-go API accounts
      • Fixed /model picker showing a hardcoded Sonnet version label when ANTHROPIC_DEFAULT_SONNET_MODEL pins a different Sonnet
      • Fixed the "Fable 5 is now consuming usage credits" banner incorrectly showing for enterprise accounts with usage-based billing
      • Fixed Bedrock GovCloud regions (us-gov-*) deriving the wrong inference profile prefix (global instead of us-gov), causing 400 errors on derived model IDs
      • Fixed background sessions inheriting another session's ANTHROPIC_* provider env (gateway URL, custom headers, /model aliases) from the shell that started the background daemon
      • Fixed a 1-2 second pause when exiting Claude Code shortly after a shell command was interrupted or killed on macOS and Linux
      • Fixed git commit co-author attribution showing an incorrect model name for some models
      • Fixed the /advisor dialog pre-selecting a saved advisor model that is blocked by the availableModels allowlist
      • Fixed skill hot-reload re-sending the entire skill listing when a single skill changed; only changed skills are now re-announced
      • Fixed Workflow tool agent() subagents missing per-agent attribution headers
      • [VSCode] Added usage attribution to the Account & usage dialog (/usage) showing cache misses, long context, subagents, and per-skill/agent/plugin/MCP breakdowns over the last 24h or 7d
      • Fixed pre-warmed background workers failing with "Could not resolve authentication method" when claimed after sitting idle
  2. June 11, 2026
    1. 🔗 Simon Willison Claude Fable is relentlessly proactive rss

      After two days of experience with Claude Fable 5 I think the best way to describe it is relentlessly proactive. It knows a whole lot of tricks and it will deploy pretty much any of them to get to its goal.

      I'll illustrate this with an example. I was hacking on Datasette Agent today when I noticed a glitch: a horizontal scrollbar that shouldn't be there in the jump menu chat prompt. I snapped this screenshot:

      Screenshot of a modal dialog demonstrating a scrollbar bug. At the top is a focused search input with blue outline and placeholder "Jump to...", with an X close button to its right. Below, a heading reads "Start a new agent chat" above a textarea with the placeholder "Ask a question about your data..." — the bug: a thick gray horizontal scrollbar is incorrectly displayed along the bottom edge of the empty textarea, spanning nearly its full width, next to the resize handle. Below the textarea: "Press Enter to start. Shift+Enter adds a new line." followed by a blue "Start chat" button.

      Then I started a fresh claude session in my datasette-agent checkout, dragged in the screenshot and told it:

      Look at dependencies to help figure out why there is a horizontal scrollbar here

      I had a hunch the cause was in a dependency of Datasette Agent (likely Datasette itself) and I knew Fable was good at digging into dependency code, either by inspecting installed files in its own virtual environment site-packages or by referencing a local checkout on disk. Telling it to start with dependencies felt like a good bet.

      I got distracted by a domestic task and wandered away from my computer.

      When I came back a few minutes later I saw my machine open a browser window in my regular Firefox and then navigate to the dialog in question. I had not told Claude Code to use any browser automation, and I was pretty sure it wasn't possible for it to trigger mouse movements or keyboard shortcuts within a window, so how was it doing that?

      I watched in fascination as it continued with its explorations, then saw it open a Safari window instead of Firefox. I also grabbed this snapshot from the Claude terminal:

      Screenshot of two Bash tool calls in a dark terminal interface. First: Bash(open -a Safari /tmp/textarea-scrollbar-test.html && sleep 4 && uv run --with pyobjc-framework-Quartz python - <<'EOF' import Quartz wins = Quartz.CGWindowListCopyWindowInfo(Quartz.kCGWindowListOptionOnScreenOnly, Quartz.kCGNullWindowID) for w in wins: if (w.get('kCGWindowOwnerName') or '') == 'Safari' and 'textarea' in (w.get('kCGWindowName') or '').lower(): print(w.get('kCGWindowNumber')) EOF) with output 153551. Second: Bash(screencapture -x -o -l 153551 /tmp/safari-cases.png && echo ok) with output ok.

      What was it doing there with uv run --with pyobjc-framework-Quartz?

      It turns out Fable had hacked up its own pattern for taking screenshots of browser windows. It was using Python to iterate through all available windows on my machine, then filtering for Safari windows with expected strings such as "textarea" in the window name. It used that to find their window number - an integer like 153551 - which it could then use with the screencapture CLI tool to grab a PNG.

      OK fine, that's a neat way of taking screenshots. But what was it taking screenshots of?

      Turns out it had been writing its own scratch HTML pages to try and recreate the bug, then opening Safari and grabbing screenshots.

      Here's that /tmp/textarea-scrollbar-test.html page it created, and the screenshot it took with screencapture -x -o -l 153551 /tmp/safari-cases.png:

      Screenshot of a Safari browser window showing a textarea scrollbar test page at file:///private/tmp/textarea-scrollbar-test.html. Page text reads: scrollbar thickness: 17px | UA: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.4 Safari/605.1.15 | devicePixelRatio: 2. Four numbered test cases follow, each with a textarea containing the placeholder "Ask a question about your data...": 1. Exact plugin CSS (resize: vertical, default overflow), 2. Plugin CSS + overflow-x: hidden, 3. Plugin CSS + resize: none, and 4. Bare default textarea, which is a much smaller box with the placeholder wrapping onto two lines. (I have way too many open tabs!)

      OK, so I can see how it's opening test pages and taking screenshots, but how on earth was it triggering the modal dialog that was meant to be under test? That's only available via a click or a keyboard shortcut, and I couldn't see a mechanism for it to run those in Safari.

      I eventually figured out what it had done.

      Claude was running in a folder that contained the source code for the application. It knows enough about Datasette to be able to run a local development server. It turns out it was editing Datasette's own templates to add JavaScript that would trigger the correct keyboard shortcut as soon as the window opened, adding code like this:

      <script>
      window.addEventListener("load", function () {
        setTimeout(function () {
          document.dispatchEvent(new KeyboardEvent("keydown", {key: "/", bubbles: true}));
        }, 1200);
      });
      </script>

      1.2 seconds after the window opens, this code triggers a simulated / key, which is the keyboard shortcut for opening the modal dialog.

      There was one challenge left. In order to understand what was going on, Claude needed to run JavaScript on the page to take measurements for itself.

      It wrote its own custom web application to capture information via CORS, then ran that as a local server and opened a page with JavaScript that would POST directly to it!

      Here's the Python web app it wrote, using the standard library http.server package:

      from http.server import HTTPServer, BaseHTTPRequestHandler
      
      class H(BaseHTTPRequestHandler):
          def do_POST(self):
              n = int(self.headers.get("Content-Length", 0))
              open("/tmp/diag.json", "w").write(self.rfile.read(n).decode())
              self.send_response(200)
              self.send_header("Access-Control-Allow-Origin", "*")
              self.end_headers()
          def do_OPTIONS(self):
              self.send_response(200)
              self.send_header("Access-Control-Allow-Origin", "*")
              self.send_header("Access-Control-Allow-Headers", "*")
              self.end_headers()
          def log_message(self, *a):  # quiet
              pass
      
      HTTPServer(("127.0.0.1", 9999), H).serve_forever()

      All this does is accept a POST request full of JSON and write that to the /tmp/diag.json file. It sends Access-Control-Allow-Origin: * headers (including from OPTIONS requests) so that code running on another domain can still communicate back to it.

      Then Claude injected this code into the template that it was loading in a browser:

      const host = document.querySelector("navigation-search");
      const ta   = host.shadowRoot.querySelector("textarea");
      const cs   = getComputedStyle(ta);
      fetch("http://127.0.0.1:9999/diag", {
        method: "POST",
        body: JSON.stringify({
          dpr: window.devicePixelRatio,
          scrollWidth: ta.scrollWidth, clientWidth: ta.clientWidth,
          whiteSpace: cs.whiteSpace, width: cs.width,
        }),
      });

      This took measurements of the <textarea> inside the <navigation-search> Web Component and sent them to the server, which wrote them to a file on disk, which Claude could then read.

      Having figured out all of these tricks Fable... hit some invisible guardrail and downgraded itself to Opus. Thankfully Opus had access to the full transcript and could continue using the tricks pioneered by Fable, and shortly afterwards found, tested and verified the fix.

      I prompted Opus to:

      Write a report in /tmp/automation-report.md where you note down all of the tricks you have used in this session to test against real browsers on my computer, include runnable code examples

      Which produced this report, which was invaluable for piecing together the details of what had happened for this post.

      I've shared the full terminal transcript of the Claude Code session as well.

      A review of everything it did

      Based on a screenshot and a one-line prompt, Claude Fable 5 + Claude Code:

      • Figured out the recipe to run the local development server (with fake environment variables needed to get it running)
      • Fired up a Playwright Chrome session
      • Turned on the visible scrollbars setting for Chrome defaults write com.google.chrome.for.testing AppleShowScrollBars Always (it turned that off again later)
      • Cycled through Firefox and WebKit in Playwright too, failing to recreate the bug
      • Worked out my default browser was Safari
      • Built a textarea-scrollbar-test.html HTML document
      • Opened that in real (not Playwright) Firefox
      • Found that osascript -e 'tell application "System Events" to tell process "firefox" to id of window 1' was blocked because "osascript is not allowed assistive access"
      • Figured out that uv run --with pyobjc-framework-Quartz python workaround, described above
      • Added JavaScript to the site templates in order to trigger the / key
      • Built its own little Python CORS web server to capture JSON data
      • Rewrote the template to capture that data and send it to the server
      • Scripted its way through the Web Component shadow DOM to the information it needed
      • Opened Safari to confirm the source of the bug
      • Modified its custom template to hack in a potential fix
      • Confirmed the hacked fix worked
      • Reported back on how to fix the problem

      Like I said, relentlessly proactive!

      An estimate of the cost

      I'm currently on the $100/month Claude Max plan, which includes a generous allowance for Fable up until June 22nd after which Anthropic say they'll start charging full API prices for it.

      I'm using AgentsView to track my spending (see this TIL). Here's what AgentsView says this session would have cost me if I was paying full price for it:

      ~ % uvx agentsview session usage be8850a7-6119-46a0-b5d6-79c7fff5ae2b
      Session:       be8850a7-6119-46a0-b5d6-79c7fff5ae2b
      Agent:         claude
      Output:        68606
      Peak ctx:      113178
      Cost:          ~$12.11 (claude-fable-5, claude-opus-4-8)
      

      If you don't keep a close eye on it, Fable will quite happily burn $12 in tokens inventing new ways to debug your CSS.

      I really need to lock this thing down

      On the one hand, watching Fable go to extreme lengths to get the information that it needed to debug what was, in the end, a two-line CSS fix, was fascinating.

      But on the other hand... this is a robust reminder that coding agents can do anything you can do by typing commands into a terminal - and frontier models know every trick in the book, and evidently a few that nobody has ever written down before.

      If Fable had been acting on malicious instructions - a prompt injection attack hidden in code or an issue thread, or something I'd carelessly pasted into my terminal - it's alarming to think quite how far it could go to exfiltrate data or cause other forms of mischief.

      Running coding agents outside of a sandbox has always been a bad idea - it's my top contendor for a Challenger disaster incident, as described by Johann Rehberger in The Normalization of Deviance in AI.

      Fable is arguably smarter and hence more suspicious of potentially malicious instructions. But that smartness is very much a two-edged sword: if it does get subverted by instructions, the amount of damage it can do given its relentless proactivity is terrifying.

      You are only seeing the long-form articles from my blog. Subscribe to /atom/everything/ to get all of my posts, or take a look at my other subscription options.

    2. 🔗 r/reverseengineering Reverse engineered BLE protocol of a $7 generic Chinese smart ring from Temu, and built an iOS app around it rss
    3. 🔗 The Pragmatic Engineer The Pulse: a trend of trying to cut back on AI spend within eng departments? rss

      Hi, this is Gergely with a bonus, free issue of the Pragmatic Engineer Newsletter. In every issue, I cover Big Tech and startups through the lens of senior engineers and engineering leaders. Today, we cover one out of four topics from The Pulse issue from two weeks ago. Full subscribers received the article below fourteen days ago. If you 've been forwarded this email, you can subscribe here .

      The below The Pulse is interesting, as a week after the original was sent it out, OpenAI CEO Sam Altman also said how AI budgeting is a huge issue for some companies - echoing findings from this analysis.


      In mid-May, Uber president, Andrew McDonald, was on the Rapid Response podcast for a conversation about the ridesharing giant with host Bob Safian, who raised the lack of hoped-for efficiency leverage from AI, citing the language learning app, Duolingo.

      "When you hear companies talking about 25% of code commits over the last quarter were AI-driven, or how their token usage went from X to Y percentage of employees: all these numbers are amazing. I think it's a massive transformation of society", McDonald said.

      "But, then you go and you talk to your senior engineering leaders, and you're asking: "how many projects that were "on the cutting room floor" got moved above the line [of being done] because of the productivity gains? Because 25% of our code commits were via Claude Code last quarter."

      That link [of improved productivity thanks to AI] is not there yet. I mean, maybe implicitly there's more that is getting shipped, but it's very hard to draw a line between one of those stats and more useful consumer features.

      Over the coming quarters and years, maybe that will become clearer. But today it's hard, even if some of the underlying metrics are trending in a really astronomical direction.

      Our CTO, Praveen, went viral because he said in an interview that we had blown through our AI budget for 2026 and it was the middle of March. We're going to have to start talking about token consumption and the associated cost versus headcount, and making tradesoffs on that as an engineering organization.

      If you 're not able to draw a direct line to [how many] useful features and functionality you're shipping to your users, that tradeoff [on AI spend] becomes harder to justify because AI is not free.

      If you're just a user [of AI tools] sitting there and coming up with interesting use cases, and you don't pay the bill, it can feel [like AI is free]. But somebody's paying the bill".

      My hunch is that pretty much every company is starting to, or will do soon, ask questions about the massive growth in AI spend; starting with AI coding tools. I talked with a few folks at larger and smaller companies about it:

      • OpenCode: customer demand for optimizing spend is spiking. Yesterday, on the podcast episode with OpenCode creator, Dax Raad, he said demand for OpenCode's hosted inference service (OpenCode Zen) surpassed all expectations because larger companies want cheaper, but still capable, AI models. He revealed that over the past month, every single inbound enterprise request was about optimizing spend. So, there's some widespread concern about AI bills.
      • Companies with cutting-edge AI bite the bullet with model routing. I talked with a CTO and a Head of Engineering at two cutting-edge tech companies. They also do not have an obvious return on investment (ROI) as yet. Still, they feel they have no choice but to pay the "intelligence premium" for state-of-the-art models or increase the number of bugs shipped. To reduce costs, both are considering "smart" model routing based on use case and prompt. These places pay top-of-market for the best engineers, so similarly, there are expectations of access to the best tools and models.
      • DoorDash: More knowledge-sharing sessions and responsibility for devs. The leading food delivery company gives responsibility for spending to devs: everyone has a high monthly token usage limit. To exceed it, you need to justify why, and also share the plan for being more efficient next month. Many regular in-house knowledge-sharing sessions are about efficient AI use.
      • Traditional company: monthly limits and dumb-model downgrades. One month ago, one of the largest retirement-savings companies in the US updated its AI usage policy for all devs, a current engineer told me, imposing a monthly GitHub Copilot token limit. Once gone, devs must use the less capable "0x" models on Copilot, which are not charged extra: GPT‑5 mini, GPT‑4.1, and Grok Code Fast 1.
      • Startups: signing up for multiple Claude / Codex Max subscriptions. I talked with several smaller startups that are generating meaningful revenue, and don't want to pay expensive API prices. So, they've made it a practice for devs to get subsidized Claude Code Max or Codex Max subscriptions.

      There 's a new bottom-up focus on AI efficiency. Most tech companies do a variety of internal knowledge-sharing things like regular team demos, lunch- and-learn sessions, and engineering all-hands. I've been noticing more AI efficiency-focused sessions in the past couple of months, coming from engineers: no top-down mandate!

      Engineering all-hands, CTOs, and even CEOs have started to raise concerns about increasing AI token costs, and now more engineers are experimenting with cheaper models for simpler tasks, model routing, more efficient token usage, etc.

      I'd expect that during the next performance review and promotion cycles, engineers who helped save on token costs might be rewarded, like two years ago, when engineering teams were rewarded for saving on third-party vendor bills.

      For an engineer, the best way to show impact in your work is to translate it to money: revenue generated, or costs saved. With AI spending as high as (or higher than) on observability, it should be straightforward to show massive savings with smart optimizations. There's a touch of irony in how any savings - for which there might be promotions and pay rises - will come from the places that actually did the rocketing spending.


      Read the full issue in the previous The Pulse. Or check out this week's The Pulse: Did Anthropic's new model just boost rival Codex's market share?

    4. 🔗 The Pragmatic Engineer The Pulse: Antigravity 2.0 takes ‘IDE’ out of its new IDE rss

      Hi, this is Gergely with a bonus, free issue of the Pragmatic Engineer Newsletter. In every issue, I cover Big Tech and startups through the lens of senior engineers and engineering leaders. Today, we cover one out of four topics from The Pulse issue from 21 May 2026. Full subscribers received the article below three weeks days ago. If you 've been forwarded this email, you can subscribe here .

      Yesterday, Google launched a full redesign of its flagship AI IDE, Antigravity 2.0. The "original" Antigravity came out in November 2025, as pretty much a clone of Windsurf, the IDE whose team Google acquired for $2.4B last July.

      Google has turned Antigravity into two distinct applications, "Antigravity IDE" (its former incarnation) and "Antigravity 2.0". This new version itself resembles a clone of Codex's desktop app. When you install Antigravity 2.0, there are two different applications. From Google's launch post:

      "If you already have installed the Antigravity IDE, when that application next updates, it will automatically update to Antigravity 2.0. At this point, you will be asked if you would like to still keep the Antigravity IDE, which is recommended for developers:

      alt

      My sense is that the team at Google may have struggled to decide whether to keep supporting "original" Antigravity while investing in the Codex-like experience, and so kept both. Whatever the reasoning, it has created confusing naming, and it feels to me like the team's true focus is 2.0.

      altBig change: Antigravity 2.0 throws out the IDE and adds a conversational interface

      The upgrade feels rushed, sloppy, and poorly thought out. I had Antigravity on my machine, and installed Antigravity 2.0 separately. I wanted to use them side-by-side, but when I tapped "Restart to update" on Antigravity 1.0, it upgraded itself to Antigravity 2.0 (the non-IDE version). Suddenly, I had two applications with different names, but neither is an IDE:

      altTesting times: Two apps but no IDE version on my machine, due to lack of testing

      Google has introduced an "Agent Manager" concept that feels unintuitive, and perhaps suitably, its creator struggles to explain it (emphasis mine:)

      "When we launched the Google Antigravity IDE in November 2025, there was no agent-first GUI surface in the market. We wanted to prove that such a surface worked, at least for software development. So, while the core of the Antigravity IDE was a familiar agent-powered IDE, we introduced the Agent Manager, a second surface that stripped away much of the "IDE" UI. This allowed users to focus on the agent conversations themselves, the artifacts the agents produced, and multi-agent management.

      Even without this separation, we have been pleasantly surprised how many people have adopted the Agent Manager in the Antigravity IDE for such non- development tasks, but it is not particularly intuitive ".

      The "Agent Manager" is basically a way to launch several agents, and the most intuitive interfaces for doing so are inside Claude and Codex desktop apps and Claude CoWork. Antigravity 2.0 copies them by starting new agent tasks on the right hand of the UI, and keeping track of them.

      Google looks indecisive about what to do with the IDE part of Antigravity. The release announcement suggests they'll keep on confusing users (emphasis mine:)

      "Although Antigravity 2.0 is the future, we won't disrupt your workflows right away. For now, both the Antigravity IDE application itself and the Agent Manager in the Antigravity IDE will remain available. In an upcoming release, we will remove the Agent Manager from the Antigravity IDE, turning the IDE into a purely agent-powered IDE. "

      Basically, the Antigravity IDE (not "the future" in Google's vision) will become more limited over time. It's unclear what a "purely" agent-powered IDE will be once agentic functionality is removed, especially as Antigravity IDE is not the future, as per Google.

      Not only that, but the announcement also encourages devs to use Antigravity 2.0 with other IDEs! From the launch post (emphasis mine):

      "We recommend dual-wielding Antigravity 2.0 with your IDE of choice, whether it is the Antigravity IDE or otherwise. Googlers have already been dual wielding Antigravity 2.0 with a whole host of IDEs! We will have compatible extensions and plugins into other popular IDEs shortly".

      To me, this suggests Google will retire Antigravity IDE and recommend VS Code, JetBrains, Cursor, or Zed, with Antigravity. Then again, why would Cursor or Zed support Antigravity? The messaging is extremely confusing: Google's still the king of opacity.

      Feedback on Antigravity 2.0 has been negative due to bugs, poor UX and model support, more bugs, and eating up Gemini token quotas rapidly. Antigravity does not support state-of-the-art Anthropic or OpenAI models (no Opus 4.7 or GPT 5.5). Not supporting OpenAI's models like this is sensible as they're competitors, but Google is an investor in Anthropic, so not supporting Opus 4.7 (while supporting the legacy 4.6 model) is a bit odd.

      altModels which Antigravity 2.0 supports

      Gemini 3.5 Flash is Google's cutting-edge model, but it gets lots of complaints from devs for editing files without asking, and seems like an inefficient model. Another common complaint is that Antigravity uses up the $100/month Ultra subscription daily quota in minutes. Basically, it seems like a poor-quality product that wasn't polished due to lack of time or inclination.

      In context, it's embarrassing for there to be a "Codex" folder in the launch video if it suggests that Google's own Antigravity devs are using Codex for day-to-day work. It also suggests that the launch video was not reviewed properly, otherwise this obvious detail would presumably have been caught and fixed:

      altCodex folder in Documents suggests Antigravity devs are users of it. Source: Antigravity 2.0 launch video

      To upset devs even more, Google is replacing its open source Gemini CLI with the closed source Antigravity CLI. There are a few issues with this move:

      • Antigravity CLI does not support Google's own Agent Client Protocol (ACP), used for programmatic control, primarily for IDE and other developer tool integrations. This is protocol which IDEs like JetBrains and Zed have adopted, so Antigravity CLI becomes incompatible with them
      • Google offers no migration path from Gemini CLI settings/skills/MCPs into Antigravity. Figure it out on your own!
      • Devs using Gemini models are forced to move as Google has removed support for Gemini 3.5 Flash model from Gemini CLI. It can only be used from Antigravity CLI. Clearly, this was done to force a move. Why not offer a migration path?

      My sense is the Antigravity team is moving fast, breaking things, and shipping a broken product. It feels like the Antigravity 2.0 and Antigravity CLI products have been rushed to meet the annual Google conference (Google I/O) deadline, this week. Google deprecates existing products to attempt to get users to switch to the new version. But the new one is broken.

      altWhat 's changed? Manu Cornet __ penned this cartoon in 2011__

      And this is a big reason why I don't believe Google will become a serious player in the dev tools space - not even with AI dev tools. Every six to twelve months they remind devs who onboarded to their dev tools that it was a mistake to do so. I would expect the majority of Google CLI and Antigravity users to go and try products from other vendors - be that Cursor, Anthropic, OpenAI, GitHub, or others - and for few to stick around after their workflows are broken.

    5. 🔗 r/reverseengineering [Reverse-Engineering] Skeet CS:GO source code (Gamesense) rss
    6. 🔗 r/reverseengineering [Reverse-Engineering] Skeet CS:GO source code (Gamesense) rss
    7. 🔗 r/reverseengineering Giulio Zausa's MMO-CHIP Makes Reverse Engineering Old Silicon Chips a Multiplayer Game rss
    8. 🔗 r/reverseengineering I built 99 adversarially malformed PE files to test tool robustness - here’s what happened rss
    9. 🔗 HexRaysSA/plugin-repository commits sync repo: +1 release rss
      sync repo: +1 release
      
      ## New releases
      - [yarg](https://github.com/r0ny123/yarg): 1.0.5
      
    10. 🔗 anthropics/claude-code v2.1.173 release

      What's changed

      • Fixed Fable 5 model names with a [1m] suffix not being normalized — Fable 5 includes 1M context by default, so the suffix is now stripped automatically
      • Fixed a spurious "sandbox dependencies missing" startup warning on Windows when sandbox was enabled in settings
    11. 🔗 r/reverseengineering Drive Firmware Security - Phison S11 rss
    12. 🔗 Console.dev newsletter sem rss

      Description: Semantic Git diffs.

      What we like: Provides a higher-level abstraction to understand what changed in the code e.g. showing function names added/removed. Includes a dependency graph to highlight what might be impacted by a change. Supports JSON output for LLMs to better analyze changes.

      What we dislike: Useful starting point to understand changes before you get into the details using Git.

    13. 🔗 Console.dev newsletter Herdr rss

      Description: Agent terminal multiplexer.

      What we like: TUI for tmux-style persistence for multiple AI agent sessions. Easily detach, reattach, and work locality or remotely over SSH. Works with your existing terminal. Keyboard-first, but supports the mouse. Agents can use it to operate their own workspaces. Has a mobile-optimized view.

      What we dislike: Live handoff for updating a running Herdr server works well, but is still technically experimental so don’t rely on it yet.

  3. June 10, 2026
    1. 🔗 IDA Plugin Updates IDA Plugin Updates on 2026-06-10 rss

      IDA Plugin Updates on 2026-06-10

      New Releases:

      Activity:

    2. 🔗 anthropics/claude-code v2.1.172 release

      What's changed

      • Sub-agents can now spawn their own sub-agents (up to 5 levels deep)
      • Amazon Bedrock now reads the AWS region from ~/.aws config files when AWS_REGION isn't set, matching AWS SDK precedence; /status shows where the region came from
      • Added a search bar when browsing a marketplace's plugins in /plugin
      • Added model attribute to the claude_code.lines_of_code.count OTEL metric
      • Fixed sessions using 1M context without usage credits getting permanently stuck — the session now automatically compacts back under the standard context limit
      • Fixed a repeating "an image in the conversation could not be processed and was removed" error when the conversation contained multiple images
      • Fixed the agents view keeping a session under Working with a busy spinner for up to 30 seconds after the worker replied
      • Fixed background agents potentially reading another directory's project settings (.mcp.json approvals, trust) when dispatched onto a pre-warmed worker
      • Fixed background-session attach failing with EAUTH for sessions started on an older version after the daemon auto-updated
      • Fixed a background sub-agent staying stuck as "active" in the agent panel after a nested agent it spawned was stopped
      • Fixed /model suggestions in the claude agents dispatch input rendering with a misleading slash prefix and showing models disabled for your org
      • Fixed availableModels restrictions not being applied to subagent model overrides, the agent dispatch model picker, and the advisor model
      • Fixed availableModels allowlists hiding the /model picker's Opus and Sonnet 1M rows when entries use version-specific IDs like claude-opus-4-8
      • Fixed the /model picker on Bedrock offering models the provider doesn't serve — selecting one silently switched the session model and lit the selection marker on multiple rows
      • Fixed model IDs getting a doubled 1M-context suffix (e.g. [1M][1m]) when ANTHROPIC_DEFAULT_OPUS_MODEL already includes one
      • Fixed opusplan model setting not shipping with 1M context in plan mode for entitled users; the opusplan[1m] workaround now also correctly switches to Opus in plan mode
      • Fixed WebFetch(domain:*.example.com) wildcard domain rules never matching subdomains in allow, deny, and ask position, and file permission rules with mid-pattern wildcards (e.g. Read(secrets-*/config.json)) being rejected at startup
      • Fixed up-arrow prompt history showing the main agent's prompts while a subagent's chat tab is open
      • Fixed memory recall not finding mounted team memory stores (CLAUDE_MEMORY_STORES) in remote sessions
      • Fixed workflow validation rejecting scripts whose prompt strings or comments merely mention Date.now()/Math.random()
      • Disable mouse tracking on Windows consoles that don't fully support it
      • Fixed the /plugin marketplace list losing its cursor after backing out of a long plugin list, and Esc from the plugin browser returning to the wrong tab
      • Improved performance in long conversations by removing redundant message normalization and avoiding full message-history transforms when streaming tool-use state is unchanged
      • Reduced idle CPU usage: /goal status chip no longer re-renders the terminal at 5 Hz while idle, and fewer UI re-renders while subagents run in parallel
      • Improved Claude in Chrome tool loading: browser tools now load in a single batched call instead of one per tool
      • Improved the non-interactive Usage Policy refusal message to suggest starting a new session or changing your model
      • /code-review now keeps the ultra option visible when you're not signed in to claude.ai, with an explanation that the cloud review requires a claude.ai account
      • Shortened the Remote Control footer indicator to "/rc active" and hid it on narrow terminals
      • Stopped promoting /loop in remote sessions, where pending loops don't keep the container alive
      • [VSCode] Fixed PowerShell tool calls rendering as raw JSON instead of a proper command display and permission dialog, and stripped ANSI escape codes from displayed shell output
    3. 🔗 r/reverseengineering IDA 9.4 Beta | Hex-Rays Docs rss
    4. 🔗 backnotprop/plannotator v0.20.1 release

      Follow @plannotator on X for updates


      What's New in v0.20.1

      A hotfix for Pi extension installs. If pi install npm:@plannotator/pi- extension failed for you today, this release fixes it.

      Pi Extension Install Failure

      Fresh installs of @plannotator/pi-extension started failing with an npm 404. The cause was upstream: our diff renderer dependency @pierre/diffs published a new 1.2.x line that depends on @pierre/theming@0.0.1, a package that does not exist on the npm registry. Plannotator declared the dependency with a loose ^1.1.12 range, so fresh installs floated onto the broken 1.2.9 and failed before Pi could finish loading extensions. Repo builds never saw it because the lockfile pinned an older version.

      The fix pins @pierre/diffs to exact 1.1.20 everywhere, whose dependency tree fully resolves. Update with:

      pi install npm:@plannotator/pi-extension
      

      Install / Update

      macOS / Linux:

      curl -fsSL https://plannotator.ai/install.sh | bash
      

      Windows:

      irm https://plannotator.ai/install.ps1 | iex
      

      Pi: Install or update the extension:

      pi install npm:@plannotator/pi-extension
      

      Upgrading from before v0.20.0? Read the v0.20.0 release notes first; that release changed how skills install.


      What's Changed

      • fix(deps): pin @pierre/diffs to exact 1.1.20 by @backnotprop

      Community

      @ramarivera reported the install failure with a complete diagnosis of the broken dependency chain, down to the exact unpublished package. @MaksimZinovev and @archidemus confirmed the failure.

      Full Changelog : v0.20.0...v0.20.1

    5. 🔗 sacha chua :: living an awesome life La semaine du 1 au 7 juin rss

      lundi le premier juin

      Ma fille a séché les cours et elle n'a pas non plus voulu aller à son cours de gymnastique parce qu'elle a eu une mauvaise nuit et elle était toujours grincheuse.

      Au lieu de la harceler, j'ai travaillé sur des transcriptions et sur mon bulletin d'information sur Emacs. J'ai écrit des fonctions pour comparer les mots et effacer les étendues qui correspondent avec les mots effacés.

      Après avoir lu dans sa chambre pendant longtemps, elle a finalement réapparu de bonne humeur. Elle et moi avons préparé du sushi pour le dîner. Ensuite, nous avons joué au Scrabble dehors.

      Elle a porté sa prothèse oculaire toute seule. Elle a dit qu'elle l'a fait pour elle-même. Je pense que l'autonomie est très importante pour ma fille.

      Nous avons fait du vélo à la cour de récréation avec son amie, où nous avons rejoint d'autres amies. De temps en temps, ma fille était surstimulée. Quand ça arrivait, elle a joué au Scrabble avec moi et la nourrice de ses amies. Après qu'une de ses amies soit partie, nous sommes allées à l'autre cour de récréation pour jouer encore.

      mardi 3

      Ma fille a participé à l'école ce matin même s'il y avait un remplaçant, mais elle n'a pas voulu y participer l'après-midi. Nous sommes assises dehors et nous avons travaillé sur ses devoirs. Nous avons vu des pics.

      J'ai emmené ma fille au parc pour jouer avec ses amis. Elle a aimé faire du vélo autour du parc avec ses amis et sans adultes. Ils ont aussi fait du vélo autour de la pataugeoire qui était sèche parce qu'elle n'était pas encore ouverte. Ils tournaient en rond.

      J'ai fait l'erreur de jouer à mon jeu de Tileman Reworked près de ma fille. Elle a voulu m'aider, bien. Elle a recueilli les citrouilles et les canneberges, bien. Elle a commencé à couper l'herbe près des récoltes, euh… J'ai essayé d'expliquer qu'il ne fallait pas la couper, mais elle est devenue grincheuse parce que je la corrigeais. Elle m'a dit qu'elle voulait seulement m'aider et elle est partie furieuse. Ce n'est pas grave. Je pense que cette ferme est trop compliquée pour elle pour le moment. Notre ferme habituelle est meilleure. J'apprécie qu'elle ait voulu m'aider, et c'était juste un jeu. C'est aussi bien si elle apprend comment coopérer.

      J'ai commencé à réécrire la transcription de la conversation entre ma sœur et notre cousine.

      jeudi 4

      J'ai discuté d'Emacs avec Ben Zanin. Il a partagé sa configuration sur elfeed, la musique, et d'autres sujets.

      J'ai travaillé comme consultante. J'ai pris un cours de formation.

      Ma fille et moi avons fait du vélo au parc. Nous avons joué à la pataugeoire et au bac à sable. Nous avons improvisé des histoires de Donjons et Dragons avec les dés sur mon smartphone.

      J'ai discuté avec mes sœurs et quelques personnes des assurances-vie de ma mère. Notre accès au compte bancaire sera limité si ma sœur décède, donc il vaut mieux que nous fassions la paperasse maintenant.

      vendredi 5

      J'ai eu ma première session de la conversation avec mon tuteur aujourd'hui ! À mon grand étonnement, j'ai pu suivre assez de ses mots et j'ai pu expliquer mes pensées ( avec une mauvaise grammaire, bien sûr ). Je sais qu'il fallait que je m'entraîne à penser en français au lieu de traduire de l'anglais, donc davantage parler, davantage apprendre. C'est un exercice intense. J'avais transpiré. Nous avons réussi à parler de la programmation, des études à l'université, le travail, la vie, et d'autres sujets.

      J'ai augmenté le stockage pour les vidéos de ma sœur.

      J'ai signé la paperasse pour les assurances-vie.

      J'ai appelé ma mère et je l'ai informée de la paperasse.

      samedi 6

      J'ai téléchargé encore d'autres vidéos de ma sœur.

      Nous avons joué aux Donjons et Dragons avec ses tantes et ses cousines. Ma fille était la meneuse de jeu pour une partie de la session. Nous avons cherché une petite chèvre perdue, et nous avons combattu quatre bandits déguisés en gardes.

      Nous avons fait des mochis.

      J'ai payé la pénalité pour la soumission en retard du bilan de vérification du revenu étranger que je n'ai pas pu finir l'année précédente parce que le banquier était peu communicatif. Tant pis. Je pense que si ça arrive encore, je dois le soumettre avec ma meilleure estimation.

      Dans mon jeu Tileman Reworked de Stardew Valley, j'ai finalement accédé à la boutique de Willy, le pêcheur. C'était le dernier jour d'automne de la quatrième année.

      J'ai travaillé comme consultante. J'ai analysé des mises à jour.

      dimanche 7

      J'ai emmené ma fille chez le perceur pour examiner ses oreilles. Le perceur nous a dit qu'elle avait l'autorisation de changer pour de nouvelles boucles d'oreilles. Sur le chemin du retour, nous avons fait une promenade dans le parc.

      J'ai emmené ma fille au Dufferin Mall pour sélectionner des boucles d'oreilles. Après quelques comparaisons, ma fille a opté pour des clous d'oreilles en acier plaqué or avec des pierres moyennes chez New Steel. C'était bon marché.

      J'ai fini de coudre la robe de ma fille. Elle voulait me coudre une robe, donc j'ai préparé des pièces pour elle. Il vaut mieux que j'utilise beaucoup d'épingles et que je trace une ligne à la craie.

      You can e-mail me at sacha@sachachua.com.

    6. 🔗 Hex-Rays Blog IDA 9.4 Beta Is Now Available rss

      IDA 9.4 Beta Is Now Available

      If you're part of our Beta Program, the new build is now available in the Download Center of your customer portal. Your testing and feedback are essential in validating new features, surfacing regressions, and ensuring this release is ready for production use.

      Not enrolled yet? Joining the program is quick and easy, just click Subscribe from your customer portal dashboard - see below for details.

    7. 🔗 r/reverseengineering Trane Tracer HVAC cybersecurity issues rss
    8. 🔗 3Blue1Brown (YouTube) What's the perfect encoding? How do you know? rss

      Full video: https://youtu.be/l6DKRf-fAAM

    9. 🔗 VoidNullable/lific v1.5.0 release

      Lific learns to remember and to listen. Every change is now recorded in an audit log — who did it, what changed, and whether it came through the web UI, an agent over MCP, the API, or the CLI — with activity surfaces across the app to read that history. A command palette puts every issue, page, project, and action one keystroke away. The issue list gains multi-select with bulk editing, connected tools get much richer query controls, and a sweep of UI fixes lands across every view.

      Audit log and activity

      • Every mutation is recorded : issue, page, project, module, label, folder, and comment changes land in an append-only audit log with per-field old → new values. Edits to titles, descriptions, statuses, priorities, modules, labels, relations, and more are captured individually — no opaque blobs.
      • Full actor attribution : each entry records who acted and through which door — a person in the web UI, an agent over MCP (shown as its bot identity, e.g. opencode-blake · agent · via mcp), a direct API call, or the CLI. Trustworthy answers to "did the agent do this, or did I?"
      • Capture is at the database layer , so every write path is covered uniformly — including future ones. History survives entity deletion (deleted issues keep their identifier in the log), module/folder/lead changes record names rather than ids, and rolled-back transactions are never recorded.
      • Project Activity page : a new "Activity" view in each project's sidebar shows everything that happened, newest first, grouped by day. Entries link to their entities, expand to show exact timestamps (local and UTC), full old → new values, and the actor's standing in the project ("412 actions · 2nd most active · last seen 3m ago"). An actor rail ranks everyone who has touched the project — humans and agents — by action count, each a one-click feed filter. The feed updates live.
      • Activity timelines on issue and page detail : a quiet history between the description and comments — status and priority changes with their icons, expandable description-diff blocks, label and relation events, agent badges, and "via web/mcp/api/cli" attribution. Updates immediately after your own edits.
      • For integrations : a new get_activity tool answers "what changed while I was gone" for any issue, page, or whole project, and the REST API gains /activity endpoints for issues, pages, and projects plus a per-project actor rollup.

      Command palette

      • Cmd+K or Ctrl+P from anywhere opens a jump-to-anything palette covering projects, issues, pages, modules, and folders.
      • It understands identifiers : OMN156, omn 156, and OMN-156 all resolve to issue OMN-156; lif doc 3 finds the page; a bare 156 is probed across every project and lists all hits.
      • Free text searches issues and pages full-text, merged with fuzzy matches over projects, modules, and folders. The best-matching group leads the list, typing a project's name takes you to it, and an empty query doubles as a project switcher.
      • Context actions : on an issue, the palette offers Set status, Set priority, Set module, Add or remove label (with current values shown), Rename, Edit description, and Add comment — submenus are filterable, rename turns the palette into a prefilled prompt, and every action lands in the audit log like any other edit. Pages get their lifecycle status and labels. Creating a project is available from every view.

      Issue list: multi-select and bulk editing

      • Select with x, extend with shift+↑/↓ (or shift+j/k), shift-click for ranges, ctrl/cmd-click to toggle — then apply status, priority, module, or a label to everything at once from a floating action bar, or delete behind a confirm. Triage that used to be N round-trips through the detail page is now one pass.
      • Selection is keyboard-cheatsheet documented, pauses auto-refresh while active, and survives background updates.
      • The board's per-column "+" now creates the issue in that column's status instead of silently defaulting to backlog.

      Integrations

      • search supports filtering by result type (issue or page), relevance or most-recent sorting, and offset paging with has-more hints.
      • list_issues supports created/updated date windows (created_since, updated_until, …) and explicit ordering by sort order, sequence, created, or updated — ascending or descending.
      • Page listings gain the same ordering controls plus the status filter; page lines and get_page now include status, folder, and timestamps.
      • list_comments can filter by author and sort in either direction.
      • All ordering values are strictly whitelisted — invalid values error instead of being interpolated.

      Web fixes and polish

      • Issue status icons are now one shared vocabulary everywhere — the new-issue form's mismatched colored dots are gone, and module pages use the same glyphs as the rest of the app.
      • The high-priority orange and destructive-action colors are theme-aware tokens: "high" reads correctly in both modes, and red Delete buttons are no longer unreadable in dark mode.
      • An issue's status now shows in the detail-page breadcrumb.
      • Clicking a title to rename it shows the intended accent underline again, and priority icons in issue rows are properly sized.
      • Pages list: the count matches what's shown when archived pages are hidden, the status pill only appears for non-default stages (Draft/Complete/Archived) instead of on every row, and the updated date is always visible — without jittering the status pill's position.
      • Folders can no longer be dragged into each other — the move looked successful but was never persisted. Page drag-and-drop is unchanged.
      • The breadcrumb says "Board" on the board view, board column visibility pills show their counts correctly, and shift-click range selection no longer sweeps text selection across rows.
      • Signing in goes straight to Settings without a redirect flash, and ~450 lines of dead pre-1.4 UI code are gone.

      Upgrading

      • The database upgrades itself automatically on first launch (one new migration). Upgrading from any 1.x is safe and needs no manual steps. Audit history begins at the moment of upgrade — earlier changes were not recorded and cannot be backfilled.
    10. 🔗 HexRaysSA/plugin-repository commits sync repo: +2 releases rss
      sync repo: +2 releases
      
      ## New releases
      - [yarg](https://github.com/r0ny123/yarg): 1.0.4, 1.0.3
      
    11. 🔗 r/reverseengineering 🚀 Release PyMemoryEditor v2.0 — read, write and scan the memory of any running process, in pure Python (Windows, Linux & macOS) rss
    12. 🔗 Armin Ronacher Gaslighting Openness rss

      I have been a staunch supporter of Open Source for a long time, including experiments in funding it. I'm a true believer in the idea that Open Source always wins in the long run, but not automatically and not quickly. Right now it is being stressed by AI slop, shifting contributor dynamics, the falling cost of producing code, and large companies learning to close doors behind them.

      A lot of that battle today is manipulation of the narrative. Opinion makers on social media and in business circles increasingly frame access as irresponsibility. That is why the EU's DMA matters, even if many people (including myself) reflexively hate EU regulation. Apple's fight over delayed AI features in Europe is not about Brussels being annoying: it is about whether users can access their own devices and data. The phone is yours, the data is yours, yet Apple decides who may reach it and takes the agency away from you and then tries to make that sound like it is in your interest (supposedly it's for your safety and security).

      The closer you get to the core of AI, the more this shows up. Anthropic has every financial incentive to restrict what people can do with Mythos and Fable, and they wrap those restrictions in safety and (national) security language. Some restrictions may be defensible, but not all of them are. They trained their models on public works, then block Open Source attempts to learn from and distill these systems.

      Disliking the EU, China, or any other large government should not make us forget that true democratized access to technology including AI is in all our interest. Some temporary product pain, including delayed Apple AI features, will be worth paying if it keeps gates open. We should not let companies own the narrative that preventing access is in our interest, particularly not as Europeans where the odds are already stacked against us by our underdeveloped capital markets, brain drain and internal fighting.

    13. 🔗 exe.dev Sharing is Caring rss

      Today's quiz is to deploy a server-rendered hello world app (python3 -mhttp.server fine for these purposes, though I used Go below), publically visible, on your cloud of choice. On your marks, get set, GO!

      $ ssh exe.dev new --name mr-rogers
      $ ssh exe.dev share set-public mr-rogers
      $ ssh mr-rogers.exe.xyz
      # on that machine:
      $ cat > main.go
      package main
      
      import (
              "fmt"
              "net/http"
      )
      
      func main() {
              http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
                      fmt.Fprintln(w, "hello world")
              })
              http.ListenAndServe(":8000", nil)
      }
      ^D
      $ go run main.go  # maybe in a tmux
      
      # back on your laptop, open https://mr-rogers.exe.xyz/
      

      At exe.dev, our goal is to make sharing a web app that you built as easy as forwarding an e-mail. You saw the command-line approach above; there's an equivalent web-based flow as well.

      If you don't want to share with the whole world, but only some friends, the share command also takes e-mail addresses, and your users can log into your site.

      If you use exe.dev on a team, the sharing hierarchy is richer in that you can also share SSH access to your VM with a team member. The full hierarchy of sharing is:

      | Individual Accounts | Team Accounts
      ---|---|---
      Administrative
      (e.g., removing the VM) | Only owner | Owner, and, indirectly, team administrators
      SSH access
      (and agent access) | Only owner | Owner, or can be shared with team
      Single web port | Can be shared publicly, or with individual e-mail addresses. | Can be shared publicly, with a team, or with individual e-mail addresses.

  4. June 09, 2026
    1. 🔗 IDA Plugin Updates IDA Plugin Updates on 2026-06-09 rss

      IDA Plugin Updates on 2026-06-09

      Activity:

      • capa
        • ccf3a87e: tests: add snapshot tests for feature extraction (#3069)
        • 58bfa760: Sync capa-testfiles submodule
    2. 🔗 Simon Willison Initial impressions of Claude Fable 5 rss

      I didn't have early access to today's Claude Fable 5 release, but I've spent the past ~5.5 hours putting it through its paces. My initial impressions are that this is something of a beast. It's slow, expensive and has been quite happily churning through everything I've thrown at it so far. As is frequently the case with current frontier models the challenge is finding tasks that it can't do.

      First, let's review the key characteristics.

      Anthropic claim that Claude Fable 5 offers the same performance as Claude Mythos 5, except with much more strict guardrails in place to prevent it being used for harmful things. Those guardrails trigger often enough that the Claude API has new mechanisms for letting you know when you hit them, and even has a new option to request it falls back to another model automatically if something gets rejected.

      Claude Mythos 5 is out today as well, Anthropic say it "Shares Claude Fable 5's capabilities without the safety classifiers".

      The models have a 1 million token context window, 128,000 maximum output tokens and a knowledge cut-off date of January 2026.

      They are priced at twice the price of Claude Opus 4.5/4.6/4.7/4.8: $10/million input tokens and $50/million output tokens. There's no increase in price for longer context usage.

      Other than that the upgrade guide is substantially thinner than the similar guide for Opus 4.8.

      The big model smell

      The best way to describe Fable is that it feels big. Not just in terms of speed and cost, but also in how much it knows.

      Here's an example prompt, which I used to compare Fable's knowledge with Opus 4.8 (typo included):

      List all of Simon Willion's open source projects, most recent first, each with a rough date of when they were first released

      Opus 4.8's reply started like this:

      I don't have a reliable, comprehensive, and date-verified list of all of Simon Willison's open source projects, and I want to be honest about that rather than risk giving you inaccurate dates or fabricated entries.

      Here's what I can tell you with reasonable confidence:

      Well-known projects by Simon Willison:

      • LLM (~2023) – A command-line tool and Python library for interacting with large language models.

      • Datasette (~2017) – A tool for exploring and publishing data, probably his most prominent recent project.

      • sqlite-utils (~2018-2019) – A Python library and CLI tool for manipulating SQLite databases, often used alongside Datasette.

      • Django (2005) – He is one of the co-creators of the Django web framework, along with Adrian Holovaty, originally developed at the Lawrence Journal-World newspaper.

      He also maintains a large ecosystem of Datasette plugins and many smaller utilities (often with names like shot-scraper, various *-to-sqlite tools for importing data, etc.).

      That's not bad. Here's the start of the response for the exact same prompt from Fable 5 - both models were running without access to search:

      I think you mean Simon Willison — the prolific open source developer, co-creator of Django, and creator of Datasette.

      An important caveat upfront: a truly complete list isn't feasible. Simon Willison is famously prolific — he has published hundreds of repositories (Datasette alone has 100+ plugins, many written by him), and my knowledge has a cutoff date, so I'll be missing his most recent work. Below are his notable projects with approximate initial release dates, most recent first:

      Notable projects (approximate dates)

      • files-to-prompt (April 2024) – concatenates files into a single prompt for LLMs
      • datasette-extract (2024) – plugin for extracting structured data using LLMs
      • LLM (May–June 2023) – CLI tool and Python library for interacting with large language models, plus a large ecosystem of plugins (llm-gpt4all, llm-mistral, llm-claude, etc., 2023 onward)
      • symbex (June 2023) – search Python code for symbols
      • ttok and strip-tags (May 2023) – CLI tools for token counting and HTML cleanup for LLM pipelines
      • datasette-lite (May 2022) – Datasette running entirely in the browser via WebAssembly/Pyodide
      • shot-scraper (March 2022) – automated website screenshots via Playwright
      • s3-credentials (November 2021) – CLI for creating scoped AWS S3 credentials
      • django-sql-dashboard (2021) – SQL reporting dashboards for Django
      • Dogsheep suite (2019) – personal analytics tools: twitter-to-sqlite, github-to-sqlite, healthkit-to-sqlite, dogsheep-beta, etc.
      • sqlite-utils (2018) – CLI and Python library for manipulating SQLite databases
      • Datasette (November 2017) – his flagship project; tool for exploring and publishing data
      • csvs-to-sqlite (2017) – convert CSV files to SQLite
      • Various early tools (~2007–2010) – soupselect, json-head, geocoders, and others
      • Django (developed 2003–2005, open-sourced July 2005) – co-created with Adrian Holovaty at the Lawrence Journal-World

      (Here's GPT-5.5 for good measure. It listed even more projects than Fable did!)

      In the past I've stated that I don't care about how much models know - I want them to be able to manipulate text and code in useful ways and actively look up the information they need via search tools, not bake it into their weights.

      But knowledge like this is a reasonably good proxy for model size - you can cram a whole lot more details about the world into a larger number of parameters.

      Does knowing more stuff mean the model is better at the tasks we pose to it? I can certainly imagine how a coding model with deeper knowledge of modern libraries and patterns could crunch through coding tasks more effectively.

      Is Fable really bigger than Opus? Anthropic haven't said anything about model size, so all we have are tea-leaves, but the speed, pricing and my own poking at its knowledge make me think that it's a large model. Maybe the largest yet from any vendor.

      Using Fable in Claude.ai

      Anthropic made Fable 5 available across all of their surfaces - the Claude.ai chat interface, Claude Code for web, Claude Code CLI and Claude Cowork as well. The model is available "until June 22nd" on the subscription plans (I'm on $100/month Max at the moment), after which it will be billed extra.

      Claude.ai is often under-estimated. Since September 2025 every chat has had access to a full container environment to run code, including the ability to install additional packages and even clone repositories directly from GitHub.

      Last week I released micropython-wasm, a Python library that uses wasmtime to run a custom build of MicroPython in WebAssembly to act as a sandbox for untrusted Python code.

      I decided to see if Fable could upgrade that to running full Python instead. I started with this prompt:

      Clone simonw/micropython-wasm from GitHub and research how this could use a full Python as opposed to MicroPython

      Fable identified that it could use Brett Cannon's cpython-wasi-build builds for this, but was unable to download them itself due to environment restrictions.

      So I grabbed the two zip files from that page and uploaded them to Claude:

      Here's the Brett Cannon builds (python-3.zip, _build-python-3.zip as attachments)

      And that was that. It churned away for a few minutes and got the entire thing working.

      Part of the response included:

      I tried the cleaner single-zip-stdlib approach to shrink the filesystem surface, but CPython's getpath bootstrap fails to find encodings from inside a zip without more prefix finessing — the directory-preopen approach works reliably, so that's what the PoC uses. The zip path is solvable but needs _PYTHONHOME/frozen-getpath work.

      So I said:

      Try a bit more at the single-zip-stdlib problem

      Then a little later:

      I want a wheel that has the whole system in it, the Python wrappers and the WASM files and the stdlibrary, so I can do uv run --with path-to-whl python -c "demo code"

      ... and it gave me this 13.9MB cpython_wasm-0.1.0-py3-none-any.whl file. You can try running Python code in a sandbox using that wheel URL and uv like this:

      uv run --with https://static.simonwillison.net/static/cors-allow/2026/cpython_wasm-0.1.0-py3-none-any.whl \
        cpython-wasm -c 'print(45 ** 56)'

      Here's the full chat transcript.

      This was a very strong start.

      Adding features to Datasette Agent and LLM using Claude Code

      Before I'd realized it was Fable day, my stretch goal for today was to add a new feature to Datasette Agent: I wanted tool calls within that agent software to gain the ability to pause mid-execution and request approval directly from the user.

      This felt like a suitably meaty task to throw at the new model.

      Over the course of the day Fable not only solved that problem, it also identified and then implemented four issues in my underlying LLM library that would help support this kind of advanced pause-resume mechanism in tool calls.

      It got everything working first using somewhat gnarly hacks, but the moment I told it that changes to LLM itself were in scope it set to work unraveling the hacks and turning them into supported features of LLM instead.

      My stretch goal turned into LLM 0.32a3, almost entirely written by Fable. Here are the release notes:

      Driven by the needs of Datasette Agent's human-in-the-loop ask_user() feature, made the following improvements to how tool calls work:

      • Tool implementations can declare a parameter named llm_tool_call in order to be passed the llm.ToolCall object for the current invocation. This allows them to access the current llm_tool_call.tool_call_id. See Accessing the tool call from inside a tool. #1480
      • Every tool call is now guaranteed a unique tool_call_id - providers that do not supply one get a synthesized tc_-prefixed ULID. #1481
      • Tools can raise a llm.PauseChain exception to cleanly pause the tool chain, useful for things like waiting for human approval. The exception propagates to the caller with .tool_call and .tool_results (completed sibling results) attached, and no model call is made with a placeholder result. See Pausing a chain from inside a tool. #1482
      • Failure semantics for concurrent tool execution: async sibling tool calls always run to completion before a pause or hook exception propagates. #1482
      • Chains can now resume from a messages= history ending in unresolved tool calls: the calls are executed through the normal before_call/after_call machinery before the first model call, skipping any that already have results. The execute_tool_calls() method also accepts a new optional tool_calls_list= argument for executing an explicit list of ToolCall objects in place of the calls requested by the response. See Resuming a chain with pending tool calls. #1482
      • Fixed a bug where the async tool executor silently dropped calls to tools not present in tools= - these now return Error: tool "..." does not exist results, matching the sync executor. #1483

      I'm really impressed with the quality of API design, tests, code and documentation that Fable put together for this. I spent several hours on it today, but it feels like several days' worth of work.

      How much I've spent

      I recently started using AgentsView to help track my local LLM usage across all of the different coding agents. I published a TIL today about adding custom Fable pricing to that tool, which I expect will not be necessary in the very near future.

      After setting the price, I ran this command to start a localhost web server to explore my usage:

      uvx agentsview serve
      

      Here's the treemap showing the breakdown of my Fable usage across various projects today:

      Screenshot of a cost tracking dashboard with two panels. The first panel is titled "Cost Attribution" with toggle buttons for Project / Model / Agent and Treemap / List, with Project and Treemap selected. Italic text reads "Click to hide from chart". A treemap shows a large red block labeled prod_datasette_agent $99.26 89.9%, with smaller blocks to its right labeled cloud (blue), datasette (teal), llm (red), and money (pink), plus a tiny orange sliver. A legend lists: 1 prod_datasette_agent $99.26, 2 cloud $3.98, 3 datasette $2.81, 4 llm $2.30, 5 money $1.92, 6 simon $0.15. The second panel is titled "Top Sessions by Cost" and lists nine sessions, each with a "Claude" badge, a prompt excerpt, a project name with a session UUID (omitted here), a token count, and a cost: 1. Review ./datasette-agent and ./datasette-apps - we are going to add a new feature to agent but you ... prod_datasette_agent, 78.2M, $99.26. 2. issues.db is a copy of the Datasette issues database. There are a LOT of notes in there relating to... datasette, 826.8k, $2.81. 3. Consult fly-docs and then look at datasette.cloud (which launches fly machines) and datasettecloud-... cloud, 924.7k, $2.61. 4. simonwillisonblog.db is a copy of my blog, plus all my software releases and other interesting thin... money, 542.9k, $1.92. 5. Look in datasette.cloud and figure out all remaining steps and decisions that need to be made in or... cloud, 455k, $1.37. 6. Review PRs and issues filed against this repo within the last 4 weeks and see if any deserve to be ... llm, 323.3k, $0.95. 7. run mypy, llm, 320.9k, $0.76. 8. [Image #1] fix this in github actions, llm, 183.9k, $0.59. 9. simon, simon, 26.4k, $0.15.

      I used $110.42 worth of tokens today, all as part of my $100/month subscription.

      And some pelicans

      I ran "Generate an SVG of a pelican riding a bicycle" against all five thinking effort levels with Fable.

      Here are the results, including the token cost for each one:

      It's interesting that high ended up using fewer tokens than medium for this particular run.

      Here are the Opus 4.8 pelicans for comparison.

      You are only seeing the long-form articles from my blog. Subscribe to /atom/everything/ to get all of my posts, or take a look at my other subscription options.

    3. 🔗 @binaryninja@infosec.exchange Wake up binjas, new Binary Ninja 5.3.9757 stable just dropped. No mastodon

      Wake up binjas, new Binary Ninja 5.3.9757 stable just dropped. No functionality this time (head over to dev for that!) but lots of stability fixes for the appropriately named stable branch:

      https://binary.ninja/2026/06/09/5.3-release-2.html

    4. 🔗 earendil-works/pi v0.79.1 release

      New Features

      • Claude Fable 5 - Claude Fable 5 is now available on the Anthropic and Amazon Bedrock providers, with adaptive thinking and xhigh effort support.
      • Prompt template defaults - Prompt templates can use default positional arguments such as ${1:-7} for optional values. See Prompt Template Arguments.
      • Configurable project trust defaults - defaultProjectTrust lets users choose whether unresolved project trust asks, always trusts, or never trusts by default, and extensions can inspect effective trust decisions. See Project Trust and ctx.isProjectTrusted().
      • Natural extension autocomplete triggers - Extension autocomplete providers can declare trigger characters such as # or $ so suggestions open without slash-command prefixes. See Autocomplete Providers.

      Added

      • Added default-value expansion for prompt template positional arguments, e.g. ${1:-7} (#5553 by @dannote).
      • Added areExperimentalFeaturesEnabled feature guard to allow users to opt in to early features (#5547 by @vegarsti).
      • Added ctx.isProjectTrusted() for extensions to observe the effective project trust decision, including temporary trust decisions (#5523).
      • Added a global defaultProjectTrust setting to choose whether unresolved project trust asks, always trusts, or never trusts by default.
      • Added extension autocomplete trigger character support for ctx.ui.addAutocompleteProvider() wrappers (#4703).
      • Added Claude Fable 5 model support inherited from @earendil-works/pi-ai for the Anthropic and Amazon Bedrock providers, with adaptive thinking and xhigh effort support.

      Fixed

      • Fixed inherited Amazon Bedrock inference profile ARN region resolution to prefer the ARN's embedded region over AWS_REGION (#5527 by @AJM10565).
      • Fixed inherited IME hardware cursor positioning while slash-command autocomplete is visible (#5283 by @smoosex).
      • Fixed inherited z.ai thinking-off requests to send the provider's thinking: { type: "disabled" } compatibility parameter (#5330).
      • Fixed inherited OpenCode completions model metadata to send explicit maxTokens as max_tokens (#5331).
      • Fixed inherited Moonshot Kimi thinking-off requests to send the provider's thinking: { type: "disabled" } compatibility parameter (#5531).
      • Fixed inherited Azure OpenAI Responses requests to disable server-side response storage (#5530).
      • Fixed inherited Azure GPT-5.4 and GPT-5.5 context window metadata to 1,050,000 tokens, matching Azure Foundry deployments instead of OpenAI's 272k limit (#5559).
      • Fixed inherited OpenAI and Azure GPT-5 Pro maxTokens metadata to 128,000, correcting an upstream value that duplicated the input sub-limit as the output limit (#5559).
      • Fixed inherited prompt history navigation to restore the current draft when returning from history browsing (#5494).
      • Fixed inherited wrapping for mixed Latin and CJK text so unspaced CJK runs can break at grapheme boundaries without leaving large trailing gaps (#5495).
      • Fixed extension OAuth login prompts to keep previous submitted prompt rows stable instead of mirroring the active input value (#5433).
      • Fixed /reload to apply updated steeringMode and followUpMode settings to the current session (#5377).
      • Fixed invalid models.json syntax to skip startup config migrations and report the normal file-path-aware models error instead of a raw JSON parse stack trace (#5418).
      • Fixed GitHub release notes and interactive changelog links to resolve package-relative documentation URLs correctly (#5516).
      • Fixed CLI help and version output, including plain redirected --help/--version output and simplified list/config help text.
      • Fixed /new from ephemeral sessions to keep the new session ephemeral instead of persisting it by default (#5045).
      • Clarified custom model docs that name and modelOverrides.name do not replace model IDs in the footer or primary model lists (#4841).
    5. 🔗 VoidNullable/lific v1.4.1 release

      A maintenance release: a sweep of correctness and security fixes across the database, auth, and MCP layers, plus server and web improvements that landed after v1.4.0.

      Fixes

      • Creating an issue is now atomic — a failed label attach can no longer leave a half-created issue behind.
      • Rotating an API key keeps its user binding, so rotated bot/tool keys no longer lose their comment attribution.
      • Empty or whitespace-only search queries return no results instead of a database error.
      • Project identifiers are validated on create and update: uppercase letters and digits, at most 5 characters, starting with a letter. Hyphenated, lowercase, or empty identifiers (which silently broke issue lookups) and the reserved word DOC are rejected.
      • An issue can no longer be linked to itself — a self-"blocks" previously made it permanently unworkable.
      • Board columns follow workflow order (backlog → todo → active → done → cancelled) and priority severity, instead of alphabetical order.
      • Auto-refresh no longer stacks duplicate fetches when navigating between views.
      • OAuth protected-resource metadata advertises the /mcp-qualified resource so claude.ai web accepts issued tokens.

      Server and web

      • Responses are gzip/brotli compressed and content-hashed assets are cached immutably, dramatically cutting first-load time on slow links.
      • Issue list, board, and page views auto-refresh to reflect changes without a manual reload.
      • Optional authless MCP endpoint at /mcp/<token> to work around claude.ai web's broken OAuth connector flow.
      • Priority icons are now consistent across the UI.
      • The root URL lands on Settings instead of the first project's issue list.
    6. 🔗 backnotprop/plannotator v0.20.0 release

      Follow @plannotator on X for updates


      Missed recent releases? Release | Highlights
      ---|---
      v0.19.27 | Kiro CLI integration, Glimpse native window, annotate-last message picker
      v0.19.26 | Amp plugin production fixes, Mermaid rendering fix, Settings flicker fix, update notification toast and shimmer
      v0.19.24 | Amp integration, configurable data directory, Auto Mode permission option, Pi plan approval fix
      v0.19.23 | Droid integration, Windows Pi AI fix, quieter update indicator
      v0.19.22 | Safari copy fix in plan viewer, CLAUDE_CONFIG_DIR support for session logs
      v0.19.21 | Ask AI in plan review and annotate mode, shared AI runtime, origin-aware provider defaults
      v0.19.20 | Interactive goal setup UI, OpenCode submit_plan fixes, browser no-op sentinel handling for Claude agents
      v0.19.18 | Edit-based submit_plan for OpenCode, Pi namespace migration, Codex annotate-last fix, OpenCode commands dir fix
      v0.19.17 | Reworked goal setup skill (interview-driven flow), CLI --version flag
      v0.19.16 | Code navigation with peek view (Cmd/Ctrl+click tokens in diffs)
      v0.19.15 | Commit-based diff base, jj evolution diffs, GitLab reliability fixes, OpenCode command intercept fix


      What's New in v0.20.0

      v0.20.0 is the largest release in a while: 11 PRs, three of them from first- time contributors. Code review gains multi-repo workspace support and a semantic diff overview. The interface gets a full visual refresh with two new themes, a grid-versus-flat plan look, and a full-page HTML annotation mode. Under the hood, the way skills and commands install has been rationalized so each artifact has a single source of truth and a default install ships lean. Several reliability fixes round it out across OpenCode, Pi, Windows, and GitLab.


      Important

      v0.20.0 is a large release, and two of its changes affect existing installs. Please read these before you upgrade.

      1. Extra skills are no longer installed by default. The plannotator- compound, plannotator-setup-goal, and plannotator-visual-explainer skills used to ship with every install. They now install separately, so a default install stays lean. To add them:

      npx skills add backnotprop/plannotator/apps/skills/extra
      

      When you upgrade, the installer performs a one-time cleanup that removes the old default-installed copies of these three skills from ~/.claude/skills and ~/.agents/skills. If you want them, reinstall with the command above. Copies you install yourself with npx skills add are never touched again. (Kiro CLI is the exception and keeps receiving setup-goal and visual-explainer.)

      2. On Claude Code, the slash commands are now skills. Claude Code merged custom commands into skills, so Plannotator follows suit. /plannotator- review, /plannotator-annotate, and /plannotator-last are now installed as Claude Code skills under ~/.claude/skills (same names, same behavior). The old ~/.claude/commands/plannotator-*.md files are removed automatically on upgrade. The standalone /plannotator-status and /plannotator-archive commands are gone: plan archive browsing now lives in a sidebar tab during plan review. If you use the marketplace plugin, run /plugin marketplace update once so the old namespaced plannotator:* entries disappear from the / menu.

      If git is missing or a fetch is blocked, the installer now stops with a clear message instead of silently leaving you half-installed. git is required.


      Multi-Repo Workspace Reviews

      Code review previously required a git repository as the working directory. Teams working across several services in a parent folder had no way to review them together: each repo needed its own session, and feedback was fragmented.

      You can now run plannotator review from a non-git parent directory that contains multiple repositories. Plannotator discovers the nested repos that have local changes, pre-selects them, and presents a single review session covering all of them. Diff switching, file-content lookups, staging, and agent operations are all repo-aware, and the review feedback covers every repo in one pass. The single-repo workflow is unchanged: the workspace flow only engages when the directory you start from is not itself a repository.

      Semantic Diff Overview

      Code review now opens to a semantic diff overview that groups changes by what was modified rather than only by which lines moved. It runs the sem analyzer over the active patch and shows the result as the default landing panel, with a sidebar entry above All Files, rows for binary changes, inline error reporting, and retry.

      The analyzer ships as an optional sidecar that the installers fetch without blocking the rest of the install, and the overview is available in both the Bun-based servers (Claude Code, OpenCode) and the Pi extension's Node server. When the sidecar is unavailable, review falls back cleanly to the standard diff view.

      UI 2.0: New Themes, Plan Look Chooser, and Full-Page HTML Annotation

      The interface received a broad visual refresh. Two new themes, Simple and Neutral, join the existing set, built on a refreshed design-system token bridge. The overlay scrollbar library was removed in favor of native scrolling, which is lighter and more accessible.

      Plan rendering now offers two looks. Grid keeps your plan as a floating card on grid paper; Clean is a simpler, edge-to-edge flat card. A first-run dialog announces the release and lets you pick. The release announcement also surfaces what is new in the release and links to the full notes.

      Annotation gains a full-page HTML mode. Running plannotator annotate --render-html opens an HTML report or explainer rendered edge-to-edge in a sandboxed frame, themed to match Plannotator, and lets you annotate it directly with text selection or by clicking an element, instead of flattening it to markdown first. This pairs naturally with the visual-explainer skill's HTML output.

      Leaner Install and Single-Source Skills

      The way Plannotator ships skills and commands was restructured so each artifact has exactly one authoritative source. Core skills (review, annotate, last) install from a single location to both ~/.claude/skills and Codex's ~/.agents/skills. The extra skills move to opt-in installation via npx skills add (see the note at the top of these release notes). Every installer's hard-coded command and skill text was removed in favor of copying the real files from the repository, which eliminates a class of cross-platform escaping bugs.

      The installers also became stricter and safer to re-run. git is now a hard requirement, and a missing git or a failed fetch stops the install with an actionable message rather than silently skipping steps. Cleanup of legacy command files and stale Codex skills only happens after the replacement skill is on disk, so no upgrade path can leave you with neither. A one-time migration ledger tracks the extras cleanup so re-running the installer never re-removes skills you reinstalled yourself.

      First-run interactive installs ask whether to add the extra skills and whether to make any skills model-invocable, and the answers are saved and reused on later runs. Automated and piped installs never prompt and keep the safe defaults.

      Expand Unchanged Regions by Default

      Code review gains a persistent setting to expand unchanged diff regions by default. With it enabled, changed files open with their surrounding context already unfolded instead of requiring manual clicks. The toggle is available from both the main review display settings and the compact diff options popover, and it persists across sessions.

      OpenCode Runtime Compatibility

      The OpenCode plugin was split into a portable entry point and a Bun-only embedded runtime, so Node-hosted OpenCode no longer imports Bun server code at load time. On Bun hosts the plugin runs its full embedded runtime; on Node hosts it falls back gracefully to the installed Plannotator CLI. The fix restores agent switching, the recent-message picker for plannotator last, share disabling, and PR review semantics through the CLI bridge, and hardens sandboxed OpenCode startup so it uses a private port instead of attaching to an unrelated server.

      Glimpse Native Window on Windows

      On Windows, Glimpse never launched: npm installs glimpseui only as script shims with no native executable, so the plain spawn always failed and Plannotator fell back to a browser tab. The server now detects this case and launches Glimpse by running its package entry point directly with node, which keeps the HTML stdin pipe intact. Non-Windows hosts are unaffected.

      Additional Changes

      • Windows install prompt timeout and OpenCode cleanup. The PowerShell installer's first-run prompts no longer hang indefinitely without a terminal, and a stale OpenCode archive command stub is swept on upgrade. #875
      • GitLab merge request review reliability. GitLab MR review keeps the raw-diffs endpoint as primary and falls back to the paginated diffs endpoint when it is empty or fails, with a clear error when a merge request genuinely has no diff. (in #879)
      • Claude Fable 5 model option. Fable 5 was added to the code review and Ask AI model selectors alongside Opus 4.8.

      Install / Update

      macOS / Linux:

      curl -fsSL https://plannotator.ai/install.sh | bash
      

      Windows:

      irm https://plannotator.ai/install.ps1 | iex
      

      Extra skills (compound, setup-goal, visual-explainer), now opt-in:

      npx skills add backnotprop/plannotator/apps/skills/extra
      

      Claude Code Plugin: Run /plugin in Claude Code, find plannotator , and click "Update now". Then run /plugin marketplace update once to clear the old namespaced command entries.

      OpenCode: Clear cache and restart:

      rm -rf ~/.bun/install/cache/@plannotator
      

      Then in opencode.json:

      {
        "plugin": ["@plannotator/opencode@latest"]
      }
      

      Pi: Install or update the extension:

      pi install npm:@plannotator/pi-extension
      

      Droid: Install via the plugin marketplace:

      droid plugin marketplace add backnotprop/plannotator
      droid plugin install plannotator@plannotator
      

      Amp: Install the CLI first, then copy the plugin:

      mkdir -p ~/.config/amp/plugins
      curl -fsSL https://raw.githubusercontent.com/backnotprop/plannotator/main/apps/amp-plugin/plannotator.ts \
        -o ~/.config/amp/plugins/plannotator.ts
      

      Kiro CLI: The installer auto-detects Kiro and installs skills automatically. After installing the CLI, launch with:

      kiro-cli chat --agent plannotator
      

      What's Changed

      • feat(review): support multi-repo workspace reviews by @Oscar-Silva in #543
      • Fix OpenCode plugin runtime compatibility by @backnotprop in #849
      • Single-source skills (core/extra), replace Claude Code commands with skills, de-hardcode installers by @backnotprop in #850
      • Add persistent full-file diff context setting by @Perlten in #858
      • fix(server): launch Glimpse via node on Windows instead of unspawnable npm shim by @NikiforovAll in #861
      • UI 2.0 visual refresh by @backnotprop in #863
      • feat(review): add semantic diff overview by @backnotprop in #871
      • fix(install): restore /plannotator-* bash execution on Claude Code and harden unattended installs by @backnotprop in #872
      • chore: remove the redundant /plannotator-status and /plannotator-archive commands by @backnotprop in #873
      • fix(install): Windows prompt timeout and stale OpenCode archive stub sweep by @backnotprop in #875
      • feat(plan): grid-default plan look chooser and 0.20.0 release dialog, with GitLab, sem, and install fixes by @backnotprop in #879
      • feat(review): add Claude Fable 5 to the model selectors by @backnotprop

      New Contributors

      Contributors

      @Oscar-Silva built multi-repo workspace review, adding repo discovery from a non-git parent directory and making diff switching, file-content lookups, staging, and agent routing repo-aware, with regression coverage for the new workspace paths. @Perlten contributed the persistent full-file diff context setting, wiring it through server config and both the single-file and all-files diff views, and also reported the original request. @NikiforovAll diagnosed and fixed the Windows Glimpse launch failure, tracing it to npm's script-shim packaging and switching to a direct node spawn that preserves the stdin pipe, and reported the underlying issue with a clear reproduction table.

      This release also resolved a number of community-reported issues. @daviziks requested multi-repo review support for poly-repo workflows. @possiblyneal asked for a way to hide legacy alias skill names from the Claude skill list. @stefanbinoj raised loading skills into the system prompt by default. @cwardgar reported that Plannotator did not respect CODEX_HOME. @robsonpeixoto reported the marketplace plugin not installing the compound skill. @mactavishz, @boris- gorbylev, and @matteo9924 reported the OpenCode plugin load and runtime failures that the runtime split resolves.

      Full Changelog : v0.19.27...v0.20.0

    7. 🔗 r/reverseengineering I reverse engineered Lofree Hypace mouse firmware flashing protocol to bypass their official web based configuration on MacOS. rss
    8. 🔗 anthropics/claude-code v2.1.170 release

      What's changed

      • Introducing Claude Fable 5: a Mythos-class model that we’ve made safe for general use. Fable’s capabilities exceed those of any model we’ve ever made generally available. Update to version 2.1.170 for access. https://www.anthropic.com/news/claude-fable-5-mythos-5
      • Fixed sessions not saving transcripts (and not appearing in --resume) when launched from the VS Code integrated terminal or any shell that inherited Claude Code environment variables.
    9. 🔗 @HexRaysSA@infosec.exchange We're heading to [@x33fcon](https://infosec.exchange/@x33fcon) and we'd love mastodon

      We're heading to @x33fcon and we'd love to see you there!

      Stop by our expo table to dig into headless IDA, get a sneak peek at the newly revamped Teams, and check out our new malware-centric features. Or just come say hello! 👋

    10. 🔗 sacha chua :: living an awesome life From DC Toedt: Copy Org Mode as Markdown rss

      DC Toedt is a lawyer and professor of practice who uses Emacs and Org Mode. He wanted a small Emacs Lisp function to convert Org Mode syntax to Markdown and copy it to the clipboard to make it easier to copy the materials he's writing for a course on contract drafting. This seems to be a common need, and here are several other approaches:

      Anyway, DC shared how he used Claude to generate a simple function to do it, which is here under public domain:

      (defun my/org-to-markdown-clipboard ()
        "Export org region (or buffer) to Markdown and copy to clipboard.
      With no active region, exports the whole buffer."
        (interactive)
        (require 'ox-md)
        (let* ((text (if (use-region-p)
                         (buffer-substring-no-properties (region-beginning)
      (region-end))
                       (buffer-substring-no-properties (point-min) (point-max))))
               (md (org-export-string-as text 'md t '(:with-toc nil
                                                      :with-author nil
                                                      :with-date nil
                                                      :with-title nil))))
          (kill-new md)
          (message "Markdown copied (%d chars)" (length md))))
      (with-eval-after-load 'org
        (define-key org-mode-map (kbd "C-c m") #'my/org-to-markdown-clipboard))
      

      You can e-mail me at sacha@sachachua.com.

    11. 🔗 Locklin on science Progress: real and Potemkin rss

      I ran across this essay, Freddie deBoer offering a bet to Scott Alexander that the AI singularity isn’t coming in the next 3 years, based on a decent decent set of economic measurements: https://substack.com/home/post/p-187862732 I used to find it somewhat mind-boggling that allegedly intelligent people think we’re on the eve of some giant technological leap […]

    12. 🔗 HexRaysSA/plugin-repository commits sync repo: +1 plugin, +2 releases rss
      sync repo: +1 plugin, +2 releases
      
      ## New plugins
      - [yarg](https://github.com/r0ny123/yarg) (1.0.2, 1.0.1)
      
    13. 🔗 doomemacs/core v2.2.0 release

      v2.2.0

    14. 🔗 sacha chua :: living an awesome life June 11: Sacha and Prot Talk Emacs: Built-ins rss

      On June 11, I'm going to chat with Prot about the Emacs Carnival June 2026 topic Underappreciated Emacs Built-ins. Thanks to Ross A. Baker for hosting the carnival!

      (America/Toronto) = Thu Jun 11 1030H EDT / 0930H CDT / 0830H MDT / 0730H PDT / 1430H UTC / 1630H CEST / 1730H EEST / 2000H IST / 2230H +08 / 2330H JST

      You can e-mail me at sacha@sachachua.com.

    15. 🔗 panda-re/panda v1.8.85 @ refs/heads/dev release

      What's Changed

      Full Changelog : v1.8.83...v1.8.85

    16. 🔗 panda-re/panda v1.8.84 @ refs/heads/dev release

      What's Changed

      Full Changelog : v1.8.83...v1.8.84

    17. 🔗 Baby Steps Only Bounds rss

      only bounds are going to be the most impactful change to Rust that you've never heard of. They are currently being designed and developed by the Arm team (David Wood, Rémy Rakic, et al.) as part of the Sized Hierarchy and Scalable Vector Extension project goal. This post explores the feature and aims to answer a particular question about the design (the scope of bounds, I'll explain). But before I dive in, I want to give a bit of context.

      Rust generics have a Sized bound by default today

      In today's Rust, every type parameter (except for Self) has a default bound called Sized:

      // So this function...
      fn identity<T>(t: T) -> T {
          t
      }
      
      // ...is actually short for
      fn identity<T>(t: T) -> T
      where
          T: Sized, // <-- Added by default!
      {
          t
      }
      

      A type T implements Sized if the compiler can compute the size of a T value at compilation time. This is true for almost every type, with a few notable exceptions. Consider [u32], which refers to "some number of u32 instances". We know that a single u32 is 4 bytes, but without knowing how many u32 there are, you can't know the size of [u32]. This means you can't have a value of type [u32] on the stack (how big should the stack frame be?).

      You opt out with ?Sized

      However, if you have a function like by_ref, that just takes the value by reference (i.e., by pointer), you shouldn't need to know how big the [u32] value is, because you're not manipulating it directly. You can have a type parameter U that doesn't require Sized, but you have to explicitly "opt out" from the default bound:

      fn by_ref&lt;U&gt;(t: &U)
      where
          U: ?Sized, // <-- Opt out from the default
      { }
      

      As a fun bit of historical trivia, this system was introduced way back in 2014 to accommodate Dynamically Sized Types. Before that, &[u32] was actually a built-in, indivisible type; we even wrote it like [u32]/& for a time.1

      But Sized vs ?Sized isn't enough for everything we need

      The Sized vs ?Sized design has served us reasonably well but it is also showing its limits. It turns out that "value has a statically computable size" vs "each value has a distinct size computable at runtime" doesn't cover all the things you might want. For example, extern types are types whose values have no known size, even at runtime. And then Arm's Scalable Vector Extension want to describe SIMD types where every value of the type has the same size (unlike str and [T], where each value can have a different length) but where that size is not known until runtime.

      A richer Sized hierarchy

      Rather than just Sized or ?Sized, what we really want is to have a richer hierarchy. The current plans look something like this:

      flowchart TD
        subgraph S["Sizedness traits"]
            Sized[["Sized (default)"]] -- extends --> MetadataSized
            MetadataSized -- extends --> MaybeSized
        end
      

      where

      • trait Sized means that all values have the same size and that size can be computed knowing only the type.
      • trait MetadataSized means that values can have different sizes and that size can be computed given the metadata attached to a reference to the value. Examples include [T] or dyn Trait.
      • trait MaybeSized is implemented for all values and tells you nothing about the value's size.

      Two caveats:

      1. I'm excluding the way that Arm's Scalable Vector Extension fit into this, because it's orthogonal.
      2. The trait names aren't settled. I'm using the names I understand the libs-api team to prefer; they're not my favorites, but that's ultimately the team who owns stdlib bikesheds, so I defer to them.2

      Problem: ?Sized notation doesn't scale to this hierarchy

      But now we have a kind of problem. The ?Sized notation was predicated3 on the idea that users should specify the default bound they are opting out of - i.e., the ? is meant to say "I don't know if this is Sized or not" (unlike the default, where you know it is Sized). But "opting out" from a bound doesn't work so well with a multi-level hierarchy. When you write ?Sized, does that correspond to T: MetadataSized (but not T: Sized)? And what if we want to insert another level in between T: MetadataSized and T: Sized later? Then we either have to change what T: ?Sized means (to refer to the new bound) or we have to have T: ?Sized drop two levels down the hierarchy. Even more annoying, what do we do while that middle rung is unstable? Surely T: ?Sized shouldn't refer to an unstable trait… what if we decide to remove it

      Solution: only bounds

      The new proposal is to write T: only MetadataSized or T: only UnknownSized instead of T: ?Sized. An only bound combines two things:

      1. Like any bound, it includes a "minimum requirement" - i.e., T: only MetadataSized means that T must implement at least MetadataSized.
      2. It additionally disables some default bounds - i.e., we will not add the default T: Sized bound.

      The name only comes from the fact that T: Sized implies T: MetadataSized. So the default of T: Sized already means that T: MetadataSized for free; but when you write only MetadataSized, you are saying "I don't need the full hierarchy, just MetadataSized will do".

      only bounds work like normal bounds: ask for what you need

      A nice feature of only bounds is that they work more like a regular bound. Whereas a ? bound is saying "I don't need this", an only bound is saying what you do need. So e.g. if you are writing a function that just has references to values of type T does not care what their size is, you can write

      fn by_ref&lt;U&gt;(u: &U)
      where
          U: only MaybeSized,
      {}
      

      If you are writing a function that does need to compute the size of values of type V, you can ask for that capability:

      fn checks_size<V>(v: &V)
      where
          V: only MetadataSized,
      {
          std::mem::size_of_val(v)
      }
      

      only bounds allow for new levels to be added later

      A nice feature of only bounds is that, later on, we can add new levels to the hierarchy, and they work normally. For example, suppose we wish to add something like Aligned where the size is not known at compilation time but the alignment is. We could change the hierarchy to

      trait Sized: Aligned
      trait Aligned: MetadataSized // <-- new!
      trait MetadataSized: MaybeSized
      trait MaybeSized
      

      and functions with U: only MaybeSized (like by_ref) and with V: only MetadataSized (with checks_size) would continue to have the same requirements. But new functions could be written with T: only Aligned that would use the new bound. And there is no conflict with stabilization; code that writes T: only Aligned can be considered unstable until that middle hierarchy is finalized.

      only bounds compose normally

      Like any other bound, only bounds are combined with other bounds to form the overall requirements. So it is possible to write e.g. T: only MetadataSized + Sized. This is equivalent to T: Sized and therefore equivalent to the default and therefore kind of pointless, but you can write it. Similarly, given that trait Clone: Sized, if you write T: only MetadataSized + Clone, that is kind of pointless too: you might as well write T: Clone, which would be equivalent. We plan to have a warn-by-default lint for that.

      Scaling only to other "default bound families" (speculative)

      The final strength of only bounds is that they allow us to introduce whole new families of default bounds. One example is the idea of introducing a Move bound. Note that this is a distinct feature and is not covered under the current RFC.

      All types in Rust today are "movable" and "forgettable", meaning that you can memcpy the value from place to place so long as you stop using the previous location and you can recycle the memory where it is stored without running the value's destructor. There is one notable exception - when you pin a value, you it can no longer be moved, and you must run its destructor before its memory is reused - but otherwise this is a hard-and-fast rule. And that's annoying!

      The problem is that not being able to guarantee that a destructor runs blocks a lot of unsafe code patterns. For example, scoped tasks a la rayon depend on a destructor for safety. In sync code, this works because we've decided it's UB to unwind a stack frame without running the destructors of values stored there, and so if you put a local variable on the stack, you can be sure its destructor will run. But that doesn't work in async code! And there are times when unwinding without running destructors would be nice.

      The solution is to introduce a second family of default traits. Unlike the Sized family we saw before, this family defines fine-grained capabilities about how values of that type can be used:

      flowchart TD
        subgraph A["Accessability traits"]
            Forget[["Forget (default)"]] -- extends --> Leak
            Leak -- extends --> Destruct
            Destruct -- extends --> Access
            Move[["Move (default)"]] -- extends --> Access
        end
        Copy -- extends --> Move
      

      The meaning of the traits are as follows:

      • Forget, the default, says that you can recycle the memory for a value without running its destructor.
      • Leak says that you can skip running a destructor for a value, but only if you never reuse the memory where the value resides.
      • Destruct says that if you have a value of this type, you can reuse the memory where it resides by running its destructor.
      • Copy, which already exists, says that you can memcpy the place and keep using the original place; it's not really a default, but I included it because it is relevant.
      • Move, another default, says that you can memcpy the value to a new place if you stop using the original.
      • Access is the root of this family. It indicates a value that can be "accessed in place" (basically, any value at all).

      This introduces new checks into the compiler:

      • When you move a value (i.e., a = b where b is not used later), we will check that the type implements Move (whereas today, it is always allowed).
      • When you exit a scope, we will check that the values in each local variables have either been moved or have a type that implements Destruct.

      Some implications:

      • If your function owns a value of type T: only Destruct, then you must destruct it before your function returns. You can't move it (because you don't know if it implements Move) and you can't leak or forget it either.
      • If your function owns a value of type T: only Move, then the only thing you can do with it is move it somewhere else. You can't drop it (because you don't know if it implements Destruct).
      • No function can own a value of type T: only Access, because you wouldn't be able to move it nor drop it, and hence you could not return. But you could have such a value (say) in a static.

      How only bounds could work in the presence of multiple families

      The spur for writing this blog post was a question in a lang team meeting on how only bounds ought to work given the existence of multiple "families" of default traits, as I described above. Although the current RFC is looking only at the Sized traits, we expect to look at the "access family" in a future RFC, so we want to be sure we are not making any decisions that won't scale to cover both.

      The way I imagine it working is like this. Each default traits is associated with one or more "families". When you have an only bound, it "opts out" from all default traits in each family that the trait is associated with:

      • T: only Move opts out from Forget, Leak, Destruct - but not Sized.
      • T: only Destruct opts out from Forget, Leak, and Move - but not Sized.
      • T: only MetadataSized opts out from Sized - but not Forget or Move.
      • T: only MaybeSized opts out from Sized - but not Forget or Move.

      You may also want to "opt back in" to some defaults. For example, T: only Move + Destruct is a sensible thing to do. It means values that can be moved and destructed but not leaked or forgotten.

      Examples

      Option::map requires only Move

      map is an example of a function that only needs Move. You need to be able to destructure self (which moves the optional value out into a local variable v and then invoke the closure op, which again moves the wrapped value v:

      impl<T: only Move> Option<T> {
          fn map<U: only Move>(
              self,
              op: impl FnOnce(T) -> U,
          ) -> Option&lt;U&gt; {
              match self {
                  Some(v) => Some(op(v)),
                  None => None,
              }
          }
      }
      

      One interesting thing is the result type U. Using only the stuff I wrote in this blog post, it needs to be only Move, because the result will be moved into the Some value and so forth. But in-place-init would allow for this definition to omit the U: only Move bound because we could statically guarantee that the Option will be constructed in place and never moved after that.

      Option::or requires only Move + Destruct

      The a.or(b) method on Option returns a if it is Some and otherwise returns b. This is an interesting one because the value b may not be used and therefore requires only Move + Destruct bounds.

      impl<T: only Move> Option<T> {
          fn or(
              self,
              alternate: Option<T>,
          ) -> Option<T>
          where
              T: Destruct, // <-- because it may be dropped
          {
              match self {
                  Some(v) => Some(v), // drops `alternate`
                  None => alternate, // moves `alternate`
              }
          }
      }
      

      Rc requires MaybeSized + Leak

      The Rc type is an example where we would want to relax bounds from both families:

      struct Rc<T: only MaybeSized + only Leak> {}
      

      I believe the proper minimum bounds for Rc are:

      • only MaybeSized because while it can store MetadataSized or Sized things, it doesn't have to, it can also store things of an non-computable size (although it does raise the question of how they would be freed, but that's an allocator concern).
      • only Leak because Rc values can form cycles and thus we can't ever guarantee the destructor will be run. Interestingly, Rc<T> can implement Forget even its contents don't.

      Frequently asked questions

      What is actually under RFC today?

      The post may be a bit confusing here. The current RFC is looking only at the proposed "Sized" traits. The Access family is a speculative future extension that we are exploring but at a much earlier stage.

      Can I use only with any trait?

      In the beginning, the plan would be that only can only be used for well- known, default traits (e.g., Move, Sized, etc). In the future though there are some thoughts to generalizing it.

      Why not opt out from all defaults at once?

      An alternative that was proposed is to have the opt-out be per-type-parameter. So you might write something like

      fn foo<T: MetadataSized + ?default>
      

      which would "opt out" from all defaulted bounds. Obviously we'd have to bikeshed the syntax, but ignore that for now. The question is whether opting out of all defaults is better than opting out of a single family. I prefer the per-family option for two reasons:

      • First, things like T: only Move demonstrate that you might very reasonably which to opt out from a single family but retain the default Sized bound. I think it's likely that there will be many functions that want to opt out of Sized or Forget but not both.
        • You might think that we could make Move: Sized to get the same effect, but I think that would be a mistake. The fact that a value's size must be computed dynamically doesn't inherently mean it can't be moved.
      • Second, it makes it harder to introduce new families later, if we decide there are other orthogonal properties of values that we'd like to relax.

      Why do you think it's likely that people want to opt out of being Sized

      xor Forget but not both?

      Because the Forget, Move, and similar traits mostly apply to owned values. The examples we saw with Option<T> were quite typical. And when you are moving values of type T around, you need that T to be Sized.

      But we saw that Rc wanted to opt out of both families with `only Leak +

      only MetadataSized`, right?

      Yes, that's true, and I think that particular combo will be common. I don't think that's an argument for the ?default approach on its own, though, particularly since that case would not be much cleaner or shorter…

      impl<T: ?default + Leak + MetadataSized> Rc<T> {}
      

      …what I think that argues for is actually trait aliases and shorthands.

      Wait, trait aliases and shorthands? Can you elaborate?

      Yes! I think that a future RFC could extend only bounds to allow you to define trait aliases with "only bounds" as supertraits:

      trait RefCountable = only Leak + only MetadataSized;
      
      // Equivalent to:
      // trait RefCountable: only Leak + only MetadataSized {}
      // impl<T> RefCountable for T where T: only Leak + only MetadataSized {}
      

      You could then use an only RefCountable bound to define Rc<T>:

      impl<T: only Refcountable> Rc<T>
      

      Without theonly, T: Refcountable would just be a regular trait bound and would not opt-out from any defaults.

      Can we use a "root" trait to opt out of all defaults?

      Yes, we could! You could define an alias like Value:

      trait Value = only Access + only MaybeSized;
      

      Since Access and MaybeSized are both implemented for all types, this effectively becomes part of both families:

      flowchart TD
        subgraph All["All default families"]
        subgraph A["Access family"]
          Forget[["Forget (default)"]] -- extends --> Leak
          Leak -- extends --> Destruct
          Destruct -- extends --> Access
          Move[["Move (default)"]] -- extends --> Access
        end
      
        subgraph S["MaybeSized family"]
          Sized[["Sized (default)"]] -- extends --> MetadataSized
          MetadataSized -- extends --> MaybeSized
        end
      
        Access -- extends --> Value
        MaybeSized -- extends --> Value
        end
      

      Then you can do T: only Value and opt out from both families at once.

      If we did that, what would happen if we wanted to add a new family in the

      future?

      Ay, there's the rub. If we wish to add a new family in the future, let's say for values that don't live in the same memory space (T: only Distributed…?), then Value would be "out of date" because code written against Value would still be assuming uni-memory-space values. But we could make Value into an edition-dependent alias or something like that, as has been discussed.

      Can we decide whether we want Value later?

      Yes! We can introduce a root trait at any time. So we can add the Sized-ness family first, then the Access family, and then see how we feel. Maybe we find people are very commonly opting out of both- in which case, some aliases are useful, or perhaps a Value variant.

      The only way we might "regret" it is if, in practice, people usually just opted out of both and then opted back in to what they want specifically. But we already know that T: only Move will be common and clearly T: only Value + Move + Sized is more awkward in that case, so I don't consider that very likely.

      Why the name Destruct and not Drop?

      That name comes from the const trait RFC. There are a few reasons to move away from Drop. The first is that it is possible to have a destructor even if you don't implement Drop: Drop really refers to user-provided logic in the destructor, but the compiler adds its own logic ("drop glue", it's sometimes called) to drop all the fields in the value. The second reason is that the Drop trait itself needs some revision, so moving away from that name lets us have other ways to specify custom logic (e.g., pinned self, or by-value, etc etc).

      How does this interact with const traits anyway?

      Quite beautifully! In fact, the proposal from Arm for SVE is to introduce the idea of T: const Sized being "a type whose size can be computed at compilation time", which I find quite elegant. Similarly T: const Destruct was proposed by the const RFC as a way to say that a value has a constant destructor.

      It's annoying to write T: only Move + Destruct. Couldn't we have

      Destruct imply Move so that I can just write T: only Destruct?

      My original proposal for introducing linear types had Destruct extending Move. This would mean that the Option::or proposal could simply do U: only Destruct and not U: only Move + Destruct. However, Alice Ryhl and others pointed out that there are immovable types that must nonetheless be destructed, so it doesn't make sense to combine those.

      Where can I learn more?

      The Project Goal has a lot of details. The latest updates are available on the tracking issue. If you like watching videos, I recommend David Wood's Rust Nation talk.

      Conclusion

      I want to close with a meta-observation and a big shout-out to the Arm team. I think they are showing how awesome open-source can be. The Arm team's primary motivation is adding support for Scalable Vector Extension. This helps Rust make full use of Arm processors. This is, in and of itself, a laudable goal, and valuable to Rust: One of Rust's assets, in my view, is that it gives you access to all the power your processor has to provide, and that should include unique extensions.

      But rather than add the feature as a kind of special-case extension to Rust, the Arm team is going further and driving a general purpose improvement, one that will unlock a bunch of other features (extern types and, to some extent, guaranteed destructors; guaranteed destructores themselves unlock scoped async threads and better Wasm integration). I love that.


      1. In fact, I recall that in one of my blog posts I proposed writing "" as the way to spell &str. I kinda wish we had done that just for the sheer wackiness of it (fn foo(name: "")). ↩︎

      2. I prefer names that refer to the operations that can be performed on the values, so e.g. instead of MetadataSized I would prefer SizeOfVal, since it means that you can invoke the std::mem::size_of_val function on it. ↩︎

      3. Little logic pun there for you. ↩︎