diff --git a/README.md b/README.md index 20ddaa4..4091662 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ bun run compile Requires [Bun](https://bun.sh) >= 1.2 and [Zig](https://ziglang.org/) (OpenTUI native bindings). -## Configuration +## Quick start Config and cookies are stored under `~/.codimd/` by default. @@ -56,33 +56,280 @@ codimd-cli whoami codimd-cli list ``` +You can also pass the server per invocation: + +```bash +codimd-cli -s https://your-codimd.example.com list +``` + +Run `codimd-cli --help` or `codimd-cli --help` for the full usage text. + +## Configuration + +Settings are merged from `~/.codimd/config.json`, environment variables, and CLI flags (highest priority). + | Variable | Description | |----------|-------------| | `CMD_CLI_SERVER_URL` | CodiMD server URL | | `CMD_CLI_CONFIG_DIR` | Config directory (default `~/.codimd`) | -| `CMD_CLI_COOKIE_PATH` | Cookie file path | -| `CMD_CLI_ID` / `CMD_CLI_PASSWORD` | Non-interactive login | - -## Commands - -| Command | Description | -|---------|-------------| -| `login` | Sign in with email/password or `--ldap` | -| `logout` | Clear session | -| `whoami` | Current user info (`GET /me`) | -| `config set/show` | Manage local config | -| `list` | List owned notes (`GET /api/notes/myNotes`) | -| `show ` | Print note markdown (`GET /:id/download`) | -| `info ` | Note metadata JSON (`GET /:id/info`) | -| `create [file]` | Create note from file or stdin (`POST /new`) | -| `import [file]` | Alias of `create` | -| `update [file]` | Update note content (`PUT /api/notes/:id`) | -| `delete ` | Delete owned note (`DELETE /api/notes/:id`) | -| `export [file]` | Export note (`--md`, `--html`, `--pdf`) | -| `history` | Browsing history (`GET /history`, `--pin` / `--unpin`) | -| `open ` | Open note URL in the default browser | -| `tui` | Interactive note browser (OpenTUI) | -| *(stdin pipe)* | `cat doc.md \| codimd-cli` creates a note | +| `CMD_CLI_COOKIE_PATH` | Cookie file path (default `~/.codimd/cookies.json`) | +| `CMD_CLI_ID` | Email or username for non-interactive login | +| `CMD_CLI_PASSWORD` | Password for non-interactive login | + +### Global options + +Available on every command: + +| Option | Description | +|--------|-------------| +| `-s, --server ` | Override the configured CodiMD server URL | +| `-h, --help` | Show help (short descriptions with `-h`, full with `--help`) | +| `-V, --version` | Print version | + +## Command reference + +### Authentication + +#### `login` + +Sign in with email/password or LDAP. Prompts interactively when credentials are not provided. + +```bash +codimd-cli login +codimd-cli login -u you@example.com +codimd-cli login --ldap -u ldap-user +``` + +| Option | Description | +|--------|-------------| +| `-u, --id ` | Email or username | +| `--ldap` | Use LDAP authentication (`POST /auth/ldap`) | + +Credentials can also come from `CMD_CLI_ID` / `CMD_CLI_PASSWORD` or saved config. + +#### `logout` + +Clear the session cookie and call the server logout endpoint. + +```bash +codimd-cli logout +``` + +#### `whoami` + +Print the current user as JSON (`GET /me`). + +```bash +codimd-cli whoami +``` + +### Configuration + +#### `config set ` + +Persist a config value to `~/.codimd/config.json`. + +```bash +codimd-cli config set serverUrl https://your-codimd.example.com +``` + +Supported keys: `serverUrl`. + +#### `config show` + +Print the effective merged configuration as JSON. + +```bash +codimd-cli config show +``` + +### Notes + +Note IDs are the short alphanumeric strings from CodiMD URLs (for example `abc123` from `https://your-codimd.example.com/abc123`). + +#### `list` + +List notes you own (`GET /api/notes/myNotes`). + +```bash +codimd-cli list +codimd-cli list --json +``` + +| Option | Description | +|--------|-------------| +| `--json` | Output raw JSON instead of a table | + +#### `show ` + +Print note markdown to stdout (`GET /:noteId/download`). + +```bash +codimd-cli show abc123 +codimd-cli show abc123 > note.md +``` + +#### `info ` + +Print note metadata as JSON (`GET /:noteId/info`). + +```bash +codimd-cli info abc123 +``` + +#### `create [file]` / `import [file]` + +Create a note from a file or stdin (`POST /new`). `import` is an alias of `create`. + +```bash +codimd-cli create draft.md +echo "# Hello" | codimd-cli create +cat draft.md | codimd-cli import +``` + +On success, prints the new note URL to stdout. + +#### `update [file]` + +Replace note content from a file or stdin (`PUT /api/notes/:noteId`). + +```bash +codimd-cli update abc123 revised.md +cat revised.md | codimd-cli update abc123 +``` + +#### `delete ` + +Delete a note you own (`DELETE /api/notes/:noteId`). Prompts for confirmation unless `--yes` is passed. + +```bash +codimd-cli delete abc123 +codimd-cli delete abc123 --yes +``` + +| Option | Description | +|--------|-------------| +| `-y, --yes` | Skip confirmation prompt | + +#### `export [output]` + +Export a note to stdout or a file. + +```bash +codimd-cli export abc123 # markdown to stdout +codimd-cli export abc123 --html # HTML to stdout +codimd-cli export abc123 --pdf out.pdf # PDF to file +codimd-cli export abc123 --md backup.md # markdown to file +``` + +| Option | Description | +|--------|-------------| +| `--md` | Export as Markdown (default) | +| `--html` | Export as HTML | +| `--pdf` | Export as PDF | + +When no output path is given, text formats go to stdout; PDF is written as binary to stdout. + +#### `open ` + +Open the note URL in your default browser and print the URL. + +```bash +codimd-cli open abc123 +``` + +### History + +#### `history` + +Show browsing history (`GET /history`), or pin/unpin entries. + +```bash +codimd-cli history +codimd-cli history --json +codimd-cli history --pin abc123 +codimd-cli history --unpin abc123 +``` + +| Option | Description | +|--------|-------------| +| `--json` | Output raw JSON | +| `--pin ` | Pin a history entry | +| `--unpin ` | Unpin a history entry | + +### Interactive + +#### `tui` + +Launch the OpenTUI note browser. See [Interactive TUI](#interactive-tui) for keyboard shortcuts. + +```bash +codimd-cli tui +``` + +### Stdin shortcut + +When no subcommand is given and stdin is not a TTY, `codimd-cli` reads stdin and creates a note (same as `create`): + +```bash +cat doc.md | codimd-cli +pbpaste | codimd-cli -s https://your-codimd.example.com +``` + +Prints the new note URL to stdout. + +## Shell completions + +Tab completion for commands and flags is built in via Cliffy's `CompletionsCommand`. No extra packages are required beyond the existing `@cliffy/command` dependency. + +Generate and enable completions for your shell: + +### Bash + +Add to `~/.bashrc`: + +```bash +source <(codimd-cli completions bash) +``` + +### Zsh + +Add to `~/.zshrc`: + +```bash +source <(codimd-cli completions zsh) +``` + +If you use Oh My Zsh, you can instead save the script once: + +```bash +codimd-cli completions zsh > "${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/_codimd-cli" +``` + +### Fish + +Either load in the current session: + +```fish +codimd-cli completions fish | source +``` + +Or install persistently: + +```fish +mkdir -p ~/.config/fish/completions +codimd-cli completions fish > ~/.config/fish/completions/codimd-cli.fish +``` + +Restart your shell or `source` the updated config file. Completions cover subcommands (`list`, `show`, …) and global flags such as `--server`. + +To inspect the generated script without enabling it: + +```bash +codimd-cli completions bash +codimd-cli completions zsh +codimd-cli completions fish +``` ## CodiMD API mapping diff --git a/src/cli.ts b/src/cli.ts index c059da9..76bff0a 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,6 +1,7 @@ #!/usr/bin/env bun import { Command } from "@cliffy/command"; +import { CompletionsCommand } from "@cliffy/command/completions"; import pkg from "../package.json" with { type: "json" }; import { config } from "./config"; @@ -63,7 +64,8 @@ const cli = new Command() .command("history", historyCommand) .command("tui", tuiCommand) .command("delete", deleteNoteCommand) - .command("open", openCommand); + .command("open", openCommand) + .command("completions", new CompletionsCommand()); if (import.meta.main) { await cli.parse(getCliArgs());