See https://omar.website/tabfs/.
(update: You can now sponsor further development of TabFS!)
๐ Mount your browser tabs as a filesystem.
Home Page: https://omar.website/tabfs/
License: GNU General Public License v3.0
See https://omar.website/tabfs/.
(update: You can now sponsor further development of TabFS!)
#16 after you open a tab, or do something with it, getting a tab ID or something would be nice, as you could be sure multiple commands get directed at the same tab (even if you have duplicate tabs).
anyone saw this problem on macOS BigSur?
Unchecked runtime.lastError: Access to the specified native messaging host is forbidden
I've installed macFUSE and gave the permission, but the extension still has error...
What's the license for code in this repo?
Is there a way to focus on an existing tab?
Checking to see if there is any interest from you (or others) for configuring the mount point instead of it being tied to a hardcoded mnt
directory.
I've added a check for an environment variable TABFS_MOUNT_DIR
to my fork, mostly curious if you'd like a PR for it.
You can check the diff here: master...buckley-w-david:master
Hello thanks for this great tool.
What i want to do is some browser automation like with selenium. (But selenium are blocked by ddos cloudflare protection).
For example it's the ability to get some urls in a tab and to retrieve back then as text : for now i try to exec some JavaScript in the console to select the urls in a var and log it in the console
Is it possible to get/log console messages?
Is it the right way to do that?
Thanks in advance
I honestly believe the best use case for this would be new folder/files for Chrome/Firefox developer tools.
Having rolling files with network requests and developer (Javascript) console would be a killer feature.
I'm not sure if it's possible to do this without actually opening the dev tools window in the browser UI itself but if it's possible without it, I'd be amazed. My everyday font-end development would become a piece of cake.
Thank You for considering!
This is the patch I used to get TabFS functioning with Brave:
- ( "$1" == "chromium" && "$#" -eq 2 && ${#2} -eq 32 ) ) ) ]]; then
- echo "Usage: $0 <chrome EXTENSION_ID | chromium EXTENSION_ID | firefox>"
+ ( "$1" == "chromium" && "$#" -eq 2 && ${#2} -eq 32 ) ||
+ ( "$1" == "brave" && "$#" -eq 2 && ${#2} -eq 32 ) ) ) ]]; then
+ echo "Usage: $0 <chrome EXTENSION_ID | chromium EXTENSION_ID | brave EXTENSION_ID | firefox>"
exit 2
fi
@@ -32,6 +33,8 @@
MANIFEST_LOCATION="$HOME/Library/Application Support/Google/Chrome/NativeMessagingHosts";;
"Darwin chromium")
MANIFEST_LOCATION="$HOME/Library/Application Support/Chromium/NativeMessagingHosts";;
+ "Darwin brave")
+ MANIFEST_LOCATION="$HOME/Library/Application Support/Google/Chrome/NativeMessagingHosts";;
esac
As you can see Brave installs to the same place as normal Chrome, instead of its own Brave-Browser/NativeMessagingHosts.
I think it would be helpful to update your documentation site to note that Brave users should use the chrome option.
The https://github.com/monkeyiq/ferris project seems to have very similar goals to the FUSE-side of TabFS, see http://www.libferris.com/features for details.
For instance, it might be simpler to generate xml on JS side and let libferris mount it as FUSE to avoid reimplementing stuff.
I'm going to preface this by saying thank you very much for making this - I'm very excited for this Tabfs and I'd love to get it working!
I followed the install instructions, afict, but tabfs doesn't appear to work for me:
$ git clone https://github.com/osnr/TabFS.git
Cloning into 'TabFS'...
remote: Enumerating objects: 42, done.
remote: Counting objects: 100% (42/42), done.
remote: Compressing objects: 100% (32/32), done.
remote: Total 622 (delta 16), reused 29 (delta 10), pack-reused 580
Receiving objects: 100% (622/622), 2.14 MiB | 1.96 MiB/s, done.
Resolving deltas: 100% (321/321), done.
$ cd TabFS/
$ sudo apt install libfuse-dev
The following NEW packages will be installed:
libfuse-dev
...
Setting up libfuse-dev (2.9.9-3) ...
$ cd fs
$ mkdir mnt
$ make
cc -DFUSE_USE_VERSION=26 -D_FILE_OFFSET_BITS=64 -Wall -Wno-unused-function -g -o tabfs tabfs.c -lfuse
$ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
$ cd ..
$ ./install.sh chrome kdnjhocmbphcdgaogeidlacbgnpnigma
+(./install.sh:6): [[ 2 -lt 1 ]]
+(./install.sh:6): [[ chrome == \f\i\r\e\f\o\x ]]
+(./install.sh:6): [[ chrome == \c\h\r\o\m\e ]]
+(./install.sh:6): [[ 2 -eq 2 ]]
+(./install.sh:6): [[ 32 -eq 32 ]]
++(./install.sh:11): uname -s
+(./install.sh:11): OS=Linux
++(./install.sh:12): echo chrome
++(./install.sh:12): tr '[:upper:]' '[:lower:]'
+(./install.sh:12): BROWSER=chrome
+(./install.sh:16): case "$OS $BROWSER" in
+(./install.sh:22): MANIFEST_LOCATION=/home/duncan/.config/google-chrome/NativeMessagingHosts
+(./install.sh:31): mkdir -p /home/duncan/.config/google-chrome/NativeMessagingHosts
+(./install.sh:33): APP_NAME=com.rsnous.tabfs
++(./install.sh:34): pwd
+(./install.sh:34): EXE_PATH=/home/duncan/dev/TabFS/fs/tabfs
+(./install.sh:36): case "$BROWSER" in
+(./install.sh:38): EXTENSION_ID=kdnjhocmbphcdgaogeidlacbgnpnigma
++(./install.sh:49): cat
+(./install.sh:49): MANIFEST='{
"name": "com.rsnous.tabfs",
"description": "TabFS",
"path": "/home/duncan/dev/TabFS/fs/tabfs",
"type": "stdio",
"allowed_extensions": ["[email protected]"],
"allowed_origins": ["chrome-extension://kdnjhocmbphcdgaogeidlacbgnpnigma/"]
}'
+(./install.sh:63): echo '{
"name": "com.rsnous.tabfs",
"description": "TabFS",
"path": "/home/duncan/dev/TabFS/fs/tabfs",
"type": "stdio",
"allowed_extensions": ["[email protected]"],
"allowed_origins": ["chrome-extension://kdnjhocmbphcdgaogeidlacbgnpnigma/"]
}'
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
fs/log.txt
nothing added to commit but untracked files present (use "git add" to track)
$ cat fs/log.txt
arg0: [/home/duncan/dev/TabFS/fs/tabfs]
arg1: [chrome-extension://kdnjhocmbphcdgaogeidlacbgnpnigma/]
In the console of the extension's background page, it says this:
background.js:664 disconnect Object
_generated_background_page.html:1 Unchecked runtime.lastError: Native host has exited.
DevTools failed to load SourceMap: Could not load content for chrome-extension://kdnjhocmbphcdgaogeidlacbgnpnigma/vendor/browser-polyfill.js.map: HTTP error: status code 404, net::ERR_UNKNOWN_URL_SCHEME
I was expecting the make
to do something... more than that, maybe? Although it does seem to have built fs/tabfs
:
$ pwd
/home/duncan/dev/TabFS/fs
$ ls -halp
Permissions Size User Group Date Modified Git Name
drwxrwxr-x - duncan duncan 31 Dec 2020 -N ./
drwxrwxr-x - duncan duncan 31 Dec 2020 -N ../
drwxrwxr-x - duncan duncan 31 Dec 2020 -- mnt/
drwxrwxr-x - duncan duncan 31 Dec 2020 -- vendor/
.rw-rw-r-- 101 duncan duncan 31 Dec 2020 -N log.txt
.rw-rw-r-- 634 duncan duncan 31 Dec 2020 -- Makefile
.rwxrwxr-x 86k duncan duncan 31 Dec 2020 -I tabfs*
.rw-rw-r-- 7.3k duncan duncan 31 Dec 2020 -- tabfs.c
System details:
OS: Ubuntu 20.04.1 LTS x86_64
Google Chrome: Version 87.0.4280.88 (Official Build) (64-bit)
What can I do to help debug & figure this out?
Thanks for a really exciting, interesting venture!
I have two different profiles logged into chrome (one for "work" and one for "home"). I tried configuring two copies of the repo, one per profile, and two mounts appear in the list generated by mount
.
I mount the first, and can ls
the tabs by-title. After mounting the second, I'm able to ls tabs-by-title for the second, but the first now errors with Device not configured
.
Any pointers to where in the configuration I should tweak to better isolate these two profiles?
First off, this tool is awesome. Thanks so much for the work on it so far ๐
I'm seeing some erratic behavior where the TabFS Chrome extension removes itself from the extensions list. I haven't identified a pattern for when/why this happens, which I imagine makes it tricky/impossible to know what the root cause is here.
Seems to happen every few days, and doesn't appear to be tied to Chrome (or my computer) restarting.
If there's anything I can dig into (logs maybe?) that would provide more information about this when it occurs, please let me know.
Chrome Version: 88.0.4324.150
OS Version: Mac OS Mojave 10.14.6
Hi,
echo 'console.log(document.getElementById("currHeight").textContent)' > mnt/tabs/last-focused/execute-script
How to get the currHeight
return's value?
I want to suggest the ability to manage bookmarks via TabFS as a new feature.
The specific use case I have in mind is the following:
This proposed workflow would allow for bi-directional synchronization of a collection of tabs into bookmarks and vice versa. As far as I know, there is no native extension which allows this workflow, while it would be very easy to implement with native unix tools.
It would allow to stop accumulation of open, "on hold" windows and enable secure (in the sense of being pretty reliable), cross-device persistence (with bookmark sync) of research sessions.
I am not totally sure if it would be more practical to save a research session by some other means, e.g. just by having a folder, textual URL list or YAML file into which open tabs are synced - but still think that using the native storage facility of bookmarks could be very userful nevertheless.
Also, this feature requires the ability to manage windows via TabFS, which afaik is something that also still has to be implemented as of today.
Currently the tabfs
executable is executing some simple shell script via system()
before calling fuse_main
. This makes it quite hard to extend because constructing strings in C can be annoying (to me at least ;)). I've got a commit on my fork that does all the shell stuff in tabfs-wrapper
before executing the tabfs
executable. This makes it simple to e.g. make the mountpoint configurable.
My question is whether such a wrapper would be desirable to have in this repo. If yes, then I would be delighted to create PR.
https://github.com/gildas-lormeau/SingleFile
SF is an awesome extension (or even CLI tool).
Advantages of extension: You don't have to mess with url, cookies, etc; you just get stuff
Advantages of CLI: you can programatically do things
Advantages of running SF via TabFS: Get an already loaded tab (don't have to download webpage again), with cookies, and everything.
My current workflow exporting 10 tabs is:
or:
This would change it to:
Anyone know if this is possible?
First of all, tabfs
is great! Thanks for this wonderful project.
I don't know if browsers provide an API to query the tab creation time. It would be nice if the file ctime
reflects the tab creation time. At the moment, the file ctime/mtime etc are not being set (and shows Unix epoch Jan 1 1970).
I am imagining a situation where a user can do operations like deleting all tabs older than a date or something of that sort..
This is just a very terse and superficial list of stuff I had to do to make it work on FreeBSD 12.2 with Firefox 84.0.1. Might be the basis for a later pull request:
Follow installation instruction as is, but modify the source like so:
Makefile:
if uname -s == FreeBSD: add "-L/usr/local/lib -I/usr/local/include" to CFLAGS_EXTRA, rest like Linux branch
fs/tabfs.c:
on FreeBSD there is no fusermount, as regular "umount" can unmount FUSE fs's, so add an #ifdef for FreeBSD that calls system("umount mnt").
install.sh:
/bin/bash doesn't exist on FreeBSD, the usual fix of using "/usr/bin/env bash" doesn't play well with command line arguments. So moving the arguments to a "set -eux" is necessary
With these modifications the installation steps produce a seemingly working fusefs (tested only a bit by rm'ing a by-title tab, which works).
edit
See PR #19
/edit
The below is the error message as I try to install TabFS.
$ cd fs
$ make
cc -I/usr/local/include/osxfuse/fuse -L/usr/local/lib -D_DARWIN_USE_64_BIT_INODE -DFUSE_USE_VERSION=26 -D_FILE_OFFSET_BITS=64 -Wall -Wno-unused-function -g -o tabfs tabfs.c -losxfuse
ld: library not found for -losxfuse
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [tabfs] Error 1
Apparently, macFUSE 4.0.4 set a header file as /usr/local/include/fuse/fuse.h
, not /usr/local/include/osxfuse/fuse.h
.
That is why, in my case, I edited Makefile and changed a line LIBS = -losxfuse
into LIBS = -lfuse
. It seems to work so far.
Actually, this resolved my problem. However I wanted to share this problem because there should be some instructions about this case on documentation for the convenience to other users.
Hi! Found your article on HN. I recently experimented with developing my own first tiny webextension for Firefox, and yes, to permanently install it outside debugging, it's enough to get it signed. I did it by uploading the plugin as a zip file to addons.mozilla.org. I had to create an account there, but other than that it's just a few steps - registering the addon and uploading new version's zip. I did it following some "your first webextension" Mozilla tutorial I believe, though I don't have a link handy at this moment to quickly share with you. I recall there were a few options explained for publishing, I chosen one with manual uploading to addons.mozilla.org as it seemed easiest for first try for me, and I didn't want to install some npm-based CLI tool they mentioned in the other options. After the procedure, you need to wait a while until the new version shows up as "Accepted", then you can download the .xpi they generated for you, and it works permanently. It seems to use some JAR-like signing, there's a META-INF directory in the .xpi after the "Accepted" status shows up.
edit: ok found the link, had it noted in the script: https://extensionworkshop.com/documentation/publish/package-your-extension/#package-linux -> then check out the "up next" links at the bottom of the page ("Submitting an add-on", etc.)
In the latest Safari 14 for macOS there is support for the standard WebExtensions API - https://developer.apple.com/documentation/safariservices/safari_web_extensions
Maybe it would be possible without much changes to support Safari as well?
For the publishing side it might be a little more complicated since it requires Mac App Store publication but it might be feasible.
What a cool app!!
Any chance you could add the ability to track which tabs were most recently used, perhaps by extending "last-focused" to work the same was as by-title except it lists all the open tabs in MRU order?
Using this on a managed Mac, 10.15.7, using osxfuse from homebrew.
Currently, virtual files are created under root:wheel, with only root having write permissions. This makes it annoying to actually poke at it.
Please create the files with their UID/GID set, so the user can actually use them.
I have 300+ tabs open, in 20 different windows. I would like to be able to move tabs between existing tabs, and possibly to new tabs, based on titles, urls, etc... For example:
"I want to move all my Stack Overflow tabs into a new window to review"
mv tabs/by-title/*Stack_Overflow* windows/create
"I want to move all of my tabs running local apps ("localhost") to the window with my GitHub repo tab open"
grep -l localhost tabs/by-id/*/url.txt | sed -r 's|/[^/]+$||' | xargs -I{} mv {} tabs/by-title/philipsd6\/dev-project.*/window/
Is that possible to implement somehow? I've used balta2ar/brotab to accomplish similar goals in the past.
My main reservation about experimenting with such a powerful & clever thing involves potential security concerns.
Every extension is a little worrisome, but in general open-source plus sufficient-community-of-users plus browser-store-review plus browser-security-boundaries will put me at ease.
But, a custom C-language filesystem, and specifically one that gets pushed JSON data derived from any untrusted website, gives extra pause.
Has the FS code been subjected to any/some/much intense review for security risks? Could it be, on either a volunteer or contracted/crowdfunded basis? Its small size & relative low-rate-of-change even as browser-visible features grow suggest a one-time (or very occasional) bounded effort/cost could offer a long period of peace-of-mind.
Interestingly, fzf, the fuzzy file finder doesn't work under mnt/
. The directory appears empty, even though find
returns results just fine.
Hey thanks this is awesome, understand if this is something you don't have time to fix (and sorry I don't even really know where to begin with fusefs) but thought I'd share the error I was running into.
โฏ RUST_BACKTRACE=full ls ~/.local/unpacked-extensions/TabFS/fs/mnt/tabs/
thread 'main' panicked at 'failed to convert symlink to str', src/meta/symlink.rs:32:26
stack backtrace:
0: 0x559f0177c59d - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::ha61d747c17f20b60
1: 0x559f0179cd7f - core::fmt::write::h07f2f84570651f43
2: 0x559f017751d6 - std::io::Write::write_fmt::ha9833741deafc915
3: 0x559f0176d0ad - std::panicking::default_hook::{{closure}}::h866368b1d4aa0ea1
4: 0x559f0176cdb3 - std::panicking::default_hook::h99a1e75b06dc3af5
5: 0x559f0176d6af - std::panicking::rust_panic_with_hook::h27cf53aebf891aaa
6: 0x559f0177c9a9 - std::panicking::begin_panic_handler::{{closure}}::h30b6e578cdc0a578
7: 0x559f0177c6dc - std::sys_common::backtrace::__rust_end_short_backtrace::h7496ad0bd42ed35e
8: 0x559f0176d2b2 - rust_begin_unwind
9: 0x559f0179c071 - core::panicking::panic_fmt::h3bf0666e029e6bf9
10: 0x559f017a4673 - core::option::expect_failed::h49baf37a70e429a8
11: 0x559f0166d85d - <lsd::meta::symlink::SymLink as core::convert::From<&std::path::Path>>::from::hda14333d61b33c74
12: 0x559f0162ece5 - lsd::meta::Meta::from_path::hbcb48b20fa03eb6b
13: 0x559f0162d032 - lsd::meta::Meta::recurse_into::h960af5887f3612de
14: 0x559f016324c3 - lsd::core::Core::run::hcc5f592d39dd44bc
15: 0x559f016640b7 - lsd::main::hd379a35ac34cbbe7
16: 0x559f0165cd53 - std::sys_common::backtrace::__rust_begin_short_backtrace::h055595d69ddc4d43
17: 0x559f0165cd69 - std::rt::lang_start::{{closure}}::h6f95d8e8181110da
18: 0x559f0176d931 - std::rt::lang_start_internal::h21042a401dce9c71
19: 0x559f01664422 - main
20: 0x7f3afa8b7dbd - __libc_start_main
21: 0x559f0160e0ba - _start
22: 0x0 - <unknown>
๏
ผ ๏ ~ at ๏ 05:12:07 PM
โฏ \cat ~/.local/unpacked-extensions/TabFS/fs/mnt/tabs/by-id/179/title.txt
TabFS
ls
fails due to a symlink issue, but I can access files directly (somehow file autocomplete works without throwing an error)
maybe related to #7?
While poking around the file structure I noticed that the tabs/last-focused
link stopped working at some point.
After reloading the extension and fiddling around a while I finally pined down that double tapping tab with something like cat mnt/tabs/last-focused/
typed, triggering compgen
, was what killed it.
To reproduce the issue:
tabs
directory of the TabFS file system[david@darvid-pc TabFS]$ cd fs/mnt/tabs
[david@darvid-pc tabs]$ ls -lah
total 0
drwxr-xr-x 3 root root 0 Dec 31 1969 .
drwxr-xr-x 3 root root 0 Dec 31 1969 ..
drwxr-xr-x 3 root root 0 Dec 31 1969 by-id
drwxrwxrwx 3 root root 0 Dec 31 1969 by-title
--w--w--w- 1 root root 100 Dec 31 1969 create
lr--r--r-- 1 root root 8 Dec 31 1969 last-focused -> by-id/6
[david@darvid-pc tabs]$ cat last-focused/url.txt
https://github.com/osnr/TabFS/issues/new
last-focused
directory[david@darvid-pc tabs]$ compgen -c last-focused/
last-focused/url.txt
last-focused/title.txt
last-focused/text.txt
last-focused/console
last-focused/execute-script
[david@darvid-pc tabs]$ ls -lah
total 0
drwxr-xr-x 3 root root 0 Dec 31 1969 .
drwxr-xr-x 3 root root 0 Dec 31 1969 ..
drwxr-xr-x 3 root root 0 Dec 31 1969 by-id
drwxrwxrwx 3 root root 0 Dec 31 1969 by-title
--w--w--w- 1 root root 100 Dec 31 1969 create
lr--r--r-- 1 root root 8 Dec 31 1969 last-focused -> by-id/6./windows/9
[david@darvid-pc tabs]$ cat last-focused/url.txt
cat: last-focused/url.txt: No such file or directory
Notice how last-focused
now points to by-id/6./windows/9
I've had some inconsistent behavior, sometimes that "./" separating the by-id/*
and windows/*
isn't present, and it would just look like by-id/6windows/9
Is it possible to add images shown in each tab to fs?
in order to be able to keep track of updates, without having to follow issues/prs. Thank you
it do not work when the result of the request is a RSS document content.
Should be nice to find the RSS feed result of the request also in the directory.
Regards,
Any hope for the Windows crew?
Brave is a Chromium-based browser that, when reading the install script of this repo, doesn't appear to be supported.
I see install documentation mentions passing chrome
for Brave but the install script does not mention "Brave Browser.app"
.
Of course, if Brave is already supported I'd be happy to see this ticket closed. :-)
This is great for viewing and closing tabs, but could it support opening tabs as well?
Is this what the create file is for? Would be great if this is documented.
Append a dot..? Though there is room for error for tabs names beginning with a dot (append a _
for those? do some '` escaping..?)
Hi,
Installing FUSE for macOS from the FUSE for macOS website failed for me, /usr/local/lib/libosxfuse.dylib didn't exist after install. However, installing via brew worked.
[david@darvid-pc TabFS]$ ls -lah mnt/tabs/by-title
total 0
drwxrwxrwx 3 root root 0 Dec 31 1969 .
drwxr-xr-x 3 root root 0 Dec 31 1969 ..
lr--r--r-- 1 root root 12 Dec 31 1969 Llanfairpwll_-_Llanfair_PG_in_Anglesey__North_Wales__Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch_29 -> ../by-id/29
lr--r--r-- 1 root root 12 Dec 31 1969 New_Issue___osnr_TabFS_32 -> ../by-id/32
[david@darvid-pc TabFS]$ cd mnt/tabs/by-id/29/
[david@darvid-pc 29]$ cat url.txt
https://llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch.co.uk/
[david@darvid-pc 29]$ echo "http://example.com" > url.txt
[david@darvid-pc 29]$
[david@darvid-pc 29]$ cat url.txt
http://example.comlgwyngyllgogerychwyrndrobwllllantysiliogogogoch.co.uk/
[david@darvid-pc 29]$
As you can see, instead of replacing the contents with "http://example.com", it has only overwritten the first n
characters (where n
is the length of the url that is written).
I'm not sure, but I believe this is because truncate (and write?) do not affect the value that was cached when the file was opened.
logs
cd into directory
req
Object { id: 1228281408, op: "getattr", path: "/" }
background.js:646:11
resp
Object { st_mode: 16877, st_nlink: 3, st_size: 0, op: "getattr" }
background.js:674:13
req
Object { id: 1236813376, op: "getattr", path: "/tabs" }
background.js:646:11
resp
Object { st_mode: 16877, st_nlink: 3, st_size: 0, op: "getattr" }
background.js:674:13
req
Object { id: 1228281408, op: "getattr", path: "/tabs/by-id" }
background.js:646:11
resp
Object { st_mode: 16877, st_nlink: 3, st_size: 0, op: "getattr" }
background.js:674:13
req
Object { id: 1236813376, op: "getattr", path: "/tabs/by-id/29" }
background.js:646:11
resp
Object { st_mode: 16877, st_nlink: 3, st_size: 0, op: "getattr" }
background.js:674:13
cat url.txt
req
Object { id: 1228281408, op: "getattr", path: "/tabs/by-id/29/cat" }
background.js:646:11
UnixError:
UnixError moz-extension://a20c96b9-c645-476c-b5a7-4e0810d50246/background.js:25
findRoute moz-extension://a20c96b9-c645-476c-b5a7-4e0810d50246/background.js:637
onMessage moz-extension://a20c96b9-c645-476c-b5a7-4e0810d50246/background.js:658
background.js:663:13
resp
Object { op: "getattr", error: 2 }
background.js:674:13
req
Object { id: 1236813376, op: "getattr", path: "/tabs/by-id/29/url.txt" }
background.js:646:11
resp
Object { st_mode: 33206, st_nlink: 1, st_size: 74, op: "getattr" }
background.js:674:13
req
Object { id: 1228281408, op: "open", path: "/tabs/by-id/29/url.txt", flags: 32768 }
background.js:646:11
resp
Object { fh: 1, op: "open" }
background.js:674:13
req
Object { id: 1236813376, op: "read", path: "/tabs/by-id/29/url.txt", size: 131072, offset: 0, fh: 1, flags: 32768 }
background.js:646:11
resp
Object { buf: "aHR0cHM6Ly9sbGFuZmFpcnB3bGxnd3luZ3lsbGdvZ2VyeWNod3lybmRyb2J3bGxsbGFudHlzaWxpb2dvZ29nb2NoLmNvLnVrLwo=", op: "read" }
background.js:674:13
req
Object { id: 1228281408, op: "read", path: "/tabs/by-id/29/url.txt", size: 131072, offset: 74, fh: 1, flags: 32768 }
background.js:646:11
resp
Object { buf: "", op: "read" }
background.js:674:13
req
Object { id: 1228281408, op: "release", path: "/tabs/by-id/29/url.txt", fh: 1 }
background.js:646:11
resp
Object { op: "release" }
background.js:674:13
echo "http://example.com" > url.txt
req
Object { id: 1236813376, op: "getattr", path: "/tabs/by-id/29/url.txt" }
background.js:646:11
resp
Object { st_mode: 33206, st_nlink: 1, st_size: 74, op: "getattr" }
background.js:674:13
req
Object { id: 1228281408, op: "open", path: "/tabs/by-id/29/url.txt", flags: 32769 }
background.js:646:11
resp
Object { fh: 2, op: "open" }
background.js:674:13
req
Object { id: 1228281408, op: "truncate", path: "/tabs/by-id/29/url.txt", size: 0 }
background.js:646:11
resp
Object { op: "truncate" }
background.js:674:13
req
Object { id: 1228281408, op: "getattr", path: "/tabs/by-id/29/url.txt" }
background.js:646:11
resp
Object { st_mode: 33206, st_nlink: 1, st_size: 74, op: "getattr" }
background.js:674:13
req
Object { id: 1236813376, op: "write", path: "/tabs/by-id/29/url.txt", buf: "http://example.com\n", offset: 0, fh: 2, flags: 32769 }
background.js:646:11
resp
Object { size: 19, op: "write" }
background.js:674:13
req
Object { id: 1228281408, op: "release", path: "/tabs/by-id/29/url.txt", fh: 2 }
background.js:646:11
resp
Object { op: "release" }
cat url.txt
resp
Object { op: "getattr", error: 2 }
background.js:674:13
req
Object { id: 1228281408, op: "getattr", path: "/tabs/by-id/29/url.txt" }
background.js:646:11
resp
Object { st_mode: 33206, st_nlink: 1, st_size: 73, op: "getattr" }
background.js:674:13
req
Object { id: 1236813376, op: "open", path: "/tabs/by-id/29/url.txt", flags: 32768 }
background.js:646:11
resp
Object { fh: 3, op: "open" }
background.js:674:13
req
Object { id: 1228281408, op: "read", path: "/tabs/by-id/29/url.txt", size: 131072, offset: 0, fh: 3, flags: 32768 }
background.js:646:11
resp
Object { buf: "aHR0cDovL2V4YW1wbGUuY29tbGd3eW5neWxsZ29nZXJ5Y2h3eXJuZHJvYndsbGxsYW50eXNpbGlvZ29nb2dvY2guY28udWsvCg==", op: "read" }
background.js:674:13
req
Object { id: 1236813376, op: "read", path: "/tabs/by-id/29/url.txt", size: 131072, offset: 73, fh: 3, flags: 32768 }
background.js:646:11
resp
Object { buf: "", op: "read" }
background.js:674:13
req
Object { id: 1228281408, op: "release", path: "/tabs/by-id/29/url.txt", fh: 3 }
background.js:646:11
resp
Object { op: "release" }
Symlinks appear to change on ls
but I'm not certain if is the true cause. It also appears to change after the symlink is broken and there is subsequent read event.
$ uname -a
Linux 5.4.0-58-generic #64-Ubuntu SMP Wed Dec 9 08:16:25 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux )
$ fsck -N /dev/sda2
fsck from util-linux 2.34
[/sbin/fsck.ext4 (1) -- /] fsck.ext4 /dev/sda2
$ mount | grep "^/dev"
/dev/sda2 on / type ext4 (rw,relatime,errors=remount-ro)
/dev/fuse on /run/user/1000/doc type fuse (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)
I've tried the extension in Firefox Nightly 86.0a1 (2020-12-31) (64-bit) and Chromium Version 83.0.4103.116 (Developer Build) built on Debian bullseye/sid, running on Debian bullseye/sid (64-bit)
The symlinks in mnt/tabs/by-title/
appear to be dangling when broken eg:
Sarven_Capadisli_35 -> ../by-id/35ndows/10
Once the add-on is reloaded, everything is back to normal ie. when working:
Sarven_Capadisli_35 -> ../by-id/35
And when working in mnt/tabs/
:
last-focused -> 'by-id/35'$'\004'
and when broken:
last-focused -> by-id/35/11
also noted when broken:
last-focused -> by-id/35/windows/10
and:
last-focused -> by-id/35/35ndows/10
The last two appears to happen if I cause an event related to 35 eg. reading a file under tab 35.
Happy to run commands if you'd like to get to the bottom of it.
Edit:
How to reproduce:
csarven@nevrasc:/var/www/TabFS$ ls -la fs/mnt/tabs/
total 0
drwxr-xr-x 3 root root 0 Jan 1 1970 .
drwxr-xr-x 3 root root 0 Jan 1 1970 ..
drwxr-xr-x 3 root root 0 Jan 1 1970 by-id
drwxrwxrwx 3 root root 0 Jan 1 1970 by-title
--w--w--w- 1 root root 100 Jan 1 1970 create
lr--r--r-- 1 root root 9 Jan 1 1970 last-focused -> 'by-id/14'$'\004'
csarven@nevrasc:/var/www/TabFS$ ls -la fs/mnt/tabs/by-title/
total 0
drwxrwxrwx 3 root root 0 Jan 1 1970 .
drwxr-xr-x 3 root root 0 Jan 1 1970 ..
lr--r--r-- 1 root root 12 Jan 1 1970 Extensions_14 -> ../by-id/14
lr--r--r-- 1 root root 12 Jan 1 1970 Sarven_Capadisli_35 -> ../by-id/35
csarven@nevrasc:/var/www/TabFS$ ls -la fs/mnt/tabs/by-title/Sarven_Capadisli_35/
ls: cannot access 'fs/mnt/tabs/by-title/Sarven_Capadisli_35/control': No such file or directory
ls: cannot access 'fs/mnt/tabs/by-title/Sarven_Capadisli_35/debugger': No such file or directory
total 0
drwxr-xr-x 3 root root 0 Jan 1 1970 .
drwxr-xr-x 3 root root 0 Jan 1 1970 ..
-r--r--r-- 1 root root 0 Jan 1 1970 console
?????????? ? ? ? ? ? control
?????????? ? ? ? ? ? debugger
-r--r--r-- 1 root root 69627 Jan 1 1970 dom.html
--w--w--w- 1 root root 100 Jan 1 1970 execute-script
-r--r--r-- 1 root root 419 Jan 1 1970 text.txt
-r--r--r-- 1 root root 17 Jan 1 1970 title.txt
-rw-rw-rw- 1 root root 20 Jan 1 1970 url.txt
lr--r--r-- 1 root root 20 Jan 1 1970 window -> ../../../windows/10
csarven@nevrasc:/var/www/TabFS$ cat fs/mnt/tabs/by-title/Sarven_Capadisli_35/url.txt
cat: fs/mnt/tabs/by-title/Sarven_Capadisli_35/url.txt: No such file or directory
I've reloaded the extension and then:
csarven@nevrasc:/var/www/TabFS$ cat fs/mnt/tabs/by-title/Sarven_Capadisli_35/url.txt
https://csarven.ca/
Hi folks. Looked everywhere in extension, Chrome Web Store, etc. Can't seem to locate the TabFS extension.
Thank you,
-Tony
Thank you for the nice project!
I could not start it probably because I got Chromium installed by flatpak which has some kind of sandboxed environment.
I'm wondering anyone has experience installing TabFS with https://github.com/flathub/org.chromium.Chromium on Linux? ๐ค
In Chromium I can see the following error message:
Unchecked runtime.lastError: Native host has exited.
Thank you ๐
First: this is fantastic work, thank you!
My main question is around the debugging warning that appears in every tab:
I'm curious if there are alternate sources for some of the information that wouldn't require the debugger API and thus the debugging warning.
I have a tiny native host extension I use to expose my tabs via local HTTP, which I then use Alfred to search, so I can e.g. select a tab by searching URLs and titles when I lose one in a window... It uses the tabs
permission to access tab metadata with chrome.windows.getAll({populate: true})
; you get ID, URL, and title from that API.
Would it be useful to use the other extension APIs where possible and have the debugger integration be optional?
Alternately, a good solution for always using --silent-debugger-extension-api
would be useful, I think (along with documentation of the security concerns if you use other extensions with the debugger
permission).
I can't see a license for this project, currently?
I'd suspect TabFS could be exploited easily (a targeted attack, especially considering the current audience, isn't that unrealistic).
It would probably be with a passkey, what can be automagically shared with 'first client to interact will get full admin' type of scenario.
ls -la Development/TabFS/fs/mnt/tabs/by-title
total 0
drwxrwxrwx 3 root root 0 Jan 1 1970 .
drwxr-xr-x 3 root root 0 Jan 1 1970 ..
lr--r--r-- 1 root root 12 Jan 1 1970 Buffer___Node.js_v15.5.0_Documentation_62 -> ../by-id/62??V
lr--r--r-- 1 root root 12 Jan 1 1970 Extensions_22 -> ../by-id/22??V
lr--r--r-- 1 root root 12 Jan 1 1970 Issues___osnr_TabFS_51 -> ../by-id/51??V
lr--r--r-- 1 root root 12 Jan 1 1970 Syncthing_23 -> ../by-id/23??V
The text changes on each reload of the extension
ls -la Development/TabFS/fs/mnt/tabs/by-title
total 0
drwxrwxrwx 3 root root 0 Jan 1 1970 .
drwxr-xr-x 3 root root 0 Jan 1 1970 ..
lr--r--r-- 1 root root 12 Jan 1 1970 Buffer___Node.js_v15.5.0_Documentation_62 -> ../by-id/62y^U
lr--r--r-- 1 root root 12 Jan 1 1970 Extensions_22 -> ../by-id/22y^U
lr--r--r-- 1 root root 12 Jan 1 1970 New_Issue___osnr_TabFS_51 -> ../by-id/51y^U
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.