Wait, Who's This "Ryan" Guy? Where's Pat?

If you prefer words, Don Boudreaux supplies them in a tsk-tsk LTE to the WSJ: Trump's Tariffs Are Paid Overwhelmingly By Americans.

You’re correct that the U.S. economy is now showing signs of the inevitable damage done by Mr. Trump’s tariffs (“The Trump Economy Stumbles,” August 2). Yet some of your wording carelessly grants too much to the administration’s case for protectionism.

You write that “much of the world will now pay 15%, if Mr. Trump sticks to his deals.” Not so. Because – as the evidence shows – pre-tariff import prices aren’t falling, what you mean is that Americans will now pay 15% for imports from much of the world.

It’s therefore inaccurate also to say, as you do, that failure of other countries to retaliate with tariffs of their own means that “that these countries seem willing to absorb the 15% tariff.” These countries are indeed willing to absorb the shrinkage of their U.S. markets rather than risk the further shrinkage that a trade war would cause. But because the president’s tariffs are paid by Americans, the people who are ‘absorbing’ the bulk of the tariffs aren’t foreigners but, rather, American firms and households who are paying the higher prices.

If you need it, here's a gifted link to the editorial with the language Don proposes fixing.

Also of note:

  • Oh, Happy Day. There's plenty of gloating among the libertarian/conservative sites, but let's not wallow, Ars Technica has the sads: RIP Corporation for Public Broadcasting: 1967–2026.

    Despite the protests of millions of Americans, the Corporation for Public Broadcasting (CPB) announced it will be winding down its operations after the White House deemed NPR and PBS a "grift" and pushed for a Senate vote that eliminated its entire budget.

    The vote rescinded $1.1 billion that Congress had allocated to CPB to fund public broadcasting for fiscal years 2026 and 2027. In a press release, CPB explained that the cuts "excluded funding for CPB for the first time in more than five decades." CPB president and CEO Patricia Harrison said the corporation had no choice but to prepare to shut down.

    "Despite the extraordinary efforts of millions of Americans who called, wrote, and petitioned Congress to preserve federal funding for CPB, we now face the difficult reality of closing our operations," Harrison said.

    Concerned Americans also rushed to donate to NPR and PBS stations to confront the funding cuts, The New York Times reported. But those donations, estimated at around $20 million, ultimately amounted to too little, too late to cover the funding that CPB lost.

    Translation of that last paragraph into reality: "Concerned Americans" turned out to be not Concerned enough.

  • Not to worry, Uncle Stupid still knows how to waste money. Rand Simberg describes Why And How To End SLS Now.

    "SLS" is NASA's "Space Launch System". Rand shares three links:

    Zimmerman has the most withering commentary. Quoting from that:

    Increasingly it appears everyone in Congress, the White House, and NASA, as well as our bankrupt mainstream press, has become utterly divorced from reality in talking about NASA’s Artemis lunar program. The claims are always absurd and never deal with the hard facts on the ground. Instead, it is always “Americans are piorneers! We are great at building things! We are going to beat China to the Moon!”

    An interview of interim NASA administration (and Transportation secretary) Sean Duffy yesterday on the Sean Hannity Show made all these delusions very clear. First Hannity introduced Duffy by stating with bald-faced ignorance that “NASA has a brand-new program. It is called Artemis that aims to get astronauts back on the Moon in the next couple of years.”

    I emphasize “brand-new” because anyone who has done even two seconds of research on the web will know that Artemis has existed now for more than a decade. Hannity illustrates his incompetence right off the bat.

    I've been a space fan for a long time. I watched the Sputnik I upper stage fly over the Oakland, Iowa football field back in 1957. Didn't like the commies even back then, but… pretty cool!

    But it would be nice if US space exploration could be less "delusional".

  • I resemble this remark. Jay Nordlinger may be picking up my psychic emanations: A President in Every Pot, &c.

    President Donald Trump is a busy beaver. There are many things a president must do, as a matter of course. But this one also wants the Cleveland Guardians to become the “Cleveland Indians” again. And the Washington Commanders to become the “Washington Redskins” again. And Coca-Cola to use cane sugar instead of whatever it is the company uses. Etc. Trump is very active on these fronts.

    I share his opinion, in some of these cases. (Not sure about “Redskins.”) But, you know? A president ought not to involve himself in every nook and cranny of American life. He is not a national boss or nanny. There should be a private sphere, an apolitical sphere, a non-governmental sphere.

    Conservatives taught me this long ago. They were right, I believe (as about virtually everything.) I cannot unlearn what I learned, and accepted, years ago. That is a big reason I’m out of step with the regnant Right today.

    Yeah, me too.

  • Mixed metaphor in Aisle 2. At Reason, Tosin Akintola notes that our fair state is failing to live up to our LFOD motto: New Hampshire’s new booze law will hamstring the state's brewpubs.

    The rationale behind New Hampshire's new brewpub regulation is more headache-inducing than the beer.

    On Friday, New Hampshire Gov. Kelly Ayotte (R) signed House Bill 242 into law. The bill, sponsored by state Rep. John Hunt (R–Rindge), will take effect in August and limits brewpubs in the state to self-distributing their beer to only one additional restaurant or business outside their premises. The bill is a follow-up to H.B. 1380, also sponsored by Hunt in 2024, which limited the amount of beer or cider a brewpub could sell to 2,500 barrels a year and permitted licensed brewpub owners to obtain licenses to sell their product on their premises in bars and at off-premise locations like grocery stores, so long as they didn't have a manufacturing license.

    If the law sounds like it will keep brewpubs small, that's because it's intended to do so. "This is what we call a very inside baseball bill," Hunt told the New Hampshire Bulletin.

    "Inside baseball" means (I think it's fair to say) that insiders wanted to make sure they wouldn't have to deal with upstart competition.

Claude, You Magnificent Bastard, I Didn't Read Your Book

[Amazon Link]
(paid link)

Introduction/Rationale

Some readers may have noticed me griping about my blogging "infrastructure" a few weeks ago. To repeat and summarize: One of the bits of code I relied on was a Google Chrome extension called chromix-too. It did something I found incredibly useful: allowed access to Chrome's "tabs" API from the Linux command line. It was also quite powerful, but I only used it for four relatively simple things:

  1. Tell me how many tabs I have open;
  2. Tell me the URL of the active tab, and the title of its rendered page;
  3. Open a new inactive tab to a specified URL;
  4. Open a new active tab to a specified URL.

Granted, the last one is easy without an extension. The others don't seem to be, "as far as I can tell."

Alas, chromix-too used some features that Google deprecated years ago. It had a V2 manifest, and maybe violated other guidelines. And Google promised/warned that it would just stop working eventually.

And, as noted, "eventually" turned out to be "a few weeks ago". An upgraded Google Chrome refused to load chromix-too.

The author of chromix-too seemed uninterested in updating his code. I didn't press him about it.

I toyed with bringing it into compliance myself. Unfortunately, it was in Javascript, and even though it was but a few thousand bytes, I found it totally impenetrable. My efforts were feeble and futile.

But I had heard that AI tools, specifically Claude, could write code for you. A little Googling showed the "right way" to do what I wanted was via Chrome's Native Messaging facility. Which led to my Claude prompt:

I want a Chrome extension using Native Messaging to access the chrome.tabs API from the Linux shell.

And it worked. Kind of. Source is at GitHub.

Caveat

When I say "kind of", I'm not kidding. If you play with this yourself, be aware there's a bug that I haven't fixed. Described, with my workaround, at the end. I'll edit this if I ever fix it. Geeky readers, please let me know if you spot the problem.

The Overall Idea

Command Line HTTP Server (7444) Native Host Chrome Extension Chrome APIs

Claude provided the code to go in the middle three boxes.

Code Details

  • Command Line: you use an HTTP client (I use curl) to talk to the HTTP server which is listening on localhost port 7444. (That's the port chromix-too used to listen on.)

  • HTTP Server: A small (8779 bytes as I type) Python script that interprets the HTTP commands received from the command line and translates them into appropriate API code.

    Its filename is chrome_api_bridge.py, and I installed it in /usr/local/bin

  • Native Host: A JSON file that serves as a bit of glue between the HTTP server and the actual extension. It's very small (243 bytes), named com.chrome.api.bridge.json, and in LinuxLand it goes in the directory $HOME/.config/google-chrome/NativeMessagingHosts/.

    Note for those trying this at home: you have to fill in the ID of the chrome extension in this file. Which you won't know until you install the extension, which is…

  • Chrome Extension: A group of four files in their own directory:

    • manifest.json The extension's JSON manifest (duh);
    • background.js … and the extension's JavaScript code
    • popup.html and popup,js … I don't use these, but Claude provided them.

Installation Details

I think you should do things in this order. Sometime next month I will be installing Fedore 43 from scratch, and if I get anything wrong here, I'll amend.

Assuming you have Linux running and (specifically) Chrome installed normally…

  1. Install the extension. Point your browser at chrome://extensions; turn the "Developer mode" toggle on; click the "Load unpacked" button; in the resulting dialog, highlight the directory containing those four extension files, and click "Select".

    Copy the 32-character ID you should now see in your new extension's box.

  2. "Register" the Native Host. Edit the file com.chrome.api.bridge.json, pasting that 32-character ID string into the obvious place under the allowed_origins key. Put this file into the directory $HOME/.config/google-chrome/NativeMessagingHosts/.

  3. Install the HTTP server script. As stated above, I used /usr/local/bin/chrome_api_bridge.py. You can probably install it anywhere you want, but you'll have to change the path in the glue file installed in the previous step.

  4. Try it. Return to the chrome://extensions tab and turn the extension on. And (assuming nothing obviously bad happened) proceed to…

Examples

How do I count Chrome's open tabs? I give the command:

curl -s http://localhost:7444/chrome/tabs/query

This gives JSON output, which I parse, The "result" key has an array value, and the number of items in the array is the number of open tabs. A complete Perl script:

#!/usr/bin/perl

use strict;
use warnings;
use English qw( -no_match_vars );
use JSON;
use version; our $VERSION = qv('v2025.07.31');

my $curl_cmd = q{curl -s http://localhost:7444/chrome/tabs/query};
open my $CTQ, q{-|}, $curl_cmd or die "Failed to run curl command: $ERRNO\n";
my $ctq_json = <$CTQ>;
my $status   = close $CTQ;
my $decoded  = decode_json($ctq_json);
printf "Chrome open tabs: %d\n", scalar @{ $decoded->{'result'} };

Similarly, the command

curl -s http://localhost:7444/chrome/tabs/getCurrent

… just gives a one-element "result" and the current tab's URL and title are easily parsed out.

Opening a tab uses a POST:

curl -s -X POST http://localhost:7444/chrome/tabs/create -H "Content-Type: application/json" -d '{"url": "https://reason.com/latest", "active": true}'

That brings up the specified URL as an active window. Bringing it up as an inactive window… is left as an exercise for the reader.

That Darn Bug

Things should "just work" after starting Chrome. They do not. My extension throws an error:

Unchecked runtime.lastError: Native host has exited.

The workaround, which I arrived at after a few hours of trying everything else, is (I am not kidding):

From the chrome://extensions page:

  1. Turn the extension off.
  2. Turn it back on.

And then things seem to work fine.

This is puzzling.

When I Google that error message, all the "fixes" seem to assume a persistent error, that things aren't working at all. Nothing about problems fixed by "turn it off, then back on." So I'm stumped for now. Again, let me know if you happen to spot the problem.

I haven't tried asking Claude.

(Headline adapted from a classic movie.)


Last Modified 2025-08-02 10:48 AM EDT