@userreason/cli 0.1.0 → 0.1.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 CHANGED
@@ -1,70 +1,123 @@
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:
58
105
 
59
106
  ```sh
60
- userreason query --workspace WORKSPACE_UUID --site SITE_UUID --resource surveys --limit 50 --json
61
- userreason command --file survey-command.json --json
107
+ npx --no-install userreason login --open --credential-store keychain
62
108
  ```
63
109
 
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.
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.
65
115
 
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.
116
+ ## Environments
67
117
 
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.
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.
69
121
 
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.
122
+ See [troubleshooting](https://docs.userreason.com/get-started/troubleshooting/)
123
+ for installation, sign-in and configuration help.
@@ -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
+ }