Hacker News new | past | comments | ask | show | jobs | submit login
TabFS – a browser extension that mounts the browser tabs as a filesystem (omar.website)
1033 points by pps on Feb 18, 2023 | hide | past | favorite | 193 comments



If you're on macOS, you can do a small piece of this natively with AppleScript (or anything that can send apple events) in Chrome or Safari -- namely, you can iterate through windows or tabs, view their source code, and execute arbitrary javascript you pass (there's a one time security option you have to accept). This can be handy for quick automations if you don't want to install anything.

(Background: I have RSI, so I've been developing some integrations between applications and Talon Voice (https://talonvoice.com/). AppleScript ends up being surprisingly valuable/fast/reliable for applications that support it. I also built an integration with iTerm2's Python API before noticing that everything I was trying to do was already supported by its AppleScript dictionary, and was faster. In Google Chrome, the "iterate through tabs and execute javascript in them" is very useful for automating Google Meet muting/unmuting.)

Nothing against this excellent project though; I'm a big fan of Omar's Twitter! And I suspect most here will appreciate the easier scriptability of the filesystem approach than dealing with the atrocious syntax of AppleScript.


You don’t need to write AppleScript yourself, someone else has already done the hard work with Scripting Bridge and you can simply enjoy an easy-to-use CLI: https://github.com/prasmussen/chrome-cli

Been using this for about a decade now.


interesting, what are your use cases?


Safari, not Chrome, but here's an AppleScript I use to map a trackpad gesture to the "next page" link on a wide variety of Web sites,

    tell application "Safari" to do JavaScript "
        (() => {
            const loc = Array
                  .from(document.querySelectorAll('[rel=\"next\"], .next, [title=\"Next page\"]'))
                  .map(i => i.getAttribute('href')).filter(i => i)[0];
            if (loc) {
                document.location = loc;
            }
        })()
    " in document 1
s/next/prev/g s/Next/Previous/ for the matching "previous page" script.

Note that this requires Safari's "AllowJavaScriptFromAppleEvents" preference to be set, either via a "Develop" menu option or directly in its preferences file via, e.g., the

    defaults write com.apple.Safari AllowJavaScriptFromAppleEvents -bool TRUE
shell command, and that this setting allows any program you authorize[1] to send Apple Events to Safari to potentially do Terrible Things. Given that the setting is both disabled and hidden by default, and additionally gated by an opt-in privacy preference, it's presumably an unlikely target for garden-variety malware, however.

[1] Check the Automation group in the Privacy tab of the Security & Privacy preference pane for a list of programs so authorized.


I can’t answer that question exactly because that’s driving Chrome, but I wrote an AppleScript the other day to make zoom less dreadful.

I annotate on screens all day and there are no useful shortcuts for moving between drawing and erasing. Also the drawing button requires 2 clicks. I’ve wired my wacom tablet so the two buttons fire off shortcuts, they run a service I’ve registered in the menus, they run the applescript, it fishes about for the right windows in zoom and clicks the buttons. It could not have worked but it just happens to because I can trigger a button and then focus moves to the next button (which I can’t otherwise target) and then I can push “space” to get the job done.


Here’s one of the scripts if anyone wants to see how weird it all is.

    tell application "System Events"
    repeat with theProcess in processes
        if not background only of theProcess then
            tell theProcess
                set processName to name
                set theWindows to windows
            end tell
            set windowsCount to count of theWindows

            if processName is "zoom.us" then
                repeat with theWindow in theWindows
      tell theWindow
   set theSize to size
                        set windowName to name
      end tell
                    if windowName is "annotation panel" then
                        if item 1 of theSize is 776 then
                            tell theWindow to tell button 5 to click
                            key code 49
                        else
                            tell theWindow to tell button 4 to click
                            key code 49
                        end if
      end if
                end repeat
            end if
        end if
    end repeat
    end tell


If I were you I would find out which “RSI” you have. Mine wasn’t from “overuse” per sé, just posture and needing to stretch/exercise.

If your RSI is Carpal Tunnel or Cubital Tunnel Syndrome, a quick and easy surgery is the answer.

If your RSI is tendinitis (unlikely, for all the times I see people self-diagnose with it) rest is your best bet.

If your RSI is arthritis, there are medications and even surgeries out there to help with it, but that’s the easiest one to diagnose because it just requires looking at an x ray of your hand.

You may have carpal tunnel syndrome-like symptoms, but that likely just means you have nerve impingement somewhere between your cervical (neck area) spine and your hand.

I’m not a doctor, but through personal experience I can tell you, you probably have the power to get rid of your “RSI” without resorting to dictation software and so on.


Regarding stretching, I found the book Conquering Carpal Tunnel Syndrome to be a huge help. It has lots of suggestions for kinds of stretches to do based on the kind of work you do, but my big takeaway (and according to the author, the most important part) was how to do the stretches: only stretch until you barely feel a stretch, then hold there until you feel a sense of release. In my experience that was more effective than the “stretch until you feel a good strong stretch” strategy.

https://www.amazon.com/Conquering-Carpal-Syndrome-Repetitive...


I have a copy of this which I no longer need. If anyone in Australia wants it hit me up and I'll mail it to you. @johnnydecimal@hachyderm.io.

FWIW -- I know this isn't an RSI thread -- mine was 100% fixed by changing my desk. It was too high, and my classic 5-wheeled office chair was unstable. I lowered the desk to about 68cm (I'm 172cm) and bought a chair with wooden legs (Ikea, ~$80), started doing light stretches in the morning, and that fixed it for me.

I made the desk from Ikea cabinets and a $100 plain wooden door. So it's a) cheap, b) massive, and c) I can screw things in to the underside.


I significantly reduced the symptoms of my carpel tunnel by changing from a normal height mechanical keyboard to one with slim key caps. I really miss my Das Ultimate but the difference is really noticeable.


Aah yep, I also had a Das, and the Filco Majestouch 2. Beautiful keyboards. Sold 'em.

Now I use the very-average Microsoft Sculpt Ergonomic. Low keycaps, low travel. And of course a split layout.

Do not use the execrable MS mouse that comes with that keyboard. I love the MX Anywhere series, I currently use a 2 and a 3. They're light, so you can nudge them round with your fingers without having to move your arm too aggressively.


Ah yes I know that keyboard - mine is a Keychron K2 V2 with optical switches. It's decent to type on but I miss having a volume knob and proper function keys.

I find it really helps not having the number pad - it means my mouse can be closer to the keyboard so my wrists are straighter.

For a mouse I use a MX Master 3 which I'm very happy with.


I tried an MX Master 3 and 2S, I also have the MX Ergo trackball mouse and the Logitech vertical mouse. The vertical mouse is what I ended up with, but for years I would switch mice, switch between several mice within a day, switch hands - and they were all half-measures that just kind of delayed the "degeneration". The issue, it would seem, was not the mouse or overusing the mouse. The issue seems to have come from my shoulder area (Thoracic Outlet Syndrome aka TOS / Pec. Minor Syndrome), which a vertical mouse will uniquely address as it allows your shoulder to be less interiorly-rotated than a standard mouse, even a trackball mouse that is not vertical.

I remember reading a Medium article a while ago about a software engineer who described how he addressed his "RSI", which I suspect was just TOS - he switched to an ergonomic keyboard and vertical mouse, which over a period of MANY MONTHS more or less resolved his RSI. He talked about how he still has to be careful and take breaks often. I really think, especially considering his age (20s), he could have kept the mouse and keyboard he had, if he just engaged in posture-correcting shoulder stretches and strength exercises.


I tried the Master but found it a tad large. As above, I'm not a ginormous person: 172cm (5' 8", just), 70kgs. I don't have huge hands. I found pushing round the Master to be a bit too much work, which sounds preposterous but ¯\_(ツ)_/¯.

The Anywhere is just smaller, lighter. More nimble.


Interesting! I like my mouse to be as heavy has possible, I find it more preside and exacting.


I also use an MX Master (2S), and wish I would have switched sooner. It can connect to 3 devices (via Bluetooth or USB receivers) with a button on the bottom to switch, and an “infinite” scroll wheel with multiple modes, which is awesome!


Any experience with low-profile mechanical keyboards, seems like a potential compromise between something like the Das, and the microsoft sculpt?


No, I wasn't aware of any.


My personal trainer told me the same- you won't gain flexibility by "forcing" the stretch, only by stretching just beyond where the muscle wants to stop, holding it there for around 30 seconds (and you should feel a "release"), and repeating the next day.


+1

This is solid advice! I had "RSI" for years (could barely type or write) and in the end what solved everything were exercises to improve my posture and strengthen my back, neck and shoulders.


There's a lack of awareness too - I saw three orthopedic surgeons and one neurologist and none asked me about, mentioned, or tested me for Thoracic Outlet Syndrome (which is likely what you had based on what fixed your symptoms). I only learned about TOS myself after they ruled out Carpal Tunnel Syndrome and going back to Google to try to find what could be causing CTS symptoms other than CTS.


> Thoracic Outlet Syndrome (which is likely what you had based on what fixed your symptoms)

Sounds about right. Nice to know there's a name for it!


Shameless plug: I've made a set of AppleScripts I call "Tab Transporter" for moving groups of tabs between browsers. The code is painful to write when you're used to a normal programming language, so these examples could be useful for anyone else looking to interact with browser tabs via AppleScript.

I've used them daily for 5+ years.

https://github.com/tedmiston/tab-transporter


Funny, I do similar [1] though my solution is very basic compared to yours. The script allows me to quickly move the current tab from Firefox or Safari to Arc Browser [2] (which uses Chrome under the hood).

I use the following key-bindings ⌥⌘F or ⌥⌘S in Raycast [3] to activate a tab move to Arc from Firefox or Safari, respectively.

1: https://github.com/ayewo/raycast-script-commands/tree/main/b...

2: https://arc.net

3: https://www.raycast.com/


Nice, thank you!


I used to scan all the tabs in open browser windows to list all URLs.

See also https://chromedevtools.github.io/devtools-protocol/ with Playwright et al., even Excel VBA: https://github.com/PerditionC/VBAChromeDevProtocol

Many sites fight against automation, see https://github.com/ultrafunkamsterdam/undetected-chromedrive...


Just to show folks how simple this is, here's the JavaScript (JXA) version of the AppleScript code needed to run JS in the current active tab:

   /usr/bin/osascript -l JavaScript <<EndOfScript
      var current_tab = Application('Google Chrome').windows[0].activeTab();
      current_tab.execute({  javascript: 'alert(1)'  })
   EndOfScript
Once you figure it out it's not too tricky. For example, I have shell utils for converting all links on a page to "in current tab links" by removing the `target` attr on <a> tags:

    function chromeJS() {
       INPUT="$1";
       INPUT=${INPUT//\"/\\\"} ## escape quotes
       INPUT=${INPUT//\'/\\\'}
       /usr/bin/osascript -l JavaScript <<EndOfScript
          var current_tab = Application('Google Chrome').windows[0].activeTab();
          current_tab.execute({  javascript: '$INPUT'  })
    EndOfScript
    }
    ...
    $ chromeJS "document.querySelectorAll('a').forEach(a => a.removeAttribute('target')); alert('Made all links in-tab links!')"


"If you're on macOS, you can do a small piece of this natively with AppleScript (or anything that can send apple events) in Chrome or Safari -- namely, you can iterate through windows or tabs, view their source code, and execute arbitrary javascript you pass (there's a one time security option you have to accept). This can be handy for quick automations if you don't want to install anything."

Are there any good examples of doing this?


sure, for example this pauses every youtube video in every chrome tab: tell application "Google Chrome" repeat with theWindow in every window repeat with theTab in (every tab of theWindow) if (URL of theTab) contains "youtube.com" then execute theTab javascript "document.querySelectorAll('video, audio').forEach(e => e.pause())" end if end repeat end repeat end tell

There are lots of examples just by googling. The script editor has a dictionary for every application you can natively script.



Interestingly, all the AppleScript functionality is built on an objective-c api called ScriptingBridge and it’s relatively easy to use a real programming language for the same sorts of things. JavaScript is natively supported by Script Editor, but there’s bindings for Ruby and Python too. I’ve wrapped it up in Common Lisp for my own use: https://github.com/fiddlerwoaroof/objc-lisp-bridge/blob/mast...


Love to hear more about this. I also suffer from RSI and would love to know if it’s helped changing input to voice


Have you got any suggestions for coping with RSI? I'm having significant issues.


If you're programming, definitely check out Cursorless: https://www.cursorless.org/.

Talon itself provides noise and speech recognition, and provides the framework that allows you to build automations with any program; Cursorless really helps make programming by voice feel comparable to typing.

For me, it's a combination of introducing alternate input methods (largely voice, but noises are also very additive -- they very well for fast/discreet actions, whereas voice is higher bandwidth but lower latency), as well as building higher-level and better integrations with applications. But I still have always to go personally.

I've been meaning to write up a blog post with everything that I've learned, but you know how it is :)


Edit: I meant to say that voice is higher bandwidth _and_ higher latency, not lower.


+1 on that blog post!


Have you tried a book on the mind body connection of pain? It helps some people with RSI: https://www.amazon.com/Healing-Back-Pain-Mind-Body-Connectio...


That’s also how I got rid of my RSI.

Once I ended that one bad relationship in my life, my mind stopped messing up the most used part of my body to send me signals that I’m actually chewing on life’s gristle.

My wrists have been pain free for 15 years. Without surgery. Without therapy. Without a change in work hours.


It's all about hardware. I've addressed it quite well with a three-pronged approach:

1. Motorized standing desk - typing from varying postures keeps strain spread out

2. Kensington trackball mouse - less hand sweeping / temptation to drags wrist on table

3. Ortholinear "Planck" keyboard - modifier keys accessible via thumb and programmable layers more generally can completely eliminate painful hand poses and keep fingers on the home-row


Change is good. I find using a variety of mice helps. Rollermouse, trackpads, rockmouse, carpal tunnel mouse(quadraclicks), mousetrapper.

For the dragging wrist problem, I really like the reloot or other similar gliding palm rests. I find upgrading them with ceramic lights makes a big difference.


Personally I find the Kensington trackball mouse made my carpel tunnel a LOT worse, they're not for everyone.


With my particular RSI I also can't use a standard trackball, but I swear by my thumb trackballs. (But every body is different, every injury is different, etc.)


The Kinesis Advantage 2 keyboard fixed mine. I also use a Logitech trackball instead of a mouse.


Devote a 4 digit budget for a new workspace that relieves RSI causing movements.


You don't need to spend that much. I mean, go for it, it sounds fun, but just getting a desk the right height (i.e. probably lower than it is now) and a stable chair solved mine. See sibling comment here.

https://news.ycombinator.com/item?id=34852007


Split vertical keyboards with very very light switches. I use Sofle Choc and have the sides at shoulders width apart

I recommend breaks and rest over strengthening exercises when dealing with hand pain. Learn preventative measures


If you had told me in 1992 when AppleScript was first introduced that it would be around for over 30 years across three processor transitions, I would not have believed you.

Now they just need to bring back QuickDraw GX, OpenDoc and PowerTalk (please don’t for all that is holy)


I wish I could just visit about:tabs and see a plain text listing, one URL per line, of all the tabs I have open.

No esoteric attack vectors, no major new features or integrations, just a quick and easy way for any user regardless of technical ability to dump their tabs before they update firefox or reboot their system ...

... since everyone has been burned by a FF restart that, for unknown reasons, fails to restore tabs even when configured properly to do so.

As it stands, you need to dig several directories deep into /Library (or whatever, depending on your OS) and then use JSON tools to export ... I've already lost most people.

FWIW, rsync.net has an outstanding $1500 bounty for this feature[1]. Consider this an inflation adjusted bump to $2500.

[1] https://news.ycombinator.com/item?id=24524923


I have a extension that does that almost pretty identically to what you are looking for... it does list out every page you have but doesn't list the url. there is an unreleased version that I use that has a tab dumping to json that I use for just that session restore reason.

Maybe I'll finish the updated version and release it soon.

feel free to check it out: https://github.com/fiveNinePlusR/tabist

https://addons.mozilla.org/en-US/firefox/addon/tabist/

https://chrome.google.com/webstore/detail/tabist/hdjegjggiog...


Firefox's session is stored entirely within sessionstore.jsonlz4 in the profile folder (and backups, or while running, in sessionstore-backups) -- locate using about:profiles. It's a nonstandard lz4 container but you can find implementations, e.g. lz4json/lz4jsoncat in some package managers.

Once decompressed you have json lists of windows of tabs, including recently closed; for every tab, urls and titles of each entry in per-tab history, base64ed favicon, last selected time, and various less useful data (some still incomprehensible -- binary serialized or cache keys?). Cookies and data from extensions like treestyletabs are in there too.

OTOH... is there a currently working deserializer for Chrome's session files?


Indeed! Dumping this recovery.jsonlz4 file on the command line is how I inspect and archive all my tabs and windows. You can do this on remote systems, too, and Firefox does not need to be running.

The scripts I use to do this can be found here:

https://github.com/madphilosopher/dump_firefox_session


> ... since everyone has been burned by a FF restart that, for unknown reasons, fails to restore tabs even when configured properly to do so.

I've actually had this several times with Chrome, but never with Firefox. The major point of me moving to FF actually was when Chrome lost 50 Tabs once again.


Firefox reliably remembers my tabs, but never my pinned tabs-- which, of course, are the ones that I actually want to be preserved across restarts. In my dream world, pinned tabs persist forever, and are even accessible across devices, perhaps sorted into separate containers à la Sideberry.


I just use Tree Tabs ability to export the entire sessions tabs.

My work laptop has around 30MB of old Tree Tabs exports I haven't gotten around to deleting.

https://addons.mozilla.org/en-US/firefox/addon/tree-tabs/


With Sidebery (modern alternative to TST), the tab tree is automatically backed up every $time_interval.

https://addons.mozilla.org/en-CA/firefox/addon/sidebery/


I built [1] for the reason to save and restore the browsing tabs. It has export and import sessions feature as a by product. [2] also has a test list mode on tabs.

[1] https://addons.mozilla.org/en-US/firefox/addon/session-boss/

[2] https://addons.mozilla.org/en-US/firefox/addon/tip-tab/


Thanks - I will look at these.


https://addons.mozilla.org/en-US/firefox/addon/tabhunter/

Makes it simple to select all tabs and copy paste as url or url + title

It's also snappy for filtering and jumping to tabs especially when using the hotkey, I've used it for years with regularly over 5k tabs.


> wish I could just visit about:tabs and see a plain text listing, one URL per line, of all the tabs I have open.

Tablist[1] does this

[1]: https://addons.mozilla.org/en-US/firefox/addon/tablist/


Great takedown in the linked thread. jhardy54 snarks that the author just needs to open a patch. When rsync presses, it turns out jhardy54's own patches have been completely neglected by the maintainers and he hasn't been able to merge them in.


Onetab does it, and lets you export your links as a text file as well.


about:discards is almost this. (Chromium desktop)


I use a deeply modified fork of this every day. My changes have been:

1. Rewrite the backend in Go (I'm nkt qualified to audit the C version, and having Web Stuff™ interact directly with an unaudited C filesystem daemon makes my skin crawl)

2. Modularize it quite a bit to make it easier to add endpoints like...

3. Rudimentary Tree-Style Tabs support

4. Desperately try to improve the performance enough to navigate a sizable session (I have not yet succeeded)

Even after all this, I've come to the conclusion that the relationship is backwards: the filesystem representation needs to drive the browser, not the other way around.

It's my considered opinion that some hero needs to step up and build a browser that exists to render one tab and nothing else, shelling out for everything more complex than scrolling. Then the power users cwn supply their own tab/bookmark/window/filesystem schemes using whatever glue they prefer, be it python, node, shell scripts, Windows Explorer...


As alluded in the post, we should all have switched to Plan 9 decades ago. Everything behaves like a file, which means you get a mountpoint for web stuff (https://man.9front.org/4/webfs), and use another application that reads and writes files on top of that (https://man.9front.org/1/mothra).

I fear the current web is too complicated for that. All hope is lost, the web cannot be salvaged.


> It's my considered opinion that some hero needs to step up and build a browser that exists to render one tab and nothing else, shelling out for everything more complex than scrolling. Then the power users cwn supply their own tab/bookmark/window/filesystem schemes using whatever glue they prefer, be it python, node, shell scripts, Windows Explorer...

That's basically uzbl. The core version has no tabs, no bookmarks, no history, and is extensible in whatever language. Seems it's been abandoned, though.

https://www.uzbl.org/


* > It's my considered opinion that some hero needs to step up and build a browser that exists to render one tab and nothing else, shelling out for everything more complex than scrolling.*

Is that not what your OS's 'native' web view API is?


Would suckless surf fit that bill?

https://surf.suckless.org/


What I want is foobar2000 + meets browser (decoupled renderer/chrome/css engine/javascript runtime/plugin system etc)


Is your fork opensource? If so, would you mind giving a link?


Yes, see the sibling comment, and for the love of all that is holy, heed the warnings. Use it at your own peril, and even then with caution and distrust.


I just moved my bookmark management out of my browser because I wanted to use unix-y tools to deal with them. CLI instead of a GUI afterthought. I think you're absolutely right. I'd love to access browser history at CLI. And management of open tabs.

Care to share your fork? Go works better for me.


FUSE proxy: https://gitgud.io/ee/gtabfs WebExtension: https://gitgud.io/ee/tabfs

Caveat _extremely_ emptor: This code works on my machine, and I have no recollection of how it came to be that way. There are undoubtedly bugs, both obvious and subtle, in both halves. The Go side is a pile of garbage (in no small part because of the countless interfaces it has to implement).

It is EXTREMELY unlikely that either the server or extension is compatible with its original counterpart. The filesystem layout itself has been reorganized more along the lines of /sys conventions.


Could you expand a bit more about your bookmark management strategy?


It's not particularly deep or thoughtful, I just realized that the browser interface is not a good place to manage a large list of links. Almost anything else is better. I have tried a few different browser-based bookmark management tools, and they have always been lacking somehow.

I started using Obsidian recently, so I am moving my bookmark archive into there. It's neat because you can right-click>copy a bookmark folder, then paste into Obsidian as markdown links, with the page title as the link text (I think it's Firefox doing this, but not sure. I had to get a "copy as markdown" extension for Chrome). I also use the multi-select "bookmark tabs" feature, and Firefox Sync to move tabs between devices. These three things in combination enable me to make closing tabs a regular, routine thing, because I now know that I can find them again when I need them. Instead of going into the black hole of my bookmark toolbar, they go into an Obsidian vault, a single folder full of markdown files. This means I can use my normal CLI tools and text editor (keyboard instead of mouse is a big part of the appeal here) to search, sort, and organize things.

The detailed organizational principles vary based on the purpose of the bookmarks, and I think that's mostly a personal thing. I don't have some sort of well-defined technique, but for example I now put the "project research link dump" into the "project notes file" (where it obviously belongs, but I was too lazy to do this previously). I have a few different "optimistic learning links" lists, like one for productivity software tools, which I might randomly browse when I have some down time at work. Another for interesting-but-not-important-for-work videos on math, physics, CS.

Now, instead of thousands of links and hundreds of folders, my bookmark toolbar can be used for just a handful of "webpages that I use frequently" - the intended purpose of the bookmark toolbar, as far as I can tell.

Well, now I want to expand on this a bit in a blog post, but I'll have to come back to that.


Thanks! That's cool, I'm taking inspiration


At that point it's just an OS.


That's a good point. Browsers are desktop environments with a built-in application runtime. Maybe it's the "Inner-platform effect."

It's an interesting idea to pull bits of the browser back into the system, or alternatively to write a desktop environment that's also a web browser (ChromeOS?).

A former coworker used Plan9 at a previous job, and he said it was cool how you could draw a rectangle on part of a terminal, and pipe that text (as it changes) to another process. Maybe rethinking GUI (and web in particular) from a unixy/plan9y perspective is a worthwhile exercise.

I grew up on Windows, and then there was the browser, and now everything is just the browser.


Too bad firefox doesn't allow it's users to install extensions without their approval and this extension can only be installed temporarily.

>in Firefox You'll need to install as a "temporary extension", so it'll only last in your current FF session. (If you want to install permanently, see this issue: https://github.com/osnr/TabFS/issues/4#issuecomment-75344738...)


This was the straw finally pushing me to very seriously consider migrating to Chromium. They seem to absolutely despise power users, they pull the same type of shit with Fennec/Fenix.

They hate their users so much they're perfectly willing to compromise their security. "This extension is not actively monitored by Mozilla". But you can't do the responsible thing and build it from source yourself.

Even installing the "Developer Edition" didn't enable to me to install self-built extensions (yes, with that secret flag). And it doesn't even tell you that it doesn't accept unsigned extensions, they claim that the extension is "broken".

The fuck?! This is Apple-level user hostility. Meanwhile Mozilla execs are getting Apple exec-style compensation while driving it further into the ground.


> This was the straw finally pushing me to very seriously consider migrating to Chromium.

What is the situation surrounding Manifest V3 in Chromium? Won't that throw a wrench into power user's workflows with its own arbitrary limitations?


Not as much as it initially seemed. All extensions I use work fine, including uBlock Lite. The arbitrary limits would trivially be increasable in a fork.

But of course I'm worried about Chromium going the way of the third E, which makes it quite possible I'll continue the toxic relationship with Mozilla for even longer.


> And it doesn't even tell you that it doesn't accept unsigned extensions, they claim that the extension is "broken".

It's likely you forgot to include the browser_specific_settings with a some arbitrary id in the manifest.json.

Permanently installing unsigned extensions definitely works in the Developer Edition after setting the pref in about:config.


Have you tried rebuilding the XPI in a different way or trying a different XPI? I would guess that your addon is broken, as it works for me: https://postimg.cc/9rkbMd7v

I understand the frustration and would also like improved control, but I understand firefox preventing this in the "normal" edition as it's very common for trojans to install unwanted extensions manually by fiddling with the profile files, I've had to remove them manually from family computers in the past.


It’s really not that bad. You can sign up for a free Mozilla developer account and upload the bundle you’d like to sign, and install the signed extension a few minutes later on any edition of Firefox.


Not that bad?? I'm sorry, but that's horrifying. Imagine if you couldn't run any code on Linux without uploading it to Linus's servers first.


Okay, but Linux is an operating system (kernel), Firefox is a web browser. That's two completely different things with different expectations and threat models.


Chrome lets you do it, and with the market share that it has, it means that it's the de facto expectation that you can actually install extensions without an account. And it's not like chrome is less secure than firefox, the opposite is true actually.


if this is horrifying, perhaps you should go touch some grass man. A decent security take is not a horror show when you can get even hobby stuff of your own signed fairly trivially.


Sorry, what security is this offering? At the cost of my PII?

And Mozilla still doesn't scan or do any due diligence on whatever it is you are installing.


How about I have to approve of any code you want to run before you can run it? That's dystopian.


> Even installing the "Developer Edition" didn't enable to me to install self-built extensions

For a different perspective, I’ve successfully done this on both Windows and Linux. In both cases it was pretty straightforward. (My extension was admittedly very simple, though… maybe it’s different with more complex ones.)


It is hostile to power users, but gracious to unsuspecting users who might have a sneaky person install extensions on their browser to steal their data/spy on them. In any case, a real power user could always use a developer build and set that flag.


> In any case, a real power user could always use a developer build and set that flag.

...this one?

>>Even installing the "Developer Edition" didn't enable to me to install self-built extensions (yes, with that secret flag).


I just tested it and it does work for me: https://postimg.cc/9rkbMd7v

I would guess that they are trying to install is actually broken.


Yes, my not so nice implication was that they aren't a real power user and it was PEBKAC. I usually try to be nicer but it's hard when someone is saying "X sucks because..."


lol, I feel that Firefox is chrome but using Firefox engine. What I don't understand is that can see evidence of this if you cause an error and view source. It has chrome:// literally hard-coded and commented out.

Host a web server, kill the web-server, try to visit the URL, open inspector and look chrome.

Examples:

"<script xmlns="http://www.w3.org/1999/xhtml" src="chrome://global/content/neterror/aboutNetErrorCodes.js"></script>"

Visit chrome://global/content/aboutNetError.mjs in your firefox browser. Why is Firefox accepting chrome:// URI's?

You can even browse: chrome://global/skin/icons/

Visit: jar:file:///usr/local/lib/firefox/omni.ja!/chrome/

(i'm on freebsd, so if linux: /usr/lib/firefox/omni.ja!/chrome or something) too drunk to care. The internet is fucked.

Firefox version: 109.0 (64-bit)

root@cuddles:/usr/crystal/doublerabbit/ # pkg install chromium Updating FreeBSD repository catalogue... FreeBSD repository is up to date. All repositories are up to date. The following 3 package(s) will be affected (of 0 checked):

New packages to be INSTALLED: chromium: 109.0.5414.119 noto-basic: 2.0_1 sndio: 1.9.0

Call me skeptical, what a coincidence. Convince me.


Oh gosh, "chrome" here is not the browser...

https://developer.mozilla.org/en-US/docs/Glossary/Chrome

https://www.nngroup.com/articles/browser-and-gui-chrome/

> 'Chrome' is the user interface overhead that surrounds user data and web page content.

Browser/GUI's "chrome" terminology existed before google "chrome" browser. That's why you use "userChrome.css" to modify the visual look by yourself.


Well you've convinced me, call me skeptical. Thanks!


I always assumed Google Chrome was named Chrome BECAUSE of "Chrome" being the internal name for the Firefox UI styling. I guess I'm old :)


Chrome is named after this :-)


It's not the prettiest solution, but you can work around this problem with web-ext: https://www.npmjs.com/package/web-ext


This is a great idea. I really do like this.

However, we shouldn't forget the reduced security of the situation. This opens entirely new attack vectors by introducing the otherwise fantastic ability of local programs to consume network input.

With the flexibility and utility of local information comes additional remote attacks. In doing so, this extension blurs the lines between the greater difficulty of remote attacks vs local attacks. Many programs never considered in their threat models that input would come over the network. There are many developers who never try to protect past a certain point, saying, "if the person gets this far, there is nothing we can do anyway", then they ship.


Isn't this already a reality with wget, curl, and even package managers like pip and npm?

I mean, any script on my machine can use these tools to interact with network input and execute untrustworthy code...


> even package managers like pip

This reminds me of a blog post [1] I read before. Pertinent quote:

> Unbeknownst to me, even with --dry-run pip will execute arbitrary code found in the package's setup.py. In fact, merely asking pip to download a package can execute arbitrary code (see pip issues 7325 [2] and 1884 [3] for more details)!

Also seen on Twitter [4].

[1] https://moyix.blogspot.com/2022/09/someones-been-messing-wit...

[2] https://github.com/pypa/pip/issues/7325

[3] https://github.com/pypa/pip/issues/1884

[4] https://twitter.com/moyix/status/1566561433898426368


Except now the attacker has your cookie jar with the bank.com cookie in it.

(Fantastic extension, btw.)


They already did. Where do you think Firefox stores your cookies?


I guess we are now getting into which folders and what permissions


That's not the issue. The issue is adding network input into local tools whose threat models never considered having network input.


If a tool's threat model never considered having network input in the first place, that tool would seem deficient in most every real-world situation.

I do not per se see a problem with "network input" but I think you're referring to input from untrusted sources, i.e. input that is not controlled or approved by the user of the tools.

I think that a modern operating system must definitely have access controls that can flag and signal when input is untrusted, wherever the source may be, network, keyboard, USB stick, camera, whatever. If the input is from a network source such as el rando website, then an AAA-layer service can block, flag, log, and handle an exception, rather than forcing every tool and every application to track the provenance of every byte of input. Don't you think?


> If a tool's threat model never considered having network input in the first place, that tool would seem deficient in most every real-world situation.

The hyperbole isn't needed. Risk can be avoided, mitigated, transferred, or accepted. This extension, which otherwise looks fantastic by the way, moves the risks between those categories for various local tools, the data in the DOM, and even for remote accounts of the other current websites. That is what is happening here.

> I do not per se see a problem with "network input" but I think you're referring to input from untrusted sources, i.e. input that is not controlled or approved by the user of the tools.

That is the implication of saying network input, since that input is uncontrolled and from a third party.


> That is the implication of saying network input, since that input is uncontrolled and from a third party.

Hey, it is easier to authenticate and authorize network input than keyboard input, considering what sort of USB devices are floating around.


If your local machine is compromised such that your mountpoints are free game to some tool running.. what difference do you think this will make? Your cookie jar IS STILL exposed without this.


You misunderstand the security implications, so making categorical statements like that isn't useful. While random running processes may be on a developer's machine, that's not at issue here.


/mnt is owned by root, the submount would be owned by either root or your user

your cookie jar is somewhere in ~ (eg ~/.firefox)

If a service has been compromised such that it can exfiltrate /mnt/blah/tab/blah/, it can also exfiltrate ~/.firefox/blah

You're shuffling deck chairs on the titanic.


You should read the article. This isn't /mnt but fs/mnt.

In this particular scenario, the article describes the use of FUSE for mounting the files. FUSE stands for "Filesystem in Userspace". This, thankfully, doesn't force running a web browser as root, which would be required in your scenario.


> doesn't force running a web browser as root, which would be required in your scenario.

It would not in any way shape or form be required in my scenario. Please re-read the basics of file permissions on POSIX.

We are asking the question: "Does this expose additional potential security vulnerabilities not exposed with the cookies existing purely in the normal cookie store?"

Our possible vectors of attack are a compromised root owned service and a compromised user owned service. Both of those vectors would allow the cookie store to be exfiltrated regardless of whether this extension is used.

Ergo, this extension does not create any additional security vulnerabilities in that regard.


I think the security implications of this would qualify as a fantastic new problem to solve if it's really of any meaningful consequence.


If anyone already uses Sideberry (and I assume TST will work as well) on Firefox and doesn't want to download an additional extension or doesn't want something quite this powerful, I wrote https://textmark.netlify.app/ a week or two ago, and I've been using it as a bookmark replacement.

Sideberry allows selecting arbitrary groups of tabs and copying them to the clipboard as an indented list of tabs. The site I put up will reopen those tabs, preserving the order and parent-child relationships between pages. It also uses `rel=noopener` to avoid a security risk I've noticed with similar sites in the past with parent-child page references. And it has no advertising and absolutely zero user tracking (aside from Netflify serverside logs that I can't turn off), since it's a project I made for myself and costs me nothing to run.

Also, the entire source (minus the favicon) is in one page, so if you want to self-host it yourself for extra protection, just view-source and copy and paste. It'll work on any static web host.

I've found this to be a hugely beneficial replacement for bookmarking. Bookmarks are too slow and cumbersome for me, so I end up not really using them. It's also annoying to enter descriptions for bookmarks, and I don't like that all of my bookmarks need to be in the browser at the same time. This allows me to copy tabs out to separate files (I use org-mode to sort everything). And then I just keep this site pinned and use it to reopen tabs later if I context-switch. It's the closest I've ever come to being able to actually manage my browser sessions and stop my tabs from growing out of control into the thousands.

I was going to wait to Open Source it and write up a better explanation of the workflow I use before sharing it, but it's appropriate to share it here. It's not nearly as powerful as what TabFS is talking about (and I'm very interested to look into TabFS more, since I've been thinking about roughly the same problem, and this looks like a potentially quite powerful setup), but it's a small system that has made a big impact for me over the past week or so, and since I was already using Sideberry it doesn't require me to install anything new or open any additional attack vectors.


For some reason (to confuse everyone?) it's "Sidebery", with one r. https://addons.mozilla.org/en-US/firefox/addon/sidebery/


Thanks for letting me know, I appreciate the heads up.


I’m already thinking about how to name web pages to trigger shell command injection attacks. ;)


Be my guest, I'll run this in a vm. But what's even scarier is cross tab exploits. Want to steal data from another tab of a tabfs user?


This is a super nice idea. I wonder what other software we could interact in this form. The Unix people did have a good point about everything being a file.


One source of inspiration is to see what the Plan 9 folks did, plus things inspired from that - filesystems for network access, for the clipboard, for representing windows on the screen.

I've also been considering some sort of filesystem for MQTT, which combined with an appropriate bridge would allow for reading and control of assorted smart devices as a filesystem.


The file interface is somewhat limited though (e.g. everything is just an opaque untyped byte stream) and has security issues in conjunction with shell scripting (e.g. quoting and escaping).

A data type aware interface like AppleScript or COM, if universally supported, would be more expedient.


> The file interface is somewhat limited though

And so? The mantra says "everything is a file", not "everything is only a file". You can provide stream access to everything, and then more advanced access to some particular resources.


The problem is that everything below the file surface is proprietary, so to speak, and that the file interface doesn’t give you a standard way of discovering the file format or (for command pipes) the commands it understands. What’s missing is a standard way of querying schema information about files/pipes. In addition, like in the TFA use-case, not just individual files have schemata, but whole directories and directory trees have. Those are not communicated by the file system, but have to be known out-of-band for each specific purpose.

Providing just a generic interface cuts two ways: On the one hand, you can represent anything, but on the other hand, you don’t know what anything represents without additional information (metadata).


Any database:

  cat /mnt/imdb/movies/tt0103064/director/details.json


  cat /mnt/imdb/actors/by_contains_name/arnold/roles.csv

Or any graphql source


GraphiQL.... what a fucking nightmare


Plan9 takes this even further


I loved this talk by Omar Rizwan from !!Con 2018 on that topic:

Four fake file systems! (9 mins) https://www.youtube.com/watch?v=pfHpDDXJQVg

i.e. screenshots, torrents, youtube, git.


> The Unix people did have a good point about everything being a file.

Yes and no. While it simplifies things to an extent, it's also confusing, especially with extension-less files.

Example: Tell me, is this a file or directory?

    ~/hn/today-posts
It could be a file that curls todays posts, or it could be a folder (directory) that contains them.


> Example: Tell me, is this a file or directory?

A directory is a file (and IIRC e.g. Plan 9 decided they should be readable just like normal files and there shouldn't be any special readdir syscalls). You can see its attributes to figure out the rest.

If not for strong Linux limitations (because of alleged hardlink knot-tying problem) and belief that it just cannot be both, transparent archive access through a filesystem would be a thing. As well as metadata access (`play ./file.mp3` vs `edit ./file.mp3/id3v2`). People of the past seemed to have paid great attention to interoperability and effort to make common interfaces; folks of the modern age ('00s and later) love unique and completely incompatible solutions to the same problem.


Neat. I’ve often wished I could cat a directory or ls a file. Plan9 sounds like something I would have enjoyed using.


> I’ve often wished I could cat a directory

This was possible in the beginning. But then came the moral police and deprived us of this freedom, because they deemed it to be "confusing".

See, for example, The Unix Programming Environment, by Kernighan and Pike, page 51 [0]:

Despite their fundamental properties inside the kernel, directories sit in the file system as ordinary files. They can be read as ordinary files. (...) The time has come to look at the bytes in a directory:

    $ od -cb .

[0] https://archive.org/details/UnixProgrammingEnviornment/page/...


Valid complaint, but maybe not such a great reason.

It gets worse when you deal with sysfs or procfs and similar. It all becomes obscure magic, like what values can be written into what file, why some files aren't readable, or the contents of files being just a bunch of numbers which you have no way of interpreting.

Another problem is that there's way too many of different file types and they aren't organized into any kind of hierarchy or any other meaningful order. This makes tools like rsync extremely complicated, with loads of footguns and still not solving the problem well. It feels especially bitter because in exceeding majority of cases you don't want tools like rsync to deal with named FIFO or device files or sockets etc. but you get accidentally but painfully bitten by them every now and then.


'ls -l' will tell you the basic information of a given listing, including whether it's a normal file, directory, symlink, block device, named pipe, etc.

stat(1) will provide additional information on a file.

file(1) will not only distinguish between filesystem=level distinctions, but will make a remarkably good guess as to what the file contents of a normal file are, based on magic(5).


How would adding an extension solve the issue? E.g. is this a file, a device file, or a symlink?

/dev/readme.dev

To know what this is, a `stat(2)` is required.


The terminal emulator may change the color of the prompt, for example.


Hmm, this might be the right audience - anyone with C and JS skills want to poke at https://github.com/osnr/TabFS/issues/75 and maybe come up with a pull request? (I got as far as I could on the C side, all the details are in the issue, but I'm not sure what shape the javascript side of the fix would be...)


Two things,

1. I couldn't get this working on my M1 Mac due to MacFUSE issues.

2. I wish there was a version for Firefox.

I think this is such a cool project, and I want this to work really badly. I have many workflows where I'd like to log data for certain sites I visit it plain text for further analysis. And long term storage.


There was recently someone who made a "fuse-ish" thing using user-mode NFS, which more closely matches my mental model of living in the new multi-arch, locked-down macOS world (https://news.ycombinator.com/item?id=32726166 not open source but the discussion shows the general idea)

I regrettably don't know the guts of NFS enough to know how much of FUSE can be ported, but my guess would be "perfect is the enemy of good" for folks who otherwise can't even run this right now


The open-source implemention I'm aware of is in Buildbarn

Design doc: https://github.com/buildbarn/bb-adrs/blob/master/0009-nfsv4.... Code: https://github.com/buildbarn/go-xdr


The article claims this does support Firefox? (albeit, requiring re-install each time you open the browser due to an upstream bug)


It's not a bug. It's an intentional choice by Mozilla that users should not be able to install software without the approval of Mozilla. They say it is for security. But the signing portal is automated so this is only realistically for revokation after widespread damage has been done.

The suggestion in the thread is to use the developer edition which is, in lineage, essentially aurora/alpha version (in the past naming scheme) and contains bugs and security holes.

With modern Firefox if you want software freedoms you have to give up safety... or use the unbranded version which has no auto update and manually re-install the browser for every update.


While a bit annoying, the signing process for a self-distributed add-on [0] seems straightforward?

[0] https://extensionworkshop.com/documentation/publish/submitti...


I was just thinking there is nothing new under the sun, but then I find imaginative programs like this.


If anyone knows a twitter account even 1/8th as fun as Omar's[1] (the author of TabFS), I'd love to hear it.

Endless fun meditations & musings on code & processes & computing. It's the most live, most inove stream of computing out there.



One of the coolest use-cases for this for me is the ability to "host" these folders on a server and be able to access it from embedded contexts. I'm hoping to write a full computer stack that can run on microcontrollers (GitHub.com/Civboot/fngi), including a gopher-like browser for lightweight protocols. It could never interface with the real WWW... unless it had a server hosting the browser like this!


Working on a nodejs/electron app called "canvas" (code hosted on a personal gitlab instance for now), core functionality being organizing all your data into "contexts". A context is identified by a context url, fe customerA/projectP/reports, each url part representing a layer on top of your data, using roaring bitmaps and lmdb underneath. Switching your context to customerB/projectR automatically changes your tabs(socketio based poc ff extension), it also exports all your data(internally data/abstr/notes, data/abstr/tabs, data/abstr/files etc) as part of a webdav exported "virtual" fs tree. While the concept is not new, paired with the cli iface the ux is a huge boost to productivity, esp with chokidar based monitoring of the os downloads and desktop folders and minio/s3; my desktop is finally used as a virtual work desk and not as a showcase for the 2nd law of thermodynamics. Stay tuned


This is absolute genius and opens up so so many opportunities!


for Firefox I use this

lz4jsoncat ~/.mozilla/firefox/YOUR_PROFILE.default/sessionstore-backups/recovery.jsonlz4 | jq '.windows[].tabs[] | .index as $a | .entries[$a-1] | .title,.url'


Working on a nodejs/electron app called "canvas" (code hosted on a personal gitlab inst for now), core functionality being organizing all your data into "contexts". A context is identified with a context url - fe customerA/projectP/reports, each url part representing a layer on top of your data, using roaring bitmaps and lmdb underneath. Switching your context to customerB/projectR automatically changes your tabs(socketio based poc ff extension), it also exports all your data(data/abstr/notes, data/abstr/tabs, data/abstr/files etx) as part of a webdav exported "virt" fs tree. While the concept is not new, paired with the cli iface the ux is a huge boost to productivity, witch chokidar based monitoring of downloads and desktop and minio/s3, my drsktop is finally used as a virtual work desk and not as a showcase for the 2nd law of thermodynamics. Stay tuned


Wow, this is brilliant.

So often I want to automate parts of my web experience, and I think ugh I need a browser extension, or user script, or puppeteer. All of which feel clunky for trying to do something simple.

Seems like this will get me 90% of the way for most things, then when I need to click a button or automatically respond to an automatic email, that's just a few lines of code and a cron job away.


Something in a similar vein: BTFS, mount a torrent file (or magnet link) as a read only drive https://github.com/johang/btfs

It's really good, and use it a lot of times. Doesn't seem to be an active project anymore though but it still works


Took me forever to find a good option on FireFox, Simple Tab Groups is pretty awesome: https://addons.mozilla.org/en-US/firefox/addon/simple-tab-gr...


BroTab exposes a python library for doing same in Firefox


This looks quite nice - for some time I have been trying to list all tabs in Chromium window so I can stick it to proper workspace (I'm using i3) - one for general browsing and one for IM/socials.

If this can identify the window (PID or better WindowID like wmctrl -l lists) it will be perfect!


This is so awesome, I can't believe that someone really created that.

I have dozens of windows, each with thousands tabs and this is something I would have dreamed of if I knew that it was possible.

Really kudo to this guy for that!


Can this be used like selenium for testing/scraping/automation? If you can open tabs, dump the DOM and inject JS, then I would think so.


Plan 9 is pleased.


Nice work! Is it possible to somehow switch to a tab somehow using this? (Use case: switching browser tabs within Emacs). Thanks



His link [0] makes me trust him more about what he's doing as he's clearly using Vim/Neovim :)

0: https://twitter.com/rsnous/status/1338932056743546880


>he's clearly using Vim/Neovim

The author directly mentions Emacs twice and one of their liked tweets says "in practice most of my logical 'windows' are actually browser tabs or Emacs buffers": https://twitter.com/rsnous/status/1176587656915849218


There's Evil mode on Emacs which is basically Vim.


Genius! Gott love it when simple ideas create game changing improvement.

I have 168 tabs open and regardless of how hard i organize them, it's still a mess. I will give this a try today.



This reminds me of Bookmark OS but not in the browser https://bookmarkos.com


What would it entail to add support for this to another browser?

Is there an API contract defined and documented anywhere?

I'm specifically hoping to use this with Qutebrowser


Qutebrowser already kinda does this. You can use environment variables to access most browser details in python user scripts. For example, QUTE_HTML points to file containing current tab's HTML.

It has been one of my favorite things about this browser as you can quickly write up easily maintainable user scripts in Python compared to whatever unmaintainable magic greasemonkey scripts end up being.

See more: https://qutebrowser.org/doc/userscripts.html


This is fantastic. I hope more people support them.


It says some features are Chrome-only. How much of what us shown will not work in Safari? If anyone already tried. Otherwise I might...


That looks incredibly useful. Now i imagine i had a small terminal window within my browser that i could focus by pressing ESC ...


Now THAT is unix philosophy at its best.


No support for Windows? There are more Windows endpoints than all iOS, MacOS, and Linux desktops combined.


Haven't looked into the source, but this is most probably using FuseFS in order to present a mountable filesystem.

Fuse does not support windows. If it did the extension could probably be easy to port..

Your best bet is probably running the browser under some wsl layer.



echoing the sentiment given to linux users every time they ask for a version for their os-- you can just install linux in a vm if you want to use this.


How many of those windows users would want to write a mesh of Python and Bash to interact with their browser?

Not saying it shouldn't support windows, but choosing Linux and MacOS as initial support is a sensible choice...


Oh cool! it seems I am a first class citizen here! Linux + Chrome + Emacs user! I will test it


I have to thank emacs OS (users) for this browser extension.


This is really cool. Great work


Does this load all videos and images into the filesystem for Onlyfans?


This seems very interesting and all the uses cases it satisfies


This is extremely useful. Thank you.


Pretty cool, but my advice to anyone is still "stop using tabs, you os already have a window manager"


tabs are great, why would I want 147 windows open? I can group my tabs by window; e.g. work, personal, side project, etc.


My counterquestion is: why use tabs as bookmarks?

Usually when you have that many tabs open, it's not because you read/work on the pages.


Genius


Exactly, why isn't more software made to be accessible from a filesystem?


unix gang approves




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: