@propper-ai/cli 0.2.1

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/README.md ADDED
@@ -0,0 +1,255 @@
1
+ # propper-cli
2
+
3
+ **`propper`** — an AWS-style, OpenAPI-generated command-line interface for the
4
+ Propper Sign + Auth APIs.
5
+
6
+ The API command tree is **auto-generated** from Propper's published OpenAPI specs
7
+ (the AWS-CLI / botocore pattern): a build-time generator turns the specs into a
8
+ JSON command manifest + a typed HTTP client, and a `commander` runtime builds the
9
+ commands from the manifest. The generated client is exported, so it doubles as an
10
+ importable **Sign SDK**. A scheduled GitHub Action keeps the CLI in sync with the
11
+ specs automatically.
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npx @propper-ai/cli --help
17
+ # or
18
+ npm install -g @propper-ai/cli
19
+ propper --help
20
+ ```
21
+
22
+ Requires Node.js 20+.
23
+
24
+ ## Quick start
25
+
26
+ ```bash
27
+ # 1. Log in (opens a browser; OAuth2 Authorization Code + PKCE)
28
+ propper auth login
29
+
30
+ # 2. Confirm who you are
31
+ propper auth status # alias: propper auth whoami
32
+
33
+ # 3. Use the APIs (propper <api> <topic> <command>)
34
+ propper sign agreements list --output table
35
+ propper sign agreements get --id ag_123
36
+ propper sign agreements create --name "NDA" --input-json @nda.json
37
+ propper sign audit certificate --agreement-id ag_123 --output-file audit.pdf
38
+ propper docgen batches list
39
+ propper locker risks list
40
+ ```
41
+
42
+ ## Authentication
43
+
44
+ `propper auth login` supports three modes:
45
+
46
+ | Mode | Command | Notes |
47
+ | --- | --- | --- |
48
+ | Browser (PKCE) | `propper auth login` | OAuth2 Authorization Code + PKCE over a loopback redirect (RFC 8252). Default. Uses the CLI's fixed public client id. |
49
+ | Client credentials | `propper auth login --client-credentials` | Headless / CI. Uses the configured machine `client_id` (`--client-id` / `PROPPER_CLIENT_ID` / `propper configure`) + a stored or `PROPPER_CLIENT_SECRET` secret. |
50
+ | Pasted token | `propper auth login --token <jwt>` | Fallback. |
51
+
52
+ Tokens are stored per-profile in `~/.propper/credentials.json` (chmod 600) and
53
+ refreshed automatically. `propper auth logout` revokes and clears them.
54
+
55
+ **Scopes.** By default login requests the full set of scopes the `propper-cli`
56
+ OAuth client is allowed (`openid email profile offline_access` plus the
57
+ `sign`, `click`, `docgen`, `locker`, and `org:read` API scopes), so the issued
58
+ token can call every product API. Narrow the request with `--scope` (a single
59
+ space-separated string), e.g. `propper auth login --scope "openid offline_access
60
+ sign:read"`. The auth server still intersects whatever you request against the
61
+ client's allow-list. Check the granted scopes with `propper auth status`.
62
+
63
+ **Credential resolution order** (first match wins, AWS-style):
64
+
65
+ 1. `--token <jwt>`
66
+ 2. `PROPPER_API_TOKEN`
67
+ 3. stored OAuth tokens for the active profile (auto-refreshed)
68
+ 4. client-credentials grant — the machine `client_id` (`--client-id` / `PROPPER_CLIENT_ID` / config) + a stored client secret or `PROPPER_CLIENT_SECRET`
69
+
70
+ > **Client ids.** The OAuth client used for browser login is a fixed, built-in
71
+ > public client and is **not** configurable. The `client_id` you set via
72
+ > `--client-id`, `PROPPER_CLIENT_ID`, or `propper configure` is a *separate*
73
+ > machine-to-machine (client-credentials) client, paired with `client_secret`.
74
+
75
+ ## Configuration & profiles
76
+
77
+ ```bash
78
+ propper configure # interactive wizard
79
+ propper configure set output table # set a value for the active profile
80
+ propper configure get api_base_url
81
+ propper configure list-profiles
82
+ propper --profile staging agreements list
83
+ ```
84
+
85
+ Config lives in `~/.propper/`:
86
+
87
+ - `config.json` — non-secret per-profile settings (`api_base_url`, `auth_base_url`,
88
+ `client_id`, `output`, default profile)
89
+ - `credentials.json` — secret tokens and the client secret (chmod 600)
90
+
91
+ The interactive wizard configures, AWS-style, a machine-to-machine `client_id` +
92
+ `client_secret` for headless / service accounts. The secret is written to
93
+ `credentials.json`, never `config.json`. You can also set keys non-interactively:
94
+
95
+ ```bash
96
+ propper configure set client_id <id> # -> config.json
97
+ propper configure set client_secret <secret> # -> credentials.json (chmod 600)
98
+ ```
99
+
100
+ The `client_id` and `client_secret` are stripped of all whitespace (including
101
+ newlines and carriage returns) on input, so a pasted value with a stray trailing
102
+ newline won't break auth.
103
+
104
+ ### Environment variables
105
+
106
+ | Variable | Purpose |
107
+ | --- | --- |
108
+ | `PROPPER_API_TOKEN` | Bearer token override |
109
+ | `PROPPER_PROFILE` | Active profile |
110
+ | `PROPPER_BASE_URL` | API base URL override |
111
+ | `PROPPER_AUTH_BASE_URL` | Auth base URL override |
112
+ | `PROPPER_CLIENT_ID` | Client-credentials (M2M) client id (also `--client-id`) |
113
+ | `PROPPER_CLIENT_SECRET` | Client-credentials (M2M) client secret |
114
+ | `PROPPER_CONFIG_DIR` | Config directory (default `~/.propper`) |
115
+ | `PROPPER_DOCS_BASE_URL` | Spec source for `sync-spec` (default `https://docs.propper.ai`) |
116
+ | `NO_COLOR` | Disable colored output |
117
+
118
+ ## Commands
119
+
120
+ Commands are namespaced by API: `propper <api> <topic> <command>`. The API
121
+ command tree is generated from each product's OpenAPI spec.
122
+
123
+ ```
124
+ # sign (Sign API, /v1/sign)
125
+ propper sign agreements list | create | get | update | delete | send | void |
126
+ status | download | set-annotations | gen-and-send
127
+ propper sign recipients list | add | update | delete
128
+ propper sign documents list | upload | get | delete | download | download-url
129
+ propper sign templates list | create | get | import | export | send | ...
130
+ propper sign audit trail | certificate
131
+
132
+ # docgen (Propper Gen API, /v1/docgen)
133
+ propper docgen approvals | batches | delivery-configs | documents | templates ...
134
+
135
+ # locker (Propper Locker API, /v1/locker)
136
+ propper locker chat | documents | risks | settings ...
137
+ ```
138
+
139
+ Run any group bare (`propper`, `propper sign`, `propper sign agreements`) to see
140
+ its help.
141
+
142
+ Hand-authored:
143
+
144
+ ```
145
+ propper auth login | logout | status (whoami)
146
+ propper configure [wizard] | set | get | list-profiles
147
+ propper completion bash | zsh | fish
148
+ ```
149
+
150
+ > **Adding more APIs** is a one-line change in `scripts/generate.ts`
151
+ > (`PRODUCT_SPECS`).
152
+
153
+ ### Global options
154
+
155
+ `--profile`, `--output json|table|yaml|text`, `--query <jmespath>` (like AWS
156
+ `--query`), `--base-url`, `--auth-base-url`, `--client-id`, `--token`,
157
+ `--no-color`, `--quiet`, `--debug`.
158
+
159
+ ### Request bodies & files
160
+
161
+ - Generated `--<field>` flags cover top-level scalar fields.
162
+ - `--input-json '<json>'`, `--input-json @file.json`, or `--input-json -` (stdin)
163
+ set the whole body (mirrors AWS `--cli-input-json`).
164
+ - `--file <path>` base64-encodes a local file into the relevant body field
165
+ (uploads, template import).
166
+ - `--output-file <path>` writes binary responses (PDF/ZIP) to disk.
167
+ - `--all` auto-paginates list endpoints.
168
+
169
+ ```bash
170
+ propper sign agreements list --query "[?status=='sent'].id" --output text
171
+ propper sign documents upload --agreement-id ag_123 --file ./contract.pdf --filename contract.pdf
172
+ echo '{"name":"MSA"}' | propper sign agreements create --input-json -
173
+ ```
174
+
175
+ ## Use as a library (SDK)
176
+
177
+ The generated client is API-namespaced and exported as `@propper-ai/cli/generated/client`:
178
+
179
+ ```ts
180
+ import { operations } from "@propper-ai/cli/generated/client";
181
+
182
+ const ctx = { apiBaseUrl: "https://api.propper.ai", token, userAgent: "my-app/1.0" };
183
+ const agreements = await operations.sign.listAgreements({ query: { limit: 10 } }, ctx);
184
+ const batches = await operations.docgen.listBatches({}, ctx);
185
+ console.log(agreements.data, batches.data);
186
+ ```
187
+
188
+ ## Development
189
+
190
+ ```bash
191
+ npm install
192
+ npm run dev -- --help # run from source
193
+ npm test # vitest
194
+ npm run lint # biome
195
+ npm run typecheck # tsc
196
+ npm run build # tsup -> dist/
197
+
198
+ npm run sync-spec # refresh vendored specs from docs.propper.ai
199
+ npm run generate # regenerate src/generated/* from openapi/*
200
+ ```
201
+
202
+ ### Install the CLI locally from source
203
+
204
+ Build, then install this checkout globally so the `propper` command is on your
205
+ `PATH` exactly as `npm install -g @propper-ai/cli` would put it.
206
+
207
+ One-shot shortcut (install deps → build → global install):
208
+
209
+ ```bash
210
+ git clone https://github.com/mypropper/propper-cli.git
211
+ cd propper-cli
212
+ npm run dev:setup-local # = npm install && npm run build && npm install -g .
213
+
214
+ propper --version # now available anywhere
215
+ which propper
216
+ ```
217
+
218
+ Equivalent manual steps:
219
+
220
+ ```bash
221
+ npm install
222
+ npm run build
223
+ npm install -g . # installs the local build globally as `propper`
224
+ ```
225
+
226
+ To uninstall: `npm run dev:uninstall-local` (= `npm uninstall -g @propper-ai/cli`).
227
+
228
+ **For active development** use the link shortcut instead — it symlinks the global
229
+ `propper` to your working copy, so it picks up changes after each `npm run build`
230
+ (no reinstall):
231
+
232
+ ```bash
233
+ npm run dev:link-local # = npm install && npm run build && npm link
234
+ npm run build # rebuild after edits; `propper` reflects the new build
235
+ # ...
236
+ npm unlink -g @propper-ai/cli # remove the symlink when done
237
+ ```
238
+
239
+ > Tip: while iterating you can skip the global install entirely and run from
240
+ > source with `npm run dev -- <args>` (e.g. `npm run dev -- agreements list`).
241
+
242
+ The generator output in `src/generated/` is committed; CI fails if it drifts from
243
+ the vendored specs (`npm run generate` must produce no diff).
244
+
245
+ ### Keeping in sync with the API
246
+
247
+ `.github/workflows/spec-sync.yml` runs daily: it syncs the specs, regenerates,
248
+ validates (lint + typecheck + test + build), and opens/updates a single
249
+ `automation/spec-sync` PR summarizing the command changes whenever the API drifts.
250
+ No drift means no PR. Set a `SPEC_SYNC_TOKEN` secret (PAT or GitHub App token) if
251
+ you want CI to run on the auto-PR.
252
+
253
+ ## License
254
+
255
+ MIT