@userreason/cli 0.1.0 → 0.2.0

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.
Files changed (70) hide show
  1. package/README.md +301 -41
  2. package/dist/authorize.d.ts +29 -0
  3. package/dist/authorize.js +23 -0
  4. package/dist/bin.js +565 -50
  5. package/dist/capture.d.ts +18 -0
  6. package/dist/capture.js +256 -0
  7. package/dist/catalog.d.ts +16 -0
  8. package/dist/catalog.js +206 -0
  9. package/dist/client.d.ts +79 -2
  10. package/dist/client.js +140 -17
  11. package/dist/config.d.ts +4 -0
  12. package/dist/config.js +35 -12
  13. package/dist/contracts.d.ts +13 -3
  14. package/dist/contracts.js +4 -4
  15. package/dist/credentials.d.ts +12 -2
  16. package/dist/credentials.js +110 -26
  17. package/dist/docs.d.ts +51 -0
  18. package/dist/docs.js +143 -0
  19. package/dist/errors.d.ts +11 -0
  20. package/dist/errors.js +38 -0
  21. package/dist/event-policy.d.ts +2 -0
  22. package/dist/event-policy.js +9 -0
  23. package/dist/first-survey-preparation.d.ts +8 -0
  24. package/dist/first-survey-preparation.js +29 -0
  25. package/dist/first-survey-source.d.ts +60 -0
  26. package/dist/first-survey-source.js +289 -0
  27. package/dist/first-survey-terminal.d.ts +5 -0
  28. package/dist/first-survey-terminal.js +16 -0
  29. package/dist/first-survey.d.ts +88 -0
  30. package/dist/first-survey.js +227 -0
  31. package/dist/help.d.ts +13 -0
  32. package/dist/help.js +74 -0
  33. package/dist/index.d.ts +23 -0
  34. package/dist/index.js +23 -0
  35. package/dist/lock.js +19 -5
  36. package/dist/profile.d.ts +20 -0
  37. package/dist/profile.js +57 -0
  38. package/dist/project.d.ts +9 -0
  39. package/dist/project.js +87 -0
  40. package/dist/recommended-surveys.d.ts +30 -0
  41. package/dist/recommended-surveys.js +201 -0
  42. package/dist/setup-executor.d.ts +35 -0
  43. package/dist/setup-executor.js +329 -0
  44. package/dist/setup-files.d.ts +11 -0
  45. package/dist/setup-files.js +96 -0
  46. package/dist/setup-runner.d.ts +14 -0
  47. package/dist/setup-runner.js +142 -0
  48. package/dist/setup-source.d.ts +31 -0
  49. package/dist/setup-source.js +48 -0
  50. package/dist/setup-store.d.ts +37 -0
  51. package/dist/setup-store.js +256 -0
  52. package/dist/setup-terminal.d.ts +3 -0
  53. package/dist/setup-terminal.js +6 -0
  54. package/dist/setup-wire.d.ts +1237 -0
  55. package/dist/setup-wire.js +175 -0
  56. package/dist/setup.d.ts +1223 -0
  57. package/dist/setup.js +258 -0
  58. package/dist/starter-survey.d.ts +22 -0
  59. package/dist/starter-survey.js +457 -0
  60. package/dist/telemetry.d.ts +67 -0
  61. package/dist/telemetry.js +304 -0
  62. package/dist/ui.d.ts +75 -0
  63. package/dist/ui.js +107 -0
  64. package/dist/views.d.ts +51 -0
  65. package/dist/views.js +93 -0
  66. package/dist/workos.d.ts +1 -1
  67. package/dist/workos.js +9 -4
  68. package/package.json +29 -12
  69. package/skills/userreason/SKILL.md +88 -8
  70. package/skills/userreason/references/management.md +67 -0
package/README.md CHANGED
@@ -1,70 +1,330 @@
1
- # @userreason/cli
1
+ # UserReason CLI
2
2
 
3
- The public CLI uses the same authenticated onboarding API as the dashboard and MCP. This source package is prepared for publication; the npm package is not published by building it.
3
+ Manage UserReason surveys, audiences and feedback from your terminal. Use the CLI
4
+ for product investigations, repeatable workflows and tools that need structured
5
+ JSON output.
6
+
7
+ [Documentation](https://docs.userreason.com/cli/) ·
8
+ [Get started](https://docs.userreason.com/get-started/quickstart/) ·
9
+ [Dashboard](https://dash.userreason.com)
10
+
11
+ ## Requirements
12
+
13
+ - Node.js **22.12 or later** and npm, pnpm or Yarn.
14
+ - A UserReason account with access to the workspace you want to manage.
15
+ - A browser to sign in and approve access on your first connection.
16
+
17
+ ## Get started
18
+
19
+ Run the CLI without a global installation:
4
20
 
5
21
  ```sh
6
- npm ci
7
- npm test
8
- node dist/bin.js --help
22
+ npx -y @userreason/cli@latest login --open
23
+ npx -y @userreason/cli@latest whoami
9
24
  ```
10
25
 
11
- After publication:
26
+ Sign in in the browser, then review the workspaces and permissions you want to
27
+ allow. Each command respects both the approved access and your current workspace
28
+ role.
29
+
30
+ For a project that already uses UserReason, install the CLI as a development
31
+ dependency:
12
32
 
13
33
  ```sh
14
- npx -y @userreason/cli@latest login --open
15
- npx -y @userreason/cli@latest whoami --json
34
+ npm install --save-dev @userreason/cli
35
+ npx --no-install userreason login --open
36
+ npx --no-install userreason prompt list
16
37
  ```
17
38
 
18
- The CLI discovers the public WorkOS client ID from `/onboarding/v1/auth-config` when no override, environment value or saved configuration exists. Discovery is bounded, timed out, environment checked and never follows redirects or receives authentication secrets. The public client ID is configuration, not a secret; `--client-id` or `UR_WORKOS_CLIENT_ID` can override it. `--dev` selects `https://api-dev.userreason.com` and uses `UR_WORKOS_DEV_CLIENT_ID` when provided. Production defaults to `https://api.userreason.com`. `--api-url` accepts HTTPS origins or loopback HTTP for local development. Successful login saves nonsecret client/API configuration separately for each environment.
39
+ The [installation wizard](https://www.npmjs.com/package/@userreason/wizard) can
40
+ install the SDK and project CLI together. For pnpm or Yarn projects, use
41
+ `pnpm exec userreason` or `yarn exec userreason` after installation.
19
42
 
20
- Login uses [WorkOS CLI Auth](https://workos.com/docs/authkit/cli-auth): a public device client confirms a code in the browser, polls at the prescribed interval and receives access/refresh tokens. No WorkOS API key, client secret or UserReason signing key is required. Device codes and tokens are never printed.
43
+ ## Work with your project
21
44
 
22
- Credentials live in macOS Keychain, Windows Credential Manager or Linux Secret Service through `@napi-rs/keyring`. There is no plaintext fallback. If the store is unavailable, enable it before logging in. Rotating refresh-token exchanges are serialized across CLI/wizard processes. Credentials are separated by API origin and WorkOS client ID. On provider outages, stored credentials are retained; a revoked/expired refresh grant requires a new login.
45
+ From an application directory, the CLI detects a supported, literal
46
+ `UserReason.init({ siteId: '…' })` configuration and selects that site's workspace.
47
+ You can also choose a target explicitly:
23
48
 
24
- Authentication does not grant workspace or site access to an agent. A human approves a local UserReason grant through the dashboard:
49
+ ```sh
50
+ npx --no-install userreason site list --workspace WORKSPACE_UUID
51
+ npx --no-install userreason prompt list --workspace WORKSPACE_UUID --site SITE_UUID
52
+ npx --no-install userreason results overview --workspace WORKSPACE_UUID --site SITE_UUID
53
+ ```
54
+
55
+ `whoami` shows your selected API, account, access and detected project. Projects
56
+ with dynamic or multiple SDK configurations need explicit `--workspace` and
57
+ `--site` flags.
58
+
59
+ Surveys use the `prompt` command group. For example, `prompt list` lists surveys
60
+ and `prompt responses` reads their responses. Audience, event, user and results
61
+ commands provide the related targeting and reporting tools.
62
+
63
+ ## Find commands and documentation
25
64
 
26
65
  ```sh
27
- userreason grant request \
28
- --scope workspace:create \
29
- --scope workspace:read \
30
- --scope site:create \
31
- --scope site:read \
32
- --scope site:update \
33
- --wait
34
-
35
- userreason workspace create --name "Acme" --json
36
- userreason site create \
37
- --workspace WORKSPACE_UUID \
38
- --name "Acme application" \
39
- --origin https://app.example.com \
40
- --environment production \
41
- --json
66
+ npx --no-install userreason --help
67
+ npx --no-install userreason prompt --help
68
+ npx --no-install userreason docs search "survey targeting"
69
+ npx --no-install userreason docs get /sdk/events/
42
70
  ```
43
71
 
44
- An account-level workspace-creation grant permits one creation. The backend binds its remaining permissions to the new workspace and removes `workspace:create`. Creating another workspace requires another approval. For an existing workspace, include `--workspace WORKSPACE_UUID` when requesting a grant. Use `--site SITE_UUID` to request site restrictions. Survey editing and campaign publishing have separate scopes and are not requested by installation.
72
+ The CLI's documentation commands read the current public documentation. When a
73
+ network request is unavailable, they can fall back to the bundled CLI reference;
74
+ `--live` requires an online result and `--offline` selects the bundled reference.
75
+ See the [command reference](https://docs.userreason.com/cli/) for schemas, flags,
76
+ examples and the permissions required by each operation.
45
77
 
46
- Use `--request-id UUID` and `--workspace-id UUID` or `--site-id UUID` to make externally orchestrated creation retries deterministic. Reuse the exact payload and IDs on retry. Default IDs are generated once per command and preserved across an access-token refresh; separate command invocations generate new IDs.
78
+ ## Automation and agents
47
79
 
48
- `--json` emits a single JSON result on stdout. Browser links, login instructions and errors use stderr. A nonzero exit code means the command failed. An authorization-required error may contain an `approval_url`; request and approve the required scope before retrying. The `x-ur-client` header is a transport hint: the Worker derives identity and grant binding from the verified token.
80
+ Add `--json` for structured output:
49
81
 
50
82
  ```sh
51
- userreason workspace list --json
52
- userreason site list --workspace WORKSPACE_UUID --json
53
- userreason grant status --id REQUEST_UUID --wait --json
54
- userreason logout
83
+ npx --no-install userreason prompt list --json
84
+ npx --no-install userreason results overview --json
55
85
  ```
56
86
 
57
- Approved agents can also use the delegated management endpoints:
87
+ Successful JSON results use stdout. Errors and interactive sign-in instructions
88
+ use stderr, and failed commands exit with a nonzero status. `--help --all` shows
89
+ the complete command reference.
90
+
91
+ The package includes a [UserReason agent skill](skills/userreason/SKILL.md) for
92
+ feedback investigations and approved management workflows. The installation
93
+ wizard can add it to a project's `.agents/skills/` directory after review.
94
+
95
+ ## Access and credentials
96
+
97
+ `login --open` connects your account and opens access review. Use `access --open`
98
+ to renew or change an existing connection. Access is time-limited, and you can
99
+ revoke a connection in the dashboard. Reading feedback and publishing changes
100
+ require their respective permissions.
101
+
102
+ Credentials are stored outside your project in a per-user file by default, with
103
+ owner-only permissions on POSIX systems. To use macOS Keychain, Windows
104
+ Credential Manager or Linux Secret Service instead, run:
105
+
106
+ ```sh
107
+ npx --no-install userreason login --open --credential-store keychain
108
+ ```
109
+
110
+ The optional OS credential-store binding must be available for this option. The
111
+ CLI does not fall back to file storage when Keychain storage is explicitly
112
+ selected. `logout` removes credentials from the selected local store; revoke the
113
+ connection in the dashboard to withdraw server access. Never commit credentials
114
+ to your application repository.
115
+
116
+ ## Environments
117
+
118
+ The CLI connects to the production UserReason API and public documentation by
119
+ default. A customer's development or preview site can still use this API; a
120
+ site's environment is separate from the API environment.
121
+
122
+ See [troubleshooting](https://docs.userreason.com/get-started/troubleshooting/)
123
+ for installation, sign-in and configuration help.
124
+
125
+ ## Optional usage measurement
126
+
127
+ The CLI reports canonical command types, success/failure counts, durations,
128
+ execution mode and its version to the UserReason API. It never reports command
129
+ arguments, documentation searches, file paths, source code, command output,
130
+ raw errors, email addresses or credentials as analytics properties. Signed-in
131
+ requests can be associated with the verified UserReason account and workspace;
132
+ anonymous usage uses a random local installation ID. Switching accounts never
133
+ attributes an earlier account's queued activity to the next account.
134
+
135
+ Usage is batched in the per-user UserReason configuration directory, outside
136
+ your project, with a seven-day expiry, bounded storage and an upload deadline of
137
+ 500 ms for anonymous batches or 1.5 seconds for authenticated batches. Failed
138
+ uploads do not change command output or exit status.
139
+ `--offline` sends no analytics requests. Local command discovery (`cli`) also
140
+ stays offline. The queue is retried on later online commands; aggregated command
141
+ counts, rather than the number of batches, describe usage.
142
+
143
+ Disable for one invocation with `--no-telemetry`, for a process or CI job with
144
+ `UR_TELEMETRY_DISABLED=1` (or `DO_NOT_TRACK=1`), or persistently with:
58
145
 
59
146
  ```sh
60
- userreason query --workspace WORKSPACE_UUID --site SITE_UUID --resource surveys --limit 50 --json
61
- userreason command --file survey-command.json --json
147
+ userreason telemetry disable
148
+ userreason telemetry status
149
+ userreason telemetry enable
62
150
  ```
63
151
 
64
- The command file is a versioned management command with `action`, `workspace_id`, `request_id`, site/resource IDs and its action-specific fields. Edits/publishing/deletion also require the current `expected_revision` where defined by the API. The CLI streams at most 64 KB from the local JSON file, and the server validates the complete command and enforces the exact action's scope. Reuse the unchanged file/UUIDs for a retry. Commands named `*.delete` archive or disable records; responses and published versions remain immutable. Workspace/site creation uses the dedicated onboarding commands instead.
152
+ The persistent setting is shared with the installation wizard. Disabling it
153
+ also removes locally queued analytics and the random installation identity.
154
+
155
+ ### Schedule a survey and set collection targets
156
+
157
+ The JSON definition accepted by `prompt create` and `prompt update` supports an
158
+ optional `rules.collection` object. For example:
159
+
160
+ ```json
161
+ {
162
+ "starts_at": "2026-10-20T07:00:00.000Z",
163
+ "ends_at": "2026-10-27T16:00:00.000Z",
164
+ "time_zone": "Europe/Amsterdam",
165
+ "response_target": 500,
166
+ "daily_response_target": 50
167
+ }
168
+ ```
169
+
170
+ Publish the saved draft through the normal prompt command. Use null for an unset
171
+ timestamp or unlimited target, or omit the object for no schedule/targets. Targets
172
+ are shared across the campaign's versions, experiments and enrollments. They stop
173
+ new admissions while allowing already-admitted surveys to finish. `prompt list`
174
+ and prompt reads include the current collection state and completed counts.
175
+
176
+ ## Conversational surveys (development)
177
+
178
+ The development API accepts a terminal conversation as a text question with a
179
+ versioned `conversation` setting. Use the existing `prompt create`, `update`,
180
+ `validate` and `publish` commands with the complete definition. Read
181
+ `https://docs-dev.userreason.com/prompts/conversations/` for the current schema.
182
+ A conversation stands alone or starts an experiment version; it cannot follow a
183
+ rating. Quick, Focused and In-depth presets limit follow-ups and time. Review and
184
+ Send remain separate: only the visitor's accepted answer is a response.
185
+
186
+ ```sh
187
+ userreason workspace ai get --dev --workspace WORKSPACE_UUID
188
+ userreason workspace ai get --dev --workspace WORKSPACE_UUID --site SITE_UUID
189
+ userreason workspace ai set --dev --workspace WORKSPACE_UUID --file AI-SETTINGS.json
190
+ userreason results conversations PROMPT_UUID --dev --workspace WORKSPACE_UUID --site SITE_UUID
191
+ userreason conversation get CONVERSATION_UUID --dev --workspace WORKSPACE_UUID --site SITE_UUID
192
+ ```
193
+
194
+ `AI-SETTINGS.json` contains only the fields to change, for example
195
+ `{"enabled":true,"voice_enabled":false}`. Owners and admins manage allowance
196
+ controls. To change site context, pass one `--site` and a file such as
197
+ `{"product_context":"Scheduled reports email PDF or CSV files."}`; editors can
198
+ update that site context. Missing settings keep their current value.
199
+
200
+ Typed, spoken and live-test sessions share workspace AI allowance. Scripted
201
+ preview uses no allowance. Accepted text, transcript, and optional generated
202
+ analysis have different provenance; generated analysis is not a visitor answer.
203
+ These commands require the matching development backend and private development
204
+ package set. Public npm `latest` remains unchanged by this rollout.
205
+
206
+ ## Browser setup client and local execution
207
+
208
+ The exported setup-v1 client provides a proof-bound handshake, strict bounded
209
+ protocol reads, heartbeat/claim/result adapters and `runSetupExecutor` with a per-project lock for the
210
+ browser-driven wizard. It uses a separate owner-only `setup-v1` store
211
+ outside the project; it neither reads nor replaces normal login credentials.
212
+ Loading a selected expired setup removes its capability. New setup saves lazily
213
+ inspect at most 128 directory entries and remove validated setup records at
214
+ least seven days old; later saves handle remaining batches. There is no cleanup
215
+ daemon. Unknown files, symlinks, project files, locks and normal login credentials
216
+ are left alone.
217
+ The server must explicitly advertise `browser_setup` v1 as enabled. Old or
218
+ disabled servers return an unsupported result before local effects. A started
219
+ setup never silently falls back to a different installation flow.
220
+
221
+ Setup requests also propagate `--no-telemetry`, the shared saved opt-out,
222
+ `UR_TELEMETRY_DISABLED` and `DO_NOT_TRACK` to optional server-side setup
223
+ measurement. Unreadable preference state suppresses measurement without blocking
224
+ the setup request. Browser measurement preferences remain separate.
225
+
226
+ An active setup can request its simulated sample using:
227
+
228
+ ```sh
229
+ userreason setup sample --setup SETUP_UUID --directory /path/to/original/project --json
230
+ ```
231
+
232
+ Use `--api-url` or `--dev` for the same API as that setup. This operation requires
233
+ its unexpired local setup capability and an open sample-test step. It reads a
234
+ clearly labelled static sample and records only that setup's read receipt; it
235
+ does not read real feedback, create responses, consume response quota, publish
236
+ surveys or authorize ongoing CLI access. The ID in the command is not a bearer
237
+ credential. Setup credentials are never printed. `--request-id UUID` permits an
238
+ explicit idempotent retry of the read.
239
+
240
+ The executor accepts only locally prepared, browser-approved typed operations.
241
+ It writes a private intent before starting, verifies exact source/manifest hashes,
242
+ and records the result before reporting. Package-manager lockfiles are declared
243
+ managed outputs: their contents are generated during dependency resolution and
244
+ their actual hashes are saved in the local receipt, rather than predicted.
245
+ After an interruption it reconciles known output; it never blindly reruns an
246
+ unknown command. `recoverSetupProjectLock` explicitly releases a crashed owner's
247
+ lock only after that process is gone. Local receipts contain prepared file bytes,
248
+ stay outside the project with owner-only permissions, and expire after seven
249
+ days. Lazy cleanup is bounded; receipts never restore expired remote access.
250
+ The browser executor requires durable file synchronization (`fsync`). Node 24
251
+ permission mode disables that operation even for allowed paths, so setup stops
252
+ before server calls or application changes under those flags. It does not remove
253
+ permission flags or fall back to nondurable receipts.
254
+
255
+ `detectSetupTerminal` emits fixed platform/app codes only. Installing the project
256
+ agent skill does not grant continuing management access. Ordinary CLI login,
257
+ terminal installation and first-survey commands are unchanged.
258
+
259
+ `runBrowserSetup` connects this executor to the optional browser onboarding flow.
260
+ The server's source-analysis flag is checked before collecting any source. The
261
+ local collector prepares a bounded, memory-only application packet with no Git
262
+ history. `onSourcePrepared` can display the exact excerpts locally; the initial
263
+ `source-plan` request contains only relative paths, line ranges, hashes and package
264
+ metadata. The browser separately approves that packet digest and configured
265
+ providers. Immediately before `source-upload`, the runner rechecks all full-file
266
+ hashes, recollects the same snapshot and validates installed package metadata.
267
+ Source text is never saved in setup receipts. Resuming rebuilds the original
268
+ snapshot ID and refuses changed content until the browser reviews a fresh packet.
269
+
270
+ Heartbeat continues while the bounded analysis request runs. A dropped response
271
+ is reconciled by polling, not a repeated provider call. A failed preparation or
272
+ analysis needs a browser retry or skip. The browser owns candidate selection,
273
+ inactive draft creation, sample skip, finish and cancellation. The local runner
274
+ cannot create drafts, publish surveys or change ongoing CLI grants. Server rollout
275
+ flags remain off by default; these are prepared clients for a compatible release.
276
+
277
+ ## Optional first-survey guidance
278
+
279
+ The development wizard also uses the exported `starterSurvey` flow. It provides
280
+ one-question starters for improvement, workflow friction and satisfaction, with
281
+ optional background personalization. Local preparation after sign-in is
282
+ memory-only; provider processing still needs approval of the exact source packet.
283
+ The model returns wording and cited rationale, while the Worker compiles the
284
+ inactive draft. Users keep control of their edits and choose delivery separately.
285
+ An unconfigured starter matches nobody, even if it is later published unchanged.
286
+ Draft save receipts survive a lost response so retries use the same identifiers.
287
+ This does not change the legacy `first-survey start` command.
288
+
289
+ `userreason first-survey start --workspace WORKSPACE_UUID --site SITE_UUID
290
+ --directory /absolute/app` offers interactive, evidence-backed suggestions and
291
+ individual unpublished draft creation. Repeating the command resumes the private
292
+ session. `handoff` prints a coding-agent task; `cancel` prevents further work;
293
+ `delete` removes the retained plan (not already-created drafts). No publication
294
+ or source edits are automatic. Noninteractive/JSON runs cannot authorize analysis.
295
+
296
+ Only a reviewed packet from the explicit application root is uploaded. Default
297
+ bounds: 200 files, 500 KiB local text, 10 KiB source packet, 12,000 input and 4,000
298
+ output tokens, one clarification round. Symlinks, ignored/generated files and
299
+ files with detected secrets are omitted. Detection is best effort: review every
300
+ excerpt. Git subjects need separate consent and are limited to 20 commits/90 days;
301
+ no authors, diffs or network fetch. Narrow the selected paths when truncated.
302
+
303
+ Before saving, the review shows every question, rating label, answer option and
304
+ conditional route in the returned definition. The analysis deadline is 35 seconds;
305
+ the transport allows the backend's maximum deadline without cutting it off early.
306
+ Draft validation remains authoritative: unsupported survey behavior cannot be
307
+ silently converted or published by this flow.
65
308
 
66
- Queries support `sites`, `surveys`, `campaigns`, `events`, `responses` and `audits`, with a limit of 1–100 and an optional `--after` UUID from the server's `next` field. Site restrictions and current workspace membership are enforced server-side.
309
+ The provider destination and configured policy are shown before approval. Local
310
+ sessions contain hashes, private proposals and mutation receipts, never submitted source
311
+ packets or credentials (generated plans can quote source); protect their owner-only config directory. They expire
312
+ after seven days. Worker plans expire after seven days and are purged on subsequent
313
+ planning activity; provider retention is separately configured/disclosed. Drafts
314
+ have their normal account retention. Deletion retains a content-free budget
315
+ receipt until expiry so it cannot reset allowance. No first-survey content is sent
316
+ to product telemetry.
67
317
 
68
- Logout removes local credentials. Revoke the relevant grant in the dashboard to remove server-side agent access. The packaged [UserReason skill](skills/userreason/SKILL.md) describes agent use of these commands.
318
+ Analysis requires an ongoing connection with `site:read` and `survey:write` on the
319
+ exact site; installation grants do not suffice. Use `access --open` if necessary,
320
+ reviewing replacement-grant semantics rather than broadening installation access.
321
+ Provider errors do not undo installation. Use the agent/manual workflow when
322
+ analysis is unavailable. Integration and browser eligibility remain unverified
323
+ until tested: reachable configuration is not browser verification. Instrumentation
324
+ requires a reviewed, hash-guarded diff and separate edit approval using the agent
325
+ skill; unsupported host transforms are never executed automatically.
69
326
 
70
- The CLI uses `/onboarding/v1/...`; those endpoints require the new migrations, configured WorkOS environment and deployed Worker. Live provider authentication is not exercised by the local fixture tests.
327
+ The 0.2.0 production installation profile selects `@userreason/js@0.5.0` and
328
+ `@userreason/cli@0.2.0` exactly. Browser setup remains an explicit wizard entry
329
+ and requires an enabled compatible server; ordinary CLI authentication and
330
+ management commands retain their existing authorization flow.
@@ -0,0 +1,29 @@
1
+ import { UserReasonClient } from './client.js';
2
+ import { type DeviceAuthorization, type Fetch } from './workos.js';
3
+ import { type Credentials, type GrantRequest } from './contracts.js';
4
+ import type { ClientConfig } from './config.js';
5
+ /** Sign in if needed, then obtain fresh, explicit consent. Never silently upgrade an existing grant. */
6
+ export declare function authorizeCli(config: ClientConfig, credentials: Credentials, options: {
7
+ onDevice: (device: DeviceAuthorization) => void | Promise<void>;
8
+ onApproval: (request: GrantRequest) => void | Promise<void>;
9
+ client?: UserReasonClient;
10
+ fetcher?: Fetch;
11
+ wait?: boolean;
12
+ workspaceIds?: string[];
13
+ }): Promise<{
14
+ authenticated: boolean;
15
+ api_url: string;
16
+ request: GrantRequest;
17
+ user?: undefined;
18
+ grant?: undefined;
19
+ } | {
20
+ authenticated: boolean;
21
+ api_url: string;
22
+ user: {
23
+ id: string;
24
+ email?: string | null;
25
+ name?: string | null;
26
+ };
27
+ grant: import("./contracts.js").Grant | undefined;
28
+ request: GrantRequest;
29
+ }>;
@@ -0,0 +1,23 @@
1
+ import { UserReasonClient } from './client.js';
2
+ import { AuthenticationError, login } from './workos.js';
3
+ import { SCOPES } from './contracts.js';
4
+ /** Sign in if needed, then obtain fresh, explicit consent. Never silently upgrade an existing grant. */
5
+ export async function authorizeCli(config, credentials, options) {
6
+ const client = options.client ?? new UserReasonClient(config, credentials, { fetcher: options.fetcher });
7
+ try {
8
+ await client.account();
9
+ }
10
+ catch (error) {
11
+ const session = await credentials.load();
12
+ if (session && !(error instanceof AuthenticationError && ['invalid_grant', 'installation_expired'].includes(error.code)))
13
+ throw error;
14
+ await login(config, credentials, options.onDevice, { fetcher: options.fetcher });
15
+ }
16
+ const request = await client.requestGrant({ allWorkspaces: !options.workspaceIds, workspaceIds: options.workspaceIds, scopes: [...SCOPES] });
17
+ await options.onApproval(request);
18
+ if (options.wait === false)
19
+ return { authenticated: true, api_url: config.apiUrl, request };
20
+ const decision = await client.waitForGrant(request.id);
21
+ const account = await client.account();
22
+ return { authenticated: true, api_url: config.apiUrl, user: account.user, grant: account.grants.find(grant => grant.id === decision.grant_id), request: decision };
23
+ }