Skip to content

Repository files navigation

linkwise

Your Linkwise library, from the terminal. Save, search, read and export without leaving the shell.

A single static binary with no runtime to install alongside it. Every command is a thin wrapper over one endpoint of the Linkwise public API, so anything the CLI can do, a script can do too.

Install

brew install linkwiseapp/tap/linkwise
npm install -g @linkwise/cli
curl -fsSL https://linkwise.app/install.sh | sh

The shell installer and the npm package both verify the release checksum before unpacking anything. If it does not match, nothing is written.

Update

linkwise update          # what is newest, and the command that installs it
linkwise update --run    # run that command

Each channel owns the file it put on disk, so the right command is not the same for everyone. update works it out from where the binary actually lives:

brew upgrade --cask linkwiseapp/tap/linkwise   # Homebrew
npm install -g @linkwise/cli@latest            # npm
curl -fsSL https://linkwise.app/install.sh | sh  # shell installer

Once a day, a command run at a terminal checks in the background and prints one line on stderr when a newer release is out. The lookup runs alongside the work you asked for rather than delaying it, and an unfinished one leaves the news for next time. LINKWISE_NO_UPDATE_CHECK turns it off; it is already off when output is piped, on --json, and wherever CI is set.

Switching from the shell installer to Homebrew means removing the old binary first: the installer writes a real file where the cask wants its own symlink, so brew install stops with there is already a Binary at ... until you rm it. Going the other way, the installer refuses on its own rather than breaking your Homebrew install.

Get started

linkwise auth login          # paste a key from linkwise.app/developers/dashboard
linkwise save https://example.com --description "why I saved it"
linkwise ls --limit 5
linkwise search postgres
linkwise read <id> > piece.md

The key is checked against the API before it is stored, so a mistyped one fails at the prompt rather than on your next command. It is kept in the system keychain; on a machine without one the CLI writes it to a 0600 file and says so.

The full-screen interface

Run linkwise with no arguments in a terminal and it opens a reader for the whole library: browse everything, what is unread, what is archived, or one collection, then read the extracted article in place.

 linkwise v0.2.0            q:quit | /:search | j/k:nav | d:light theme | enter:select

        █     █████ █   █ █   █ █   █ █████ █████ █████
        █       █   ██  █ █  █  █   █   █   █     █
        █       █   █ █ █ ███   █ █ █   █   █████ ████
        █       █   █  ██ █  █  ██ ██   █       █ █
        █████ █████ █   █ █   █ █   █ █████ █████ █████
        Save it now. Actually read it later.

        Library
        > Browse All
          Browse Unread
          Browse Archived
          Browse Collections        23

j and k move, enter opens, esc goes back, / searches and ? lists every key. On a link: o opens it in the browser, y copies the URL, e archives it, u marks it read and p pins it.

d switches between the light and dark palettes and remembers the choice in config.toml. NO_COLOR drops it to plain text, as everywhere else.

Anywhere the interface cannot be drawn, linkwise prints help exactly as it did before: piped output, no terminal on stdin, --json, or not signed in. A script that runs the bare command sees what it always saw.

Output

A table when stdout is a terminal, NDJSON when it is a pipe. Detected rather than flagged, and --json forces it either way.

linkwise ls --limit 3                              # a table
linkwise ls --limit 3 | jq -r '.url'               # NDJSON
linkwise ls --collection reading --json > out.json

Exit codes

Distinct per failure class, so a script can tell an expired key from a missing link without parsing stderr.

Code Meaning
0 Success
1 Unclassified, including a network failure
2 Bad flags or a missing argument. Nothing was sent
3 No key, or it is invalid, expired or revoked
4 The key lacks the scope, or API access is disabled
5 No such link, collection or tag
6 Rate limited. The CLI already waited and retried once
7 A quota is exhausted, or the endpoint is Pro only

Configuration

~/.config/linkwise/config.toml, with settings resolved in this order, first one wins: a command flag, then the environment, then the config file, then the default.

Variable Meaning
LINKWISE_TOKEN Personal access token. Overrides the keychain, so CI never picks up a developer's key
LINKWISE_API Base URL, for pointing at another deploy
LINKWISE_PROFILE Which profile to use, for multiple accounts
NO_COLOR Any value disables colour, per no-color.org

The full-screen interface reads one more setting, which it writes itself when you press d:

[tui]
theme = "dark"   # or "light"

Build from source

go build -o linkwise ./cmd/linkwise
./linkwise --version

scripts/smoke.sh runs the surface a fake server cannot prove (the keychain, tty detection, real exit codes) against the live API. It needs LINKWISE_TOKEN set to a read-and-write key, and it saves and deletes one link.

Documentation

Full command reference, authentication and exit codes: https://linkwise.app/developers/cli

Licence

MIT.

About

The Linkwise command line interface

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages