seamless-cli 0.10.1 → 0.11.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 (80) hide show
  1. package/README.md +197 -29
  2. package/dist/commands/apps.js +147 -0
  3. package/dist/commands/apps.js.map +1 -0
  4. package/dist/commands/config.js +16 -15
  5. package/dist/commands/config.js.map +1 -1
  6. package/dist/commands/help.js +65 -187
  7. package/dist/commands/help.js.map +1 -1
  8. package/dist/commands/helpTopics.js +376 -0
  9. package/dist/commands/helpTopics.js.map +1 -0
  10. package/dist/commands/init.js +295 -76
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/commands/instanceLogin.js +55 -0
  13. package/dist/commands/instanceLogin.js.map +1 -0
  14. package/dist/commands/login.js +42 -80
  15. package/dist/commands/login.js.map +1 -1
  16. package/dist/commands/logout.js +18 -8
  17. package/dist/commands/logout.js.map +1 -1
  18. package/dist/commands/org.js +5 -4
  19. package/dist/commands/org.js.map +1 -1
  20. package/dist/commands/profile.js +29 -2
  21. package/dist/commands/profile.js.map +1 -1
  22. package/dist/commands/sessions.js +9 -7
  23. package/dist/commands/sessions.js.map +1 -1
  24. package/dist/commands/templates.js +58 -0
  25. package/dist/commands/templates.js.map +1 -0
  26. package/dist/commands/users.js +9 -7
  27. package/dist/commands/users.js.map +1 -1
  28. package/dist/commands/verify.js +5 -2
  29. package/dist/commands/verify.js.map +1 -1
  30. package/dist/commands/whoami.js +13 -5
  31. package/dist/commands/whoami.js.map +1 -1
  32. package/dist/core/args.js +11 -0
  33. package/dist/core/args.js.map +1 -1
  34. package/dist/core/authClient.js +29 -6
  35. package/dist/core/authClient.js.map +1 -1
  36. package/dist/core/cancel.js +32 -0
  37. package/dist/core/cancel.js.map +1 -0
  38. package/dist/core/config.js +45 -1
  39. package/dist/core/config.js.map +1 -1
  40. package/dist/core/confirmAction.js +26 -0
  41. package/dist/core/confirmAction.js.map +1 -0
  42. package/dist/core/images.js +3 -3
  43. package/dist/core/interactiveLogin.js +72 -0
  44. package/dist/core/interactiveLogin.js.map +1 -0
  45. package/dist/core/output.js +23 -9
  46. package/dist/core/output.js.map +1 -1
  47. package/dist/core/portal.js +112 -8
  48. package/dist/core/portal.js.map +1 -1
  49. package/dist/core/templates.js +10 -0
  50. package/dist/core/templates.js.map +1 -1
  51. package/dist/core/tty.js +25 -0
  52. package/dist/core/tty.js.map +1 -0
  53. package/dist/generators/auth/auth.js +8 -7
  54. package/dist/generators/auth/auth.js.map +1 -1
  55. package/dist/generators/docker/docker.js +27 -21
  56. package/dist/generators/docker/docker.js.map +1 -1
  57. package/dist/index.js +89 -21
  58. package/dist/index.js.map +1 -1
  59. package/dist/prompts/appSelect.js +16 -10
  60. package/dist/prompts/appSelect.js.map +1 -1
  61. package/dist/prompts/initMode.js +77 -0
  62. package/dist/prompts/initMode.js.map +1 -0
  63. package/dist/prompts/oauthSetup.js +4 -3
  64. package/dist/prompts/oauthSetup.js.map +1 -1
  65. package/dist/prompts/projectSetup.js +77 -50
  66. package/dist/prompts/projectSetup.js.map +1 -1
  67. package/dist/testSetup.js +9 -0
  68. package/dist/testSetup.js.map +1 -0
  69. package/package.json +1 -1
  70. package/verify/adapter-app/package.json +1 -1
  71. package/verify/docker-compose.verify.yml +4 -3
  72. package/verify/harness/api/ownerAdmin.spec.ts +24 -0
  73. package/verify/harness/lib/env.ts +3 -4
  74. package/verify/harness/lib/flows.ts +1 -36
  75. package/verify/harness/playwright.config.ts +8 -3
  76. package/dist/commands/bootstrapAdmin.js +0 -96
  77. package/dist/commands/bootstrapAdmin.js.map +0 -1
  78. package/dist/core/bootstrapSecret.js +0 -39
  79. package/dist/core/bootstrapSecret.js.map +0 -1
  80. package/verify/harness/api/adminBootstrap.spec.ts +0 -34
@@ -1,201 +1,53 @@
1
1
  import { VERSION } from "../index.js";
2
+ import { COMMAND_HELP, findCommandHelp, } from "./helpTopics.js";
3
+ const DIVIDER = "────────────────────────────────────────────";
4
+ const DOCS_URL = "https://docs.seamlessauth.com";
5
+ function indent(text, spaces) {
6
+ const pad = " ".repeat(spaces);
7
+ return text
8
+ .split("\n")
9
+ .map((line) => (line.length > 0 ? pad + line : line))
10
+ .join("\n");
11
+ }
12
+ function renderSections(command, headingIndent) {
13
+ return command.sections
14
+ .map((section) => `${indent(section.heading, headingIndent)}\n${indent(section.body, headingIndent + 2)}`)
15
+ .join("\n\n");
16
+ }
2
17
  export function printHelp() {
18
+ const usage = COMMAND_HELP.flatMap((c) => c.usage)
19
+ .concat(["seamless <command> --help", "seamless --help", "seamless --version"])
20
+ .map((line) => ` ${line}`)
21
+ .join("\n");
22
+ const commands = COMMAND_HELP.map((c) => renderSections(c, 2)).join("\n\n");
3
23
  console.log(`
4
24
  seamless v${VERSION}
5
25
 
6
26
  Seamless CLI — scaffold and manage full-stack authentication systems.
7
27
 
8
- ────────────────────────────────────────────
28
+ ${DIVIDER}
9
29
 
10
30
  USAGE
11
31
 
12
- seamless init [project-name] [--<example>]
13
- seamless check
14
- seamless bootstrap-admin [email] [--api-url <url>]
15
- seamless verify [--api-only] [--filter=<flow>] [--keep-up]
16
- seamless profile <list|add|use|remove>
17
- seamless login [identifier] [--identifier <email>] [--local] [--profile <name>]
18
- seamless whoami [--profile <name>]
19
- seamless logout [--all] [--profile <name>]
20
- seamless sessions [list]
21
- seamless sessions revoke <id | --all>
22
- seamless config <get|set|roles|diff|apply>
23
- seamless users <list|delete|credentials|prepare-device-replacement>
24
- seamless org <list|create|get|update>
25
- seamless org members <list|add|update|remove>
26
- seamless --help
27
- seamless --version
28
-
29
- ────────────────────────────────────────────
30
-
31
- COMMANDS
32
-
33
- init [project-name]
34
- Scaffold a new Seamless Auth project
35
-
36
- Without a name:
37
- • Creates project in current directory
38
-
39
- With a name:
40
- • Creates new directory
41
-
42
- With an example flag (e.g. --oauth):
43
- • Scaffolds that use-case starter and skips the web prompt
44
- • --oauth also prompts for OIDC providers (Google, GitHub, Microsoft,
45
- GitLab) and wires the ones you configure into the auth server
46
- • Run an unknown flag to see the available examples
47
-
48
- profile <list|add|use|remove>
49
- Manage the Seamless Auth instances the CLI targets, stored as named
50
- profiles in ~/.config/seamless/config.json (respects XDG_CONFIG_HOME).
51
-
52
- profile list
53
- • Show configured profiles; the active one is marked with *
54
-
55
- profile add <name> --instance-url <url> [--identifier-type email|phone]
56
- • Create or update a profile (prompts interactively if flags are omitted)
57
-
58
- profile use <name>
59
- • Switch the active profile for subsequent commands
60
-
61
- profile remove <name>
62
- • Delete a profile
63
-
64
- The active profile can also be chosen per command with --profile <name> or
65
- the SEAMLESS_PROFILE environment variable.
66
-
67
- login [identifier]
68
- Log in to the active profile's Seamless Auth instance using email OTP.
69
- Prompts for the identifier (or pass it positionally or with --identifier)
70
- and the code sent to your inbox, then stores the session in the OS keychain.
71
-
72
- --local
73
- • For local instances only. Asks the instance to return the OTP in the
74
- response instead of emailing it, and verifies with it automatically.
75
- • Requires the auth API to run outside production with
76
- ALLOW_UNCREDENTIALED_DELIVERY_SECRETS=true.
77
-
78
- --profile <name>
79
- • Log in against a specific profile instead of the active one
80
- • Also selectable with the SEAMLESS_PROFILE environment variable
81
-
82
- whoami
83
- Show the identity behind the active profile's session (sub, email, roles),
84
- alongside the profile name and instance URL. Fails cleanly if not logged in.
85
-
86
- logout [--all]
87
- End the current session on the instance and clear the local keychain tokens.
88
- --all revokes every session for the user before clearing local tokens.
89
-
90
- sessions [list]
91
- List the active sessions for the logged-in user, with the current session
92
- marked. Shows the session id, device or user agent, IP, and last-used time.
93
-
94
- sessions revoke <id | --all>
95
- Revoke one session by id, or every session with --all. Revoking the current
96
- session (or --all) prompts for confirmation and then clears local tokens.
97
-
98
- config <get|set|roles|diff|apply>
99
- Read and write the instance system configuration (requires an admin role).
100
-
101
- config get [key] [--json]
102
- • Print the whole config or a single key
103
-
104
- config set <key> <value>
105
- • Update one key; the value is parsed as JSON, falling back to a string
106
- (for example: config set access_token_ttl 15m,
107
- config set login_methods '["email_otp","passkey"]')
108
-
109
- config roles [--json]
110
- • List the instance's available roles
111
-
112
- config diff <file>
113
- • Show how a local JSON config file differs from the instance
114
-
115
- config apply <file> [--dry-run]
116
- • Apply a local JSON config file after a confirmation prompt
32
+ ${usage}
117
33
 
118
- config oauth-providers <list|add|update|remove>
119
- • Manage OAuth providers one at a time. Client secrets stay server-side,
120
- referenced by clientSecretEnv; the secret value is never sent.
121
- (for example: config oauth-providers add --file google.json,
122
- config oauth-providers update google '{"enabled":false}',
123
- config oauth-providers remove google)
34
+ ${DIVIDER}
124
35
 
125
- users <list|delete|credentials|prepare-device-replacement>
126
- Admin user management (requires an admin role).
127
-
128
- users list [--limit <n>] [--offset <n>] [--json]
129
- • List users
130
- users delete <id>
131
- • Delete a user (asks for confirmation)
132
- users credentials <id> [--json]
133
- • Show a user's registered credentials
134
- users prepare-device-replacement <id> [--keep-sessions] [--keep-passkeys] [--keep-totp]
135
- • Admin-assisted account recovery (needs an elevated session)
136
-
137
- org <list|create|get|update>, org members <list|add|update|remove>
138
- Admin organization management (requires an admin role).
139
-
140
- org list [--json]
141
- org create <name> [--slug <slug>]
142
- org get <id> [--json]
143
- org update <id> [--name <name>] [--slug <slug>]
144
- org members list <orgId> [--json]
145
- org members add <orgId> (--user <id> | --email <email>) [--roles a,b] [--scopes a,b]
146
- org members update <orgId> <userId> [--roles a,b] [--scopes a,b]
147
- org members remove <orgId> <userId>
148
-
149
- check
150
- Validate project setup, Docker, and running services
151
-
152
- verify [--local] [--api-only] [--filter=<flow>] [--keep-up]
153
- Stand up the auth stack and run the conformance suite across the API and
154
- the cookie (adapter) paths. Requires Docker. Builds the auth server from
155
- a sibling seamless-auth-api checkout (override with SEAMLESS_API_DIR).
156
-
157
- --local builds and links the local @seamless-auth/* SDK source (sibling
158
- seamless-auth-server, override with SEAMLESS_SERVER_DIR) instead of the
159
- published npm packages — so you can catch SDK regressions before publishing.
160
-
161
- bootstrap-admin [email] [--api-url <url>]
162
- Create a bootstrap admin invite
163
-
164
- Targets your app API (the SeamlessAuth server adapter), which exposes the
165
- bootstrap route and delivers the invite — not the auth server directly.
166
- Defaults to http://localhost:3000; override with --api-url or SEAMLESS_API_URL.
167
-
168
- Automatically resolves bootstrap secret from:
169
- • .env
170
- • auth/.env
171
- • docker-compose.yml
172
-
173
- If not found, you will be prompted.
174
-
175
- Examples:
176
- seamless bootstrap-admin
177
- seamless bootstrap-admin admin@example.com
178
- seamless bootstrap-admin admin@example.com --api-url http://localhost:3000
179
-
180
- ────────────────────────────────────────────
181
-
182
- BEHAVIOR
183
-
184
- seamless <project-name>
36
+ COMMANDS
185
37
 
186
- • Shortcut for: seamless init <project-name>
38
+ ${commands}
187
39
 
188
- ────────────────────────────────────────────
40
+ ${DIVIDER}
189
41
 
190
42
  GETTING STARTED
191
43
 
192
44
  1. seamless init
193
- 2. docker-compose up
194
- 3. seamless bootstrap-admin
45
+ 2. docker compose up
46
+ 3. Register in the browser with the email you gave init
195
47
 
196
- Complete registration to become admin
48
+ That address is the owner, so it becomes an admin
197
49
 
198
- ────────────────────────────────────────────
50
+ ${DIVIDER}
199
51
 
200
52
  WHAT YOU GET
201
53
 
@@ -205,7 +57,7 @@ WHAT YOU GET
205
57
  • Admin dashboard (Docker or source)
206
58
  • Docker Compose setup
207
59
 
208
- ────────────────────────────────────────────
60
+ ${DIVIDER}
209
61
 
210
62
  EXAMPLES
211
63
 
@@ -218,21 +70,47 @@ EXAMPLES
218
70
  seamless init --oauth my-app
219
71
  → Create ./my-app from the OAuth example starter
220
72
 
221
- seamless my-app
222
- → Shortcut for init
223
-
224
73
  seamless check
225
74
  → Validate your project
226
75
 
227
- seamless bootstrap-admin
228
- → Create your first admin user
229
-
230
- ────────────────────────────────────────────
76
+ ${DIVIDER}
231
77
 
232
78
  DOCS
233
79
 
234
- https://docs.seamlessauth.com
80
+ ${DOCS_URL}
81
+
82
+ `);
83
+ }
84
+ // Returns false when the command has no help entry, so the caller can fall
85
+ // back to the unknown-command path instead of printing an empty topic.
86
+ export function printCommandHelp(name) {
87
+ const command = findCommandHelp(name);
88
+ if (!command)
89
+ return false;
90
+ const usage = command.usage.map((line) => ` ${line}`).join("\n");
91
+ // The heading only earns its place when a command has more than one section
92
+ // (sessions list vs sessions revoke); otherwise it just repeats the usage.
93
+ const description = command.sections.length === 1
94
+ ? indent(command.sections[0].body, 2)
95
+ : renderSections(command, 2);
96
+ const examples = command.examples?.length
97
+ ? `\nEXAMPLES\n\n${command.examples
98
+ .map((example) => indent(example, 2))
99
+ .join("\n\n")}\n`
100
+ : "";
101
+ console.log(`
102
+ seamless ${command.name} — seamless v${VERSION}
103
+
104
+ USAGE
105
+
106
+ ${usage}
107
+
108
+ DESCRIPTION
235
109
 
110
+ ${description}
111
+ ${examples}
112
+ Docs: ${DOCS_URL}
236
113
  `);
114
+ return true;
237
115
  }
238
116
  //# sourceMappingURL=help.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/commands/help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,MAAM,UAAU,SAAS;IACvB,OAAO,CAAC,GAAG,CAAC;YACF,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwOlB,CAAC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/commands/help.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,376 @@
1
+ // One entry per dispatched command. Both the full `seamless --help` output and
2
+ // the per-command `seamless <command> --help` output are rendered from this, so
3
+ // a flag documented once shows up in both places.
4
+ export const COMMAND_HELP = [
5
+ {
6
+ name: "init",
7
+ usage: [
8
+ "seamless init [project-name] [--<template>]",
9
+ "seamless init [project-name] --yes [--web=<id>] [--api=<id>] [--email=<address>] [--auth=<mode>] [--admin=<mode>]",
10
+ ],
11
+ sections: [
12
+ {
13
+ heading: "init [project-name]",
14
+ body: `Scaffold a new Seamless Auth project
15
+
16
+ Without a name:
17
+ • Creates project in current directory
18
+
19
+ With a name:
20
+ • Creates new directory
21
+
22
+ With a template flag (e.g. --oauth, --react-oauth, --fastify):
23
+ • Scaffolds that starter and skips that layer's prompt
24
+ • A template answers to both its id and its short alias, so --basic and
25
+ --react-vite select the same starter
26
+ • --oauth also prompts for OIDC providers (Google, GitHub, Microsoft,
27
+ GitLab) and wires the ones you configure into the auth server
28
+ • Run seamless templates list to see every id, alias, and flag
29
+
30
+ --profile <name>
31
+ • Use that profile instead of the active one
32
+
33
+ --app <id>
34
+ • Connect the project to that managed application (needs a portal
35
+ session from seamless login)
36
+
37
+ --local
38
+ • Point the generated project at a locally running auth stack
39
+
40
+ NON-INTERACTIVE
41
+
42
+ --yes, -y
43
+ • Answer every remaining question with the recommended option instead of
44
+ prompting, for CI, a Dockerfile, or a scripted run
45
+ • Pair it with --local or --app <id>: which stack the project gets is not
46
+ something --yes will guess
47
+ • It never stands in for a destructive confirmation (see --force)
48
+
49
+ --web=<id|alias>, --api=<id|alias>
50
+ • Choose the web and api starters by name
51
+ • Default to the first selectable template of that kind in the registry
52
+
53
+ --email=<address>
54
+ • The owner address, which becomes the admin when you register
55
+ • Required under --yes unless a portal session supplies one
56
+
57
+ --auth=<docker|local>
58
+ • How the auth server runs (default: docker)
59
+
60
+ --admin=<api|image|source|none>
61
+ • Where the admin console is hosted (default: api)
62
+
63
+ --force
64
+ • Allow the two destructive steps --yes will not take on its own:
65
+ scaffolding into a directory that is not empty, and rotating a managed
66
+ application's existing service token`,
67
+ },
68
+ ],
69
+ examples: [
70
+ `seamless init
71
+ → Interactive setup in current directory`,
72
+ `seamless init my-app
73
+ → Create new project in ./my-app`,
74
+ `seamless init --oauth my-app
75
+ → Create ./my-app from the OAuth example starter`,
76
+ `seamless init my-app --local --yes --email=you@example.com
77
+ → Scaffold the recommended local stack with no prompts`,
78
+ ],
79
+ },
80
+ {
81
+ name: "templates",
82
+ usage: ["seamless templates list [--json]"],
83
+ sections: [
84
+ {
85
+ heading: "templates list [--json]",
86
+ body: `List the starters seamless init can scaffold, read from the same registry
87
+ init uses (so SEAMLESS_TEMPLATES_DIR and SEAMLESS_TEMPLATES_REF apply).
88
+ Needs no login.
89
+
90
+ • Columns: id, kind (web or api), framework, the init flags that select
91
+ it, and status
92
+ • Every template answers to --<id>; some also declare a shorter --<alias>
93
+ • Templates marked coming-soon cannot be selected yet, so they list no flag
94
+
95
+ --json
96
+ • Emit the registry entries as an array, for scripting`,
97
+ },
98
+ ],
99
+ examples: [
100
+ `seamless templates list
101
+ → Table of every available starter`,
102
+ `seamless templates list --json
103
+ → Machine-readable registry entries`,
104
+ ],
105
+ },
106
+ {
107
+ name: "check",
108
+ usage: ["seamless check"],
109
+ sections: [
110
+ {
111
+ heading: "check",
112
+ body: `Validate project setup, Docker, and running services`,
113
+ },
114
+ ],
115
+ examples: [
116
+ `seamless check
117
+ → Validate your project`,
118
+ ],
119
+ },
120
+ {
121
+ name: "verify",
122
+ usage: [
123
+ "seamless verify [--local] [--api-only] [--no-react] [--filter=<flow>] [--keep-up]",
124
+ ],
125
+ sections: [
126
+ {
127
+ heading: "verify [--local] [--api-only] [--filter=<flow>] [--keep-up]",
128
+ body: `Stand up the auth stack and run the conformance suite across the API and
129
+ the cookie (adapter) paths. Requires Docker. Builds the auth server from
130
+ a sibling seamless-auth-api checkout (override with SEAMLESS_API_DIR).
131
+
132
+ --local
133
+ • Builds and links the local @seamless-auth/* SDK source (sibling
134
+ seamless-auth-server, override with SEAMLESS_SERVER_DIR) instead of the
135
+ published npm packages, so you can catch SDK regressions before
136
+ publishing
137
+
138
+ --api-only
139
+ • Run the API layer only, skipping the adapter and browser layers
140
+
141
+ --no-react
142
+ • Skip the browser layer but keep the adapter layer
143
+
144
+ --filter=<flow>
145
+ • Run only the flows matching <flow> (the = form; a space-separated
146
+ --filter <flow> is not parsed)
147
+
148
+ --keep-up
149
+ • Leave the Docker stack running after the suite finishes`,
150
+ },
151
+ ],
152
+ examples: [
153
+ `seamless verify --api-only
154
+ → Fast pass against the API layer only`,
155
+ `seamless verify --local --filter=passkey
156
+ → Run the passkey flows against locally built SDK source`,
157
+ ],
158
+ },
159
+ {
160
+ name: "profile",
161
+ usage: ["seamless profile <list|add|use|remove|login>"],
162
+ sections: [
163
+ {
164
+ heading: "profile <list|add|use|remove|login>",
165
+ body: `Manage the Seamless Auth instances the CLI targets, stored as named
166
+ profiles in ~/.config/seamless/config.json (respects XDG_CONFIG_HOME).
167
+ A profile is an instance you administer, which is a different account from
168
+ your portal login: it lives in that instance's own user pool.
169
+
170
+ profile list
171
+ • Show configured profiles; the active one is marked with *
172
+
173
+ profile add <name> --instance-url <url> [--identifier-type email|phone]
174
+ • Create or update a profile (prompts interactively if flags are omitted)
175
+
176
+ profile use <name>
177
+ • Switch the active profile for subsequent commands
178
+
179
+ profile remove <name>
180
+ • Delete a profile
181
+
182
+ profile login [name] [identifier] [--identifier <email>] [--local]
183
+ • Log in to that instance so users, config, org, and sessions can run
184
+ • Defaults to the active profile, and does not change which one is active
185
+
186
+ The active profile can also be chosen per command with --profile <name> or
187
+ the SEAMLESS_PROFILE environment variable.`,
188
+ },
189
+ ],
190
+ },
191
+ {
192
+ name: "login",
193
+ usage: ["seamless login [identifier] [--identifier <email>] [--local]"],
194
+ sections: [
195
+ {
196
+ heading: "login [identifier]",
197
+ body: `Sign in to the Seamless portal, the managed control plane. This is the
198
+ account that authorizes connecting a project to a managed application, and
199
+ it needs no profile. Prompts for the identifier (or pass it positionally or
200
+ with --identifier) and the emailed code, then stores the session in the OS
201
+ keychain. Use seamless profile login to sign in to an auth instance.
202
+
203
+ --local
204
+ • For a local portal only. Asks the instance to return the OTP in the
205
+ response instead of emailing it, and verifies with it automatically.
206
+ • Requires the auth API to run outside production with
207
+ ALLOW_UNCREDENTIALED_DELIVERY_SECRETS=true.
208
+ • Point SEAMLESS_PORTAL_AUTH_URL at a local instance to develop against it.`,
209
+ },
210
+ ],
211
+ },
212
+ {
213
+ name: "apps",
214
+ usage: ["seamless apps <list|get>"],
215
+ sections: [
216
+ {
217
+ heading: "apps <list|get>",
218
+ body: `Show the managed applications your portal account owns. Requires a portal
219
+ session (seamless login), not an instance profile.
220
+
221
+ apps list [--json]
222
+ • Table of reference, name, plan, status, and instance URL
223
+ • The reference is the infra id, or the id before one is assigned
224
+ • Applications still provisioning are listed with (provisioning)
225
+
226
+ apps get <id|name|infra-id> [--json]
227
+ • Detail for one application, including the console URL, owners, and
228
+ whether a service token has been issued (masked, never the live value)`,
229
+ },
230
+ ],
231
+ },
232
+ {
233
+ name: "whoami",
234
+ usage: ["seamless whoami [--profile <name>]"],
235
+ sections: [
236
+ {
237
+ heading: "whoami",
238
+ body: `Show the identity behind your portal session (sub, email, roles), alongside
239
+ the instance URL. Pass --profile <name> to report an instance session
240
+ instead. Fails cleanly if not logged in.`,
241
+ },
242
+ ],
243
+ },
244
+ {
245
+ name: "logout",
246
+ usage: ["seamless logout [--all] [--profile <name>]"],
247
+ sections: [
248
+ {
249
+ heading: "logout [--all]",
250
+ body: `End your portal session and clear the local keychain tokens. Pass
251
+ --profile <name> to log out of an instance instead.
252
+ --all revokes every session for the user before clearing local tokens.`,
253
+ },
254
+ ],
255
+ },
256
+ {
257
+ name: "sessions",
258
+ usage: [
259
+ "seamless sessions [list]",
260
+ "seamless sessions revoke <id | --all> [--force]",
261
+ ],
262
+ sections: [
263
+ {
264
+ heading: "sessions [list]",
265
+ body: `List the active sessions for the logged-in user, with the current session
266
+ marked. Shows the session id, device or user agent, IP, and last-used time.`,
267
+ },
268
+ {
269
+ heading: "sessions revoke <id | --all> [--force]",
270
+ body: `Revoke one session by id, or every session with --all. Revoking the current
271
+ session (or --all) prompts for confirmation and then clears local tokens.
272
+
273
+ --force
274
+ • Skip that confirmation (--yes and -y are accepted aliases), which is also
275
+ what lets this run without a terminal attached`,
276
+ },
277
+ ],
278
+ },
279
+ {
280
+ name: "config",
281
+ usage: ["seamless config <get|set|roles|diff|apply|oauth-providers>"],
282
+ sections: [
283
+ {
284
+ heading: "config <get|set|roles|diff|apply>",
285
+ body: `Read and write the instance system configuration (requires an admin role).
286
+
287
+ config get [key] [--json]
288
+ • Print the whole config or a single key
289
+
290
+ config set <key> <value>
291
+ • Update one key; the value is parsed as JSON, falling back to a string
292
+ (for example: config set access_token_ttl 15m,
293
+ config set login_methods '["email_otp","passkey"]')
294
+
295
+ config roles [--json]
296
+ • List the instance's available roles
297
+
298
+ config diff <file>
299
+ • Show how a local JSON config file differs from the instance
300
+
301
+ config apply <file> [--dry-run] [--force]
302
+ • Apply a local JSON config file after a confirmation prompt
303
+ • --force skips the confirmation; --dry-run still changes nothing
304
+
305
+ config oauth-providers <list|add|update|remove>
306
+ • Manage OAuth providers one at a time. Client secrets stay server-side,
307
+ referenced by clientSecretEnv; the secret value is never sent.
308
+ (for example: config oauth-providers add --file google.json,
309
+ config oauth-providers update google '{"enabled":false}',
310
+ config oauth-providers remove google --force)
311
+
312
+ --force
313
+ • Skips the confirmation on apply and oauth-providers remove (--yes and -y
314
+ are accepted aliases), which is also what lets them run without a
315
+ terminal attached`,
316
+ },
317
+ ],
318
+ },
319
+ {
320
+ name: "users",
321
+ usage: [
322
+ "seamless users <list|delete|credentials|prepare-device-replacement>",
323
+ ],
324
+ sections: [
325
+ {
326
+ heading: "users <list|delete|credentials|prepare-device-replacement>",
327
+ body: `Admin user management (requires an admin role).
328
+
329
+ users list [--limit <n>] [--offset <n>] [--json]
330
+ • List users
331
+ users delete <id> [--force]
332
+ • Delete a user (asks for confirmation)
333
+ users credentials <id> [--json]
334
+ • Show a user's registered credentials
335
+ users prepare-device-replacement <id> [--force] [--keep-sessions] [--keep-passkeys] [--keep-totp]
336
+ • Admin-assisted account recovery (needs an elevated session)
337
+
338
+ --force
339
+ • Skips the confirmation on delete and prepare-device-replacement (--yes and
340
+ -y are accepted aliases), which is also what lets them run without a
341
+ terminal attached`,
342
+ },
343
+ ],
344
+ },
345
+ {
346
+ name: "org",
347
+ usage: [
348
+ "seamless org <list|create|get|update>",
349
+ "seamless org members <list|add|update|remove>",
350
+ ],
351
+ sections: [
352
+ {
353
+ heading: "org <list|create|get|update>, org members <list|add|update|remove>",
354
+ body: `Admin organization management (requires an admin role).
355
+
356
+ org list [--json]
357
+ org create <name> [--slug <slug>]
358
+ org get <id> [--json]
359
+ org update <id> [--name <name>] [--slug <slug>]
360
+ org members list <orgId> [--json]
361
+ org members add <orgId> (--user <id> | --email <email>) [--roles a,b] [--scopes a,b]
362
+ org members update <orgId> <userId> [--roles a,b] [--scopes a,b]
363
+ org members remove <orgId> <userId> [--force]
364
+
365
+ --force
366
+ • Skips the confirmation on members remove (--yes and -y are accepted
367
+ aliases), which is also what lets it run without a terminal attached`,
368
+ },
369
+ ],
370
+ },
371
+ ];
372
+ export const COMMANDS = COMMAND_HELP.map((c) => c.name);
373
+ export function findCommandHelp(name) {
374
+ return COMMAND_HELP.find((c) => c.name === name);
375
+ }
376
+ //# sourceMappingURL=helpTopics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpTopics.js","sourceRoot":"","sources":["../../src/commands/helpTopics.ts"],"names":[],"mappings":"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"}