chore: updated docs and added cli arg functionality 17d07f49
Steve · 2026-04-13 22:21 3 file(s) · +151 −11
apps/jotts/src/main.rs +10 −1
1 1
use clap::{Parser, Subcommand};
2 +
use std::path::PathBuf;
2 3
3 4
#[derive(Parser)]
4 5
#[command(name = "jotts", about = "Markdown notes — TUI, server, and CLI")]
10 11
    /// API key for authenticated operations
11 12
    #[arg(short = 'k', long, env = "JOTTS_API_KEY")]
12 13
    api_key: Option<String>,
14 +
15 +
    /// File path to create a note from
16 +
    #[arg(value_name = "FILE")]
17 +
    file: Option<PathBuf>,
13 18
14 19
    #[command(subcommand)]
15 20
    command: Option<Commands>,
57 62
            jotts::tui::run_auth()?;
58 63
        }
59 64
        None => {
60 -
            jotts::tui::run_interactive(cli.remote, cli.api_key)?;
65 +
            if let Some(file) = cli.file {
66 +
                jotts::tui::run_file_upload(cli.remote, cli.api_key, file)?;
67 +
            } else {
68 +
                jotts::tui::run_interactive(cli.remote, cli.api_key)?;
69 +
            }
61 70
        }
62 71
    }
63 72
apps/jotts/src/tui.rs +30 −0
11 11
    text::{Line, Span, Text},
12 12
    widgets::{Block, Borders, Clear, List, ListItem, ListState, Paragraph, Widget, Wrap},
13 13
};
14 +
use std::path::PathBuf;
14 15
use std::time::{Duration, Instant};
15 16
16 17
fn edit_in_external_editor(
511 512
        false,
512 513
        Some("http://localhost:3000".to_string()),
513 514
    ))
515 +
}
516 +
517 +
pub fn run_file_upload(
518 +
    remote: Option<String>,
519 +
    api_key: Option<String>,
520 +
    file: PathBuf,
521 +
) -> Result<(), Box<dyn std::error::Error>> {
522 +
    let (backend, _, remote_url) = resolve_backend(remote, api_key)?;
523 +
524 +
    let title = file
525 +
        .file_stem()
526 +
        .ok_or("Invalid file path")?
527 +
        .to_string_lossy()
528 +
        .to_string();
529 +
    let content = std::fs::read_to_string(&file)
530 +
        .map_err(|e| format!("Failed to read file: {}", e))?;
531 +
    let note = backend
532 +
        .create_note(&title, &content)
533 +
        .map_err(|e| format!("{}", e))?;
534 +
    let link = match &remote_url {
535 +
        Some(url) => format!("{}/notes/{}", url.trim_end_matches('/'), note.short_id),
536 +
        None => note.short_id.clone(),
537 +
    };
538 +
    println!("{}", link);
539 +
    if let Ok(mut clipboard) = Clipboard::new() {
540 +
        let _ = clipboard.set_text(&link);
541 +
        println!("\u{2714} Copied to clipboard!");
542 +
    }
543 +
    Ok(())
514 544
}
515 545
516 546
pub fn run_auth() -> Result<(), Box<dyn std::error::Error>> {
docs/docs/pages/apps/jotts.mdx +111 −10
8 8
- Password authentication with session cookies
9 9
- Create, edit, and delete markdown notes
10 10
- Markdown rendering with strikethrough, tables, and task lists
11 +
- Interactive TUI with authenticated access for note management
11 12
- Dark themed UI with Commit Mono font
12 13
- SQLite for persistent storage
13 14
15 +
## Install
16 +
17 +
Jotts can be installed several ways:
18 +
19 +
### Homebrew
20 +
21 +
```bash
22 +
brew install stevedylandev/tap/jotts
23 +
```
24 +
25 +
### Releases
26 +
27 +
Visit the [releases](https://github.com/stevedylandev/andromeda/releases?q=jotts&expanded=true) page for binaries and install scripts.
28 +
14 29
## Configure
15 30
16 31
### Environment Variables
17 32
18 33
| Variable | Description | Default |
19 34
|---|---|---|
20 -
| `JOTTS_PASSWORD` | Password for login authentication | `changeme` |
35 +
| `JOTTS_PASSWORD` | Password for web login authentication | `changeme` |
36 +
| `JOTTS_API_KEY` | API key for protecting `/api/*` endpoints | — |
21 37
| `JOTTS_DB_PATH` | SQLite database file path | `jotts.sqlite` |
22 38
| `HOST` | Server bind address | `127.0.0.1` |
23 39
| `PORT` | Server port | `3000` |
24 40
| `COOKIE_SECURE` | Enable HTTPS-only cookies | `false` |
25 41
42 +
If `JOTTS_API_KEY` is not set, `/api/*` routes return `403`.
43 +
26 44
## Deploy
27 45
28 46
### Railway
29 47
30 -
The easiest way to deploy Jotts is with the one-click Railway template. See the [Deploying with Railway](/deploy-railway) guide for a walkthrough of the process. Jotts requires `JOTTS_PASSWORD` to be set during the configure step.
48 +
The easiest way to deploy Jotts is with the one-click Railway template. See the [Deploying with Railway](/deploy-railway) guide for a walkthrough of the process. Jotts requires `JOTTS_PASSWORD` to be set during the configure step. Set `JOTTS_API_KEY` too if you want to use the TUI against your remote instance.
31 49
32 50
[![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/deploy/DLhUhH?referralCode=JGcIp6)
33 51
44 62
45 63
### Binary
46 64
47 -
Install with Homebrew:
65 +
```bash
66 +
cargo build --release -p jotts
67 +
```
68 +
69 +
The resulting binary is self-contained with all assets embedded. Copy it to your server with a configured `.env` file and run it directly.
70 +
71 +
## Use
72 +
73 +
### CLI
74 +
75 +
```
76 +
jotts [OPTIONS] [FILE] [COMMAND]
77 +
```
78 +
79 +
#### Commands
80 +
81 +
| Command | Description |
82 +
|---|---|
83 +
| `server` | Start the web server |
84 +
| `tui` | Launch the interactive TUI |
85 +
| `auth` | Save remote URL and API key to config file |
86 +
87 +
#### Arguments
88 +
89 +
| Argument | Description |
90 +
|---|---|
91 +
| `[FILE]` | File path to create a note from |
92 +
93 +
#### Options
94 +
95 +
| Option | Description |
96 +
|---|---|
97 +
| `-r, --remote <URL>` | Remote server URL (env: `JOTTS_REMOTE_URL`) |
98 +
| `-k, --api-key <KEY>` | API key for authenticated operations (env: `JOTTS_API_KEY`) |
99 +
100 +
### Server
101 +
102 +
Start the web server with:
48 103
49 104
```bash
50 -
brew install stevedylandev/tap/jotts
105 +
jotts server --port 3000 --host localhost
51 106
```
52 107
53 -
Or grab a prebuilt binary from the [releases page](https://github.com/stevedylandev/andromeda/releases?q=jotts&expanded=true).
108 +
Log in at `/login` with your configured password. From there you can create, edit, and delete markdown notes. Notes support GitHub-flavored markdown including strikethrough, tables, and task lists.
54 109
55 -
You can also build from source:
110 +
#### API Endpoints
111 +
112 +
| Method | Endpoint | Description |
113 +
|---|---|---|
114 +
| `GET` | `/api/notes` | List all notes |
115 +
| `POST` | `/api/notes` | Create a note (`{"title": "...", "content": "..."}`) |
116 +
| `GET` | `/api/notes/{short_id}` | Get a note by ID |
117 +
| `PUT` | `/api/notes/{short_id}` | Update a note |
118 +
| `DELETE` | `/api/notes/{short_id}` | Delete a note by ID |
119 +
120 +
All `/api/*` endpoints require an `x-api-key` header matching `JOTTS_API_KEY`.
121 +
122 +
### TUI
123 +
124 +
The Jotts TUI makes it easy to create, edit, and manage your notes either locally or remotely.
56 125
57 126
```bash
58 -
cargo build --release -p jotts
127 +
# Launch TUI (default behavior when no file argument is given)
128 +
jotts
129 +
130 +
# Or explicitly
131 +
jotts tui
132 +
133 +
# With remote options
134 +
jotts -r https://your-jotts-instance.com -k your-api-key
59 135
```
60 136
61 -
The resulting binary is self-contained with all assets embedded. Copy it to your server with a configured `.env` file and run it directly.
137 +
#### Local Access
62 138
63 -
## Use
139 +
If you are running `jotts` in the same directory as the `jotts.sqlite` file created by the server instance, the TUI will automatically access the database locally.
140 +
141 +
#### Remote Access
142 +
143 +
To access a remote instance:
144 +
- Set `JOTTS_API_KEY` on your server instance
145 +
- Run `jotts auth` to enter your server URL and API key, stored under `$HOME/.config/jotts`
64 146
65 -
Log in at `/login` with your configured password. From there you can create, edit, and delete markdown notes. Notes support GitHub-flavored markdown including strikethrough, tables, and task lists.
147 +
#### Keybindings
148 +
149 +
| Key | Action |
150 +
|---|---|
151 +
| `j`/`Down` | Move down / Scroll down |
152 +
| `k`/`Up` | Move up / Scroll up |
153 +
| `Enter` | Focus content pane |
154 +
| `Esc` | Back / Quit |
155 +
| `y` | Copy note content |
156 +
| `Y` | Copy note link |
157 +
| `o` | Open in browser |
158 +
| `e` | Edit note |
159 +
| `E` | Edit in `$EDITOR` |
160 +
| `d` | Delete note |
161 +
| `c` | Create note |
162 +
| `/` | Search notes |
163 +
| `^W` | Toggle word wrap (edit) |
164 +
| `r` | Refresh notes (remote only) |
165 +
| `q` | Quit |
166 +
| `?` | Toggle help |