@getoatmilk/cli 0.0.0-stage → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +680 -0
- package/README.md +228 -2
- package/dist/oatmilk.js +621 -0
- package/package.json +44 -4
package/README.md
CHANGED
|
@@ -1,3 +1,229 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Oatmilk CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Oatmilk in your terminal. Browse and act on your company's books in a full-screen app, talk to Ask AI, or script
|
|
4
|
+
everything headless — with your own permissions, in the company you choose.
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
npx @getoatmilk/cli
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
Requires Node.js 22 or newer.
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
curl -fsSL https://getoatmilk.com/install.sh | sh # macOS and Linux; updates itself
|
|
16
|
+
npx @getoatmilk/cli # try it without installing
|
|
17
|
+
npm install -g @getoatmilk/cli # then run: oatmilk
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`pnpm add -g @getoatmilk/cli`, `yarn global add @getoatmilk/cli` and `bun add -g @getoatmilk/cli` work too. Each
|
|
21
|
+
GitHub release also has standalone binaries for macOS, Linux and Windows that don't need Node.js, with SHA-256
|
|
22
|
+
checksums.
|
|
23
|
+
|
|
24
|
+
`oatmilk update` installs the newest version the way oatmilk was installed. When one is out, the app shows `↑ 0.3.0 ⌃U`
|
|
25
|
+
at the top right; `⌃U` installs it. `oatmilk update auto|notify|off` chooses whether it updates by itself.
|
|
26
|
+
|
|
27
|
+
## First run
|
|
28
|
+
|
|
29
|
+
The first time you run `oatmilk`, it asks one question: how you want to use Oatmilk.
|
|
30
|
+
|
|
31
|
+
| Choice | What it does |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| **Sign in to Oatmilk** | Your account at getoatmilk.com, nothing to install. When Ollama or LM Studio runs a model that calls tools, it offers to run Ask AI on it, so your questions stay on this computer while your books stay in Oatmilk. |
|
|
34
|
+
| **Keep everything on this computer** | Your account, books, files and every model here, with no sign-up. Needs Docker; the first start takes about 10 minutes. |
|
|
35
|
+
| **More options** | Choose for each part (sign-in, books, files, Ask AI and agents, classifiers, reading documents, email, web research: here, in the cloud, or off), your own cloud services with AI here, or an Oatmilk your team runs. |
|
|
36
|
+
|
|
37
|
+
Every step shows where you are (`2/5`), and the setup says how local it is in words (`85% local`). For the local
|
|
38
|
+
choices, setup finds Ollama or LM Studio, picks models that fit (a chat model that calls tools and reads images, and a
|
|
39
|
+
decision model for classifiers when Ollama serves them), downloads missing ones into Ollama, starts Oatmilk in Docker
|
|
40
|
+
(or from a source checkout with `bun run dev`), asks your name and your company's name, and signs the terminal in. You
|
|
41
|
+
never sign in on this computer; the browser gets a password setup shows once (`oatmilk local password` shows it again).
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
oatmilk setup # the same screens again
|
|
45
|
+
oatmilk setup --local --yes # everything here without questions (Ollama or LM Studio running)
|
|
46
|
+
oatmilk setup --local --cloud-for agents --yes # everything here except Ask AI (AI_GATEWAY_API_KEY in the environment)
|
|
47
|
+
oatmilk setup --local --models lmstudio --model qwen/qwen3.5-9b --company "Acme" --yes
|
|
48
|
+
oatmilk setup --cloud # Oatmilk Cloud
|
|
49
|
+
oatmilk status # where each part runs, the server, the models, Ask AI, who's signed in
|
|
50
|
+
oatmilk local start | stop | restart | logs | open | password | backup
|
|
51
|
+
oatmilk models # Ollama and LM Studio here, and what Oatmilk uses
|
|
52
|
+
oatmilk models test | pull tev1 | use --models lmstudio --restart
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Running it locally needs Docker and [Bun](https://bun.sh), and Oatmilk's source: setup uses the checkout you're in, or
|
|
56
|
+
downloads one with git. Cloud keys for a mix (Clerk, PostgreSQL, S3, AI Gateway, Resend, Tavily) are asked for in the
|
|
57
|
+
setup screens, or read from the environment with `--yes`. They're kept only in the local Oatmilk's own settings file.
|
|
58
|
+
|
|
59
|
+
## Sign in
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
oatmilk login # opens your browser; approve, then come back to the terminal
|
|
63
|
+
oatmilk login --device # SSH or no browser: sign in on any device, paste back the code
|
|
64
|
+
oatmilk login --api-key # paste an API key from Settings › Developer (or pipe it in)
|
|
65
|
+
oatmilk whoami # who, which company, which permissions
|
|
66
|
+
oatmilk orgs use "Contoso" # switch company
|
|
67
|
+
oatmilk login --password # an account on your own Oatmilk, with its email and password
|
|
68
|
+
oatmilk logout # sign out and revoke the token
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
On an Oatmilk that setup made on this computer, the terminal signs itself in with the account's saved password.
|
|
72
|
+
`oatmilk logout` forgets that password too, so you stay signed out until `oatmilk login --password`.
|
|
73
|
+
|
|
74
|
+
Browser sign-in is the same OAuth flow AI apps use for Oatmilk's MCP server: the CLI registers itself once, signs in
|
|
75
|
+
with PKCE through a one-time redirect to `localhost`. Your role in each company still decides what you can do. Tokens
|
|
76
|
+
refresh on their own. They are saved in `~/.config/oatmilk/credentials.json` (`%APPDATA%\oatmilk` on Windows), readable only by
|
|
77
|
+
you.
|
|
78
|
+
|
|
79
|
+
An API key belongs to one company and has exactly the permissions chosen when it was made.
|
|
80
|
+
|
|
81
|
+
## Ask AI on your own model
|
|
82
|
+
|
|
83
|
+
Ask AI in the terminal can think on Ollama, LM Studio or any OpenAI-compatible server on your computer, with your
|
|
84
|
+
books wherever they are, Oatmilk Cloud included. The model reads them through Oatmilk's tools, signed in as you, and
|
|
85
|
+
asks before every change. Your questions, its answers and what it reads stay on your computer.
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
oatmilk ai use ollama # starts Ollama if needed, downloads a model if it has none, checks it calls tools
|
|
89
|
+
oatmilk ai use lmstudio --model qwen/qwen3.5-9b
|
|
90
|
+
oatmilk ai # where Ask AI thinks, and the models found here
|
|
91
|
+
oatmilk ai use oatmilk # back to Oatmilk's AI
|
|
92
|
+
oatmilk -p "What needs me today?" --ai local
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
In the app, `/model` switches at once, and the top bar shows the model in use.
|
|
96
|
+
|
|
97
|
+
## Log hours as a contractor
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
oatmilk hours # this pay period: what's logged, what's not sent, when it's due
|
|
101
|
+
oatmilk hours add 2h "Design review" # also 1h30m, 90m, 1.5 or 1:30; --date yesterday, mon or 2026-10-06
|
|
102
|
+
oatmilk hours submit # send it for review
|
|
103
|
+
oatmilk hours none # no work this period
|
|
104
|
+
oatmilk hours use "Acme" # when you work for more than one company
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Running `oatmilk` opens your hours, and `a` logs time one question at a time. To log hours by asking Claude or
|
|
108
|
+
ChatGPT, connect them to `https://app.getoatmilk.com/api/mcp?toolset=contractor` (`oatmilk mcp config` prints it).
|
|
109
|
+
|
|
110
|
+
## Add receipts and connect your data
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
oatmilk add receipt.pdf "lunch photo.jpg" # like Add a receipt; adding the same file again does nothing
|
|
114
|
+
oatmilk connect # receipts by email, Gmail, banks, Wise, Stripe, Notion, Drive
|
|
115
|
+
oatmilk connect receipts # the address to forward receipts to
|
|
116
|
+
oatmilk connect gmail # opens the page where you connect it
|
|
117
|
+
oatmilk sync # Wise and Stripe, now
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Provider keys and sign-ins are entered only in Oatmilk in the browser; the terminal opens the right page.
|
|
121
|
+
|
|
122
|
+
## The app
|
|
123
|
+
|
|
124
|
+
Run `oatmilk` (or `oatmilk "What needs me today?"` to start with a question).
|
|
125
|
+
|
|
126
|
+
- **Sidebar** — the same pages as the web workspace for your role: Home, Inbox, Checklist, Transactions,
|
|
127
|
+
Reimbursements, Invoices, Reports, Agreements, Contractors, Settings, and more.
|
|
128
|
+
- **Lists** — search with `/`, move with `↑↓` or `j k`, open with `⏎`, switch views with `[ ]`. The record opens
|
|
129
|
+
beside the list, with its actions on single keys (approve, categorize, add a note, send, void…); `o` opens it in
|
|
130
|
+
the browser. Lists load more as you scroll.
|
|
131
|
+
- **⌃K** — jump to any page, find transactions, email, invoices and contractors, or run any API action.
|
|
132
|
+
- **Ask AI** — the message box at the bottom is always there. It is the workspace's Ask AI, with the same tools, the
|
|
133
|
+
screen you're on as context, and the same approvals: it asks before deleting, voiding, granting access or emailing
|
|
134
|
+
people. Your chats carry over between the terminal and the browser.
|
|
135
|
+
- **Keys** — `Tab` moves between the sidebar, the screen and the message box. `⌃O` shows or hides the chat, `⌃G`
|
|
136
|
+
opens a page Ask AI offered, `⌃B` goes back, `?` lists every key, and `/` in the message box lists commands.
|
|
137
|
+
- **Themes** — the same themes as the browser, fitted to a light or dark terminal. `/theme` tries each one live;
|
|
138
|
+
`⏎` keeps it.
|
|
139
|
+
|
|
140
|
+
## Your data
|
|
141
|
+
|
|
142
|
+
```sh
|
|
143
|
+
oatmilk export # every record (a ZIP of each table) and every file, into a folder
|
|
144
|
+
oatmilk export --out ~/backup --no-files
|
|
145
|
+
oatmilk orgs close # close the company for good: offers an export, then asks for its name
|
|
146
|
+
oatmilk orgs close --confirm "Acme" --yes
|
|
147
|
+
oatmilk wipe # remove every sign-in, setting and history from this computer
|
|
148
|
+
oatmilk wipe --local-data # and delete the local Oatmilk's companies, accounts and files
|
|
149
|
+
oatmilk local wipe # only the local Oatmilk's data
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Changing where Oatmilk runs doesn't move the books by themselves, and setup says so. `oatmilk local backup` saves a
|
|
153
|
+
local Oatmilk's database and files to restore elsewhere with the same `self-host/.env`; between Oatmilk Cloud and this
|
|
154
|
+
computer, `oatmilk export --cloud` or `--local` keeps a full copy.
|
|
155
|
+
|
|
156
|
+
Exporting and closing need an administrator. The web app has the same in Settings › Your data, and the terminal app
|
|
157
|
+
in Settings (Account and Privacy tabs).
|
|
158
|
+
|
|
159
|
+
## Headless
|
|
160
|
+
|
|
161
|
+
Everything works without the app, for scripts, CI and other agents.
|
|
162
|
+
|
|
163
|
+
```sh
|
|
164
|
+
oatmilk -p "Which receipts am I missing this month?"
|
|
165
|
+
oatmilk exec "Categorize the Uber rides as Travel" --yes # approve changes without asking
|
|
166
|
+
oatmilk exec "What changed?" --output-format stream-json # one JSON event per line
|
|
167
|
+
oatmilk exec --continue "And last month?" # continue your latest chat
|
|
168
|
+
echo "Summarize overdue invoices" | oatmilk exec --output-format json
|
|
169
|
+
|
|
170
|
+
oatmilk search uber --status needs_you --json
|
|
171
|
+
oatmilk api entries.list '{"limit":5}'
|
|
172
|
+
oatmilk api invoices.void --input id=… --input expectedRevision=2 --input reason="Sent twice" --yes
|
|
173
|
+
oatmilk actions invoice # find actions; `oatmilk actions invoices.void` explains one
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
In CI, set `OATMILK_API_KEY` (and `OATMILK_ORG` for OAuth tokens with several companies) instead of signing in.
|
|
177
|
+
|
|
178
|
+
`exec` exits with `7` when Ask AI needs an answer or an approval it couldn't get; the JSON result lists what it is
|
|
179
|
+
waiting on. Run it again with `--yes` to approve, or continue the chat with `--chat <id>`.
|
|
180
|
+
|
|
181
|
+
| Exit | Meaning |
|
|
182
|
+
| --- | --- |
|
|
183
|
+
| 0 | Done |
|
|
184
|
+
| 1 | Failed |
|
|
185
|
+
| 2 | Wrong usage |
|
|
186
|
+
| 3 | Sign in needed |
|
|
187
|
+
| 4 | Not allowed |
|
|
188
|
+
| 5 | Not found |
|
|
189
|
+
| 6 | Rate limited |
|
|
190
|
+
| 7 | Needs your input |
|
|
191
|
+
| 130 | Cancelled |
|
|
192
|
+
|
|
193
|
+
## MCP
|
|
194
|
+
|
|
195
|
+
AI apps can use Oatmilk's remote MCP server directly, signing in with OAuth. `oatmilk mcp config` prints the setup
|
|
196
|
+
for Claude Code, Codex, Gemini CLI and Cursor. For apps that only start local commands, the CLI is a stdio bridge to
|
|
197
|
+
the same server, signed in as you:
|
|
198
|
+
|
|
199
|
+
```sh
|
|
200
|
+
claude mcp add oatmilk -- npx -y @getoatmilk/cli mcp
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Options
|
|
204
|
+
|
|
205
|
+
| Flag or variable | |
|
|
206
|
+
| --- | --- |
|
|
207
|
+
| `--local` | Use the Oatmilk on this computer, starting it if it's stopped. |
|
|
208
|
+
| `--cloud` | Use Oatmilk Cloud. |
|
|
209
|
+
| `--offline`, `OATMILK_OFFLINE=1` | Refuse any Oatmilk on the internet: only this computer and its network. |
|
|
210
|
+
| `--setup`, `--no-setup` | Show the first-run setup again, or never. |
|
|
211
|
+
| `--no-start` | Don't start a stopped local Oatmilk. |
|
|
212
|
+
| `--no-ai` | The app without Ask AI; `exec` refuses to run. |
|
|
213
|
+
| `--theme`, `OATMILK_THEME` | The app's theme: `system`, or one like `matcha`. `/theme` saves one. |
|
|
214
|
+
| `OATMILK_TERMINAL` | `light` or `dark`, if the app misreads your terminal's background. |
|
|
215
|
+
| `OATMILK_NO_UPDATE=1` | Never check for new versions (CI never checks). |
|
|
216
|
+
| `OLLAMA_HOST`, `LMSTUDIO_URL` | Where to look for Ollama and LM Studio. |
|
|
217
|
+
| `OATMILK_DATA_DIR` | Where the CLI keeps a downloaded copy of Oatmilk's source and the dev server's log. |
|
|
218
|
+
| `--host`, `OATMILK_HOST` | The Oatmilk address. Default `https://app.getoatmilk.com`; `staging` works, and so does your own Oatmilk, such as `https://oatmilk.localhost`. |
|
|
219
|
+
| `--org`, `OATMILK_ORG` | The company to work in. |
|
|
220
|
+
| `OATMILK_API_KEY` | Sign in with an API key. |
|
|
221
|
+
| `OATMILK_TOKEN` | Sign in with an OAuth access token. |
|
|
222
|
+
| `OATMILK_CONFIG_DIR` | Where sign-ins are saved. |
|
|
223
|
+
| `OATMILK_NO_BROWSER=1` | Never open a browser. |
|
|
224
|
+
| `NO_COLOR` | Plain output. |
|
|
225
|
+
| `NODE_EXTRA_CA_CERTS` | For a self-hosted Oatmilk on `*.localhost` that setup didn't make: the path of its local certificate authority, which `bun run self-host cert` saves. One setup made is trusted on its own. |
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
AGPL-3.0-only.
|