@nocobase/app-cli-client 0.0.0-stage → 0.1.0-beta.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 (178) hide show
  1. package/README.md +24 -2
  2. package/dist/brand.d.ts +52 -0
  3. package/dist/brand.d.ts.map +1 -0
  4. package/dist/brand.js +61 -0
  5. package/dist/brand.js.map +1 -0
  6. package/dist/commands.d.ts +9 -0
  7. package/dist/commands.d.ts.map +1 -0
  8. package/dist/commands.js +30 -0
  9. package/dist/commands.js.map +1 -0
  10. package/dist/completion.d.ts +13 -0
  11. package/dist/completion.d.ts.map +1 -0
  12. package/dist/completion.js +157 -0
  13. package/dist/completion.js.map +1 -0
  14. package/dist/config.d.ts +100 -0
  15. package/dist/config.d.ts.map +1 -0
  16. package/dist/config.js +43 -0
  17. package/dist/config.js.map +1 -0
  18. package/dist/docs.d.ts +9 -0
  19. package/dist/docs.d.ts.map +1 -0
  20. package/dist/docs.js +146 -0
  21. package/dist/docs.js.map +1 -0
  22. package/dist/dynamic/execute.d.ts +24 -0
  23. package/dist/dynamic/execute.d.ts.map +1 -0
  24. package/dist/dynamic/execute.js +125 -0
  25. package/dist/dynamic/execute.js.map +1 -0
  26. package/dist/dynamic/files.d.ts +21 -0
  27. package/dist/dynamic/files.d.ts.map +1 -0
  28. package/dist/dynamic/files.js +79 -0
  29. package/dist/dynamic/files.js.map +1 -0
  30. package/dist/dynamic/help.d.ts +6 -0
  31. package/dist/dynamic/help.d.ts.map +1 -0
  32. package/dist/dynamic/help.js +42 -0
  33. package/dist/dynamic/help.js.map +1 -0
  34. package/dist/dynamic/index.d.ts +34 -0
  35. package/dist/dynamic/index.d.ts.map +1 -0
  36. package/dist/dynamic/index.js +197 -0
  37. package/dist/dynamic/index.js.map +1 -0
  38. package/dist/dynamic/manifest.d.ts +21 -0
  39. package/dist/dynamic/manifest.d.ts.map +1 -0
  40. package/dist/dynamic/manifest.js +175 -0
  41. package/dist/dynamic/manifest.js.map +1 -0
  42. package/dist/dynamic/output.d.ts +14 -0
  43. package/dist/dynamic/output.d.ts.map +1 -0
  44. package/dist/dynamic/output.js +103 -0
  45. package/dist/dynamic/output.js.map +1 -0
  46. package/dist/dynamic/parse.d.ts +3 -0
  47. package/dist/dynamic/parse.d.ts.map +1 -0
  48. package/dist/dynamic/parse.js +13 -0
  49. package/dist/dynamic/parse.js.map +1 -0
  50. package/dist/dynamic/rest.d.ts +29 -0
  51. package/dist/dynamic/rest.d.ts.map +1 -0
  52. package/dist/dynamic/rest.js +212 -0
  53. package/dist/dynamic/rest.js.map +1 -0
  54. package/dist/dynamic/session.d.ts +20 -0
  55. package/dist/dynamic/session.d.ts.map +1 -0
  56. package/dist/dynamic/session.js +70 -0
  57. package/dist/dynamic/session.js.map +1 -0
  58. package/dist/dynamic/ticket.d.ts +13 -0
  59. package/dist/dynamic/ticket.d.ts.map +1 -0
  60. package/dist/dynamic/ticket.js +40 -0
  61. package/dist/dynamic/ticket.js.map +1 -0
  62. package/dist/hooks/command-not-found.d.ts +4 -0
  63. package/dist/hooks/command-not-found.d.ts.map +1 -0
  64. package/dist/hooks/command-not-found.js +6 -0
  65. package/dist/hooks/command-not-found.js.map +1 -0
  66. package/dist/index.d.ts +8 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +14 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/install.d.ts +72 -0
  71. package/dist/install.d.ts.map +1 -0
  72. package/dist/install.js +148 -0
  73. package/dist/install.js.map +1 -0
  74. package/dist/lib/command.d.ts +35 -0
  75. package/dist/lib/command.d.ts.map +1 -0
  76. package/dist/lib/command.js +97 -0
  77. package/dist/lib/command.js.map +1 -0
  78. package/dist/lib/credentials.d.ts +110 -0
  79. package/dist/lib/credentials.d.ts.map +1 -0
  80. package/dist/lib/credentials.js +330 -0
  81. package/dist/lib/credentials.js.map +1 -0
  82. package/dist/lib/device.d.ts +48 -0
  83. package/dist/lib/device.d.ts.map +1 -0
  84. package/dist/lib/device.js +189 -0
  85. package/dist/lib/device.js.map +1 -0
  86. package/dist/lib/envelope.d.ts +21 -0
  87. package/dist/lib/envelope.d.ts.map +1 -0
  88. package/dist/lib/envelope.js +87 -0
  89. package/dist/lib/envelope.js.map +1 -0
  90. package/dist/lib/files.d.ts +4 -0
  91. package/dist/lib/files.d.ts.map +1 -0
  92. package/dist/lib/files.js +23 -0
  93. package/dist/lib/files.js.map +1 -0
  94. package/dist/lib/globals.d.ts +25 -0
  95. package/dist/lib/globals.d.ts.map +1 -0
  96. package/dist/lib/globals.js +77 -0
  97. package/dist/lib/globals.js.map +1 -0
  98. package/dist/lib/http.d.ts +45 -0
  99. package/dist/lib/http.d.ts.map +1 -0
  100. package/dist/lib/http.js +141 -0
  101. package/dist/lib/http.js.map +1 -0
  102. package/dist/lib/mime.d.ts +3 -0
  103. package/dist/lib/mime.d.ts.map +1 -0
  104. package/dist/lib/mime.js +38 -0
  105. package/dist/lib/mime.js.map +1 -0
  106. package/dist/lib/secrets/index.d.ts +18 -0
  107. package/dist/lib/secrets/index.d.ts.map +1 -0
  108. package/dist/lib/secrets/index.js +55 -0
  109. package/dist/lib/secrets/index.js.map +1 -0
  110. package/dist/lib/secrets/macos.d.ts +13 -0
  111. package/dist/lib/secrets/macos.d.ts.map +1 -0
  112. package/dist/lib/secrets/macos.js +61 -0
  113. package/dist/lib/secrets/macos.js.map +1 -0
  114. package/dist/lib/secrets/secret-service.d.ts +17 -0
  115. package/dist/lib/secrets/secret-service.d.ts.map +1 -0
  116. package/dist/lib/secrets/secret-service.js +81 -0
  117. package/dist/lib/secrets/secret-service.js.map +1 -0
  118. package/dist/lib/secrets/store.d.ts +28 -0
  119. package/dist/lib/secrets/store.d.ts.map +1 -0
  120. package/dist/lib/secrets/store.js +41 -0
  121. package/dist/lib/secrets/store.js.map +1 -0
  122. package/dist/lib/secrets/windows.d.ts +20 -0
  123. package/dist/lib/secrets/windows.d.ts.map +1 -0
  124. package/dist/lib/secrets/windows.js +155 -0
  125. package/dist/lib/secrets/windows.js.map +1 -0
  126. package/dist/lib/update-hint.d.ts +5 -0
  127. package/dist/lib/update-hint.d.ts.map +1 -0
  128. package/dist/lib/update-hint.js +26 -0
  129. package/dist/lib/update-hint.js.map +1 -0
  130. package/dist/login.d.ts +15 -0
  131. package/dist/login.d.ts.map +1 -0
  132. package/dist/login.js +232 -0
  133. package/dist/login.js.map +1 -0
  134. package/dist/logout.d.ts +13 -0
  135. package/dist/logout.d.ts.map +1 -0
  136. package/dist/logout.js +56 -0
  137. package/dist/logout.js.map +1 -0
  138. package/dist/parse/arguments.d.ts +84 -0
  139. package/dist/parse/arguments.d.ts.map +1 -0
  140. package/dist/parse/arguments.js +460 -0
  141. package/dist/parse/arguments.js.map +1 -0
  142. package/dist/parse/exit.d.ts +7 -0
  143. package/dist/parse/exit.d.ts.map +1 -0
  144. package/dist/parse/exit.js +24 -0
  145. package/dist/parse/exit.js.map +1 -0
  146. package/dist/parse/help.d.ts +22 -0
  147. package/dist/parse/help.d.ts.map +1 -0
  148. package/dist/parse/help.js +151 -0
  149. package/dist/parse/help.js.map +1 -0
  150. package/dist/parse/index.d.ts +5 -0
  151. package/dist/parse/index.d.ts.map +1 -0
  152. package/dist/parse/index.js +7 -0
  153. package/dist/parse/index.js.map +1 -0
  154. package/dist/parse/manifest.d.ts +97 -0
  155. package/dist/parse/manifest.d.ts.map +1 -0
  156. package/dist/parse/manifest.js +4 -0
  157. package/dist/parse/manifest.js.map +1 -0
  158. package/dist/profile.d.ts +4 -0
  159. package/dist/profile.d.ts.map +1 -0
  160. package/dist/profile.js +80 -0
  161. package/dist/profile.js.map +1 -0
  162. package/dist/request.d.ts +25 -0
  163. package/dist/request.d.ts.map +1 -0
  164. package/dist/request.js +35 -0
  165. package/dist/request.js.map +1 -0
  166. package/dist/run.d.ts +17 -0
  167. package/dist/run.d.ts.map +1 -0
  168. package/dist/run.js +88 -0
  169. package/dist/run.js.map +1 -0
  170. package/dist/update.d.ts +45 -0
  171. package/dist/update.d.ts.map +1 -0
  172. package/dist/update.js +177 -0
  173. package/dist/update.js.map +1 -0
  174. package/dist/whoami.d.ts +31 -0
  175. package/dist/whoami.d.ts.map +1 -0
  176. package/dist/whoami.js +118 -0
  177. package/dist/whoami.js.map +1 -0
  178. package/package.json +67 -3
@@ -0,0 +1,330 @@
1
+ // The two identities the CLI acts as:
2
+ //
3
+ // - a run: inside a run's working directory, the token in the run's credentials file, which the runner wrote there
4
+ // (`AppCliConfig.runCredentialsFile`) and deletes when the run ends, found through `AGENT_RUN_CREDENTIALS` or by
5
+ // walking up from the working directory;
6
+ // - a person: anywhere else, `<PREFIX>_API_KEY` (with `<PREFIX>_SERVER`) when set, which is how CI acts without
7
+ // signing in, else the credential of the selected profile, which `<bin> login` stored in the system keychain (or,
8
+ // where there is none, in `<state dir>/config.json`, 0600): the session token a sign-in through the browser received,
9
+ // sent as `Authorization: Bearer`, or an API key given with `--api-key-stdin`, sent as `x-api-key`. `config.json`
10
+ // names each profile's server, what its credential is and where, and which profile is current; `--profile` and
11
+ // `<PREFIX>_PROFILE` choose another.
12
+ import { existsSync } from 'node:fs';
13
+ import { readFile } from 'node:fs/promises';
14
+ import path from 'node:path';
15
+ import { EXIT_CODES, HEADERS, RUN_CREDENTIALS_ENV, RunCliCredentialSchema, } from '@nocobase/agent-protocol';
16
+ import { z } from 'zod';
17
+ import { appCliConfig, appCliPaths, } from "../config.js";
18
+ import { UsageError } from "./command.js";
19
+ import { readJson, writeJsonAtomic } from "./files.js";
20
+ import { ApiClient } from "./http.js";
21
+ import { defaultSecretStore, describeStorage, keychainAccount, keychainDisabled, keychainLabel, keychainService, } from "./secrets/index.js";
22
+ const CredentialKindSchema = z.enum(['session', 'apiKey']);
23
+ /** What a profile's credential is and where: a keychain, or `config.json` itself. */
24
+ const StoredAuthSchema = z.discriminatedUnion('storage', [
25
+ z.object({
26
+ kind: CredentialKindSchema,
27
+ storage: z.enum(['keychain', 'secret-service', 'credential-manager']),
28
+ }),
29
+ z.object({
30
+ kind: CredentialKindSchema,
31
+ storage: z.literal('file'),
32
+ key: z.string().min(1),
33
+ }),
34
+ ]);
35
+ /** One signed-in server: its address, where its key is, and what the server named the key. */
36
+ const StoredProfileSchema = z.object({
37
+ server: z.string().min(1),
38
+ auth: StoredAuthSchema,
39
+ keyId: z.string().optional(),
40
+ keyName: z.string().optional(),
41
+ });
42
+ /** `config.json`: the profiles by name, and the current one. */
43
+ const StoredConfigSchema = z.object({
44
+ current: z.string().optional(),
45
+ profiles: z.record(z.string(), StoredProfileSchema),
46
+ });
47
+ /** The profile a sign-in goes to when none is named. */
48
+ export const DEFAULT_PROFILE = 'default';
49
+ const PROFILE_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
50
+ function resolveOptions(options) {
51
+ const config = options.config ?? appCliConfig();
52
+ const env = options.env ?? process.env;
53
+ return {
54
+ config,
55
+ env,
56
+ paths: options.paths ?? appCliPaths(),
57
+ store: 'store' in options ? options.store : defaultSecretStore(config, env),
58
+ };
59
+ }
60
+ /** `<PREFIX>_<name>`, such as `ACME_API_KEY`; undefined when the CLI has no prefix or the variable is empty. */
61
+ export function envValue(config, env, name) {
62
+ if (config.envPrefix === undefined)
63
+ return undefined;
64
+ const value = env[`${config.envPrefix}_${name}`];
65
+ return value === undefined || value.trim() === '' ? undefined : value.trim();
66
+ }
67
+ /** The keychain account of a profile: the state directory, and the profile's name after `#` beside the default. */
68
+ export function profileAccount(home, profile) {
69
+ const account = keychainAccount(home);
70
+ return profile === DEFAULT_PROFILE ? account : `${account}#${profile}`;
71
+ }
72
+ /** Reads `config.json`; a file written before profiles is the default profile. */
73
+ async function readStored(paths) {
74
+ const raw = await readJson(paths.userConfig);
75
+ const parsed = StoredConfigSchema.safeParse(raw);
76
+ if (parsed.success)
77
+ return parsed.data;
78
+ const legacy = StoredProfileSchema.safeParse(raw);
79
+ if (legacy.success)
80
+ return {
81
+ current: DEFAULT_PROFILE,
82
+ profiles: { [DEFAULT_PROFILE]: legacy.data },
83
+ };
84
+ return { profiles: {} };
85
+ }
86
+ async function writeStored(paths, stored) {
87
+ await writeJsonAtomic(paths.userConfig, stored);
88
+ }
89
+ /** The profile a command acts as: `--profile`, `<PREFIX>_PROFILE`, the current one, or `default`. */
90
+ export function selectedProfile(stored, options, config, env) {
91
+ return (options.profile ??
92
+ envValue(config, env, 'PROFILE') ??
93
+ stored.current ??
94
+ DEFAULT_PROFILE);
95
+ }
96
+ /** Refuses a name a profile cannot have. */
97
+ export function checkProfileName(name) {
98
+ if (!PROFILE_NAME.test(name))
99
+ throw new UsageError(`Not a profile name: ${name}. Use letters, digits, ".", "_" and "-".`);
100
+ return name;
101
+ }
102
+ /**
103
+ * The key the CLI acts with, or undefined when nobody is signed in: `<PREFIX>_API_KEY` (with `<PREFIX>_SERVER`, or the
104
+ * profile's server), else the selected profile's. Throws a `UsageError` when the key is in a keychain that cannot be
105
+ * read or no longer has it, and inside an agent run, which never acts as the person.
106
+ */
107
+ export async function readUserConfig(options = {}) {
108
+ const { config, env, paths, store } = resolveOptions(options);
109
+ const named = env[RUN_CREDENTIALS_ENV];
110
+ if (named !== undefined && named !== '')
111
+ throw new UsageError(`This is an agent run, and its credentials file (${named}) is gone: the run has ended.`, EXIT_CODES.auth);
112
+ const stored = await readStored(paths);
113
+ const profile = selectedProfile(stored, options, config, env);
114
+ const entry = stored.profiles[profile];
115
+ const envKey = envValue(config, env, 'API_KEY');
116
+ if (envKey !== undefined) {
117
+ const server = envValue(config, env, 'SERVER') ?? entry?.server;
118
+ if (server === undefined)
119
+ throw new UsageError(`${config.envPrefix}_API_KEY is set without a server: set ${config.envPrefix}_SERVER too.`, EXIT_CODES.auth);
120
+ return {
121
+ server: normalizeServer(server),
122
+ key: envKey,
123
+ kind: 'apiKey',
124
+ storage: 'env',
125
+ };
126
+ }
127
+ if (entry === undefined) {
128
+ if (options.profile !== undefined &&
129
+ Object.keys(stored.profiles).length > 0)
130
+ throw new UsageError(`There is no profile ${profile}. \`${config.bin} profile list\` shows them.`, EXIT_CODES.auth);
131
+ return undefined;
132
+ }
133
+ const server = envValue(config, env, 'SERVER') ?? entry.server;
134
+ const known = {
135
+ profile,
136
+ kind: entry.auth.kind,
137
+ ...(entry.keyId ? { keyId: entry.keyId } : {}),
138
+ ...(entry.keyName ? { keyName: entry.keyName } : {}),
139
+ };
140
+ if (entry.auth.storage === 'file')
141
+ return { server, key: entry.auth.key, storage: 'file', ...known };
142
+ const where = describeStorage(entry.auth.storage, paths.userConfig);
143
+ const again = `Run \`${config.bin} login${profile === DEFAULT_PROFILE ? '' : ` --profile ${profile}`}\` again.`;
144
+ if (store?.kind !== entry.auth.storage)
145
+ throw new UsageError(`The credential is in ${where}, which this process cannot use${config.keychainEnv === undefined ? '' : ` (${config.keychainEnv}=off?)`}. ${again}`, EXIT_CODES.auth);
146
+ let key;
147
+ try {
148
+ key = await store.get(keychainService(config), profileAccount(paths.home, profile));
149
+ }
150
+ catch (error) {
151
+ throw new UsageError(`${error instanceof Error ? error.message : String(error)}. Unlock it, or ${again.toLowerCase()}`, EXIT_CODES.auth);
152
+ }
153
+ if (key === undefined)
154
+ throw new UsageError(`The credential is gone from ${where}. ${again}`, EXIT_CODES.auth);
155
+ return { server, key, storage: entry.auth.storage, ...known };
156
+ }
157
+ /**
158
+ * The server and profile a command would act as, read without its key (no keychain is touched): what completion needs
159
+ * to find the cached manifest. Undefined when nobody is signed in.
160
+ */
161
+ export async function peekUserConfig(options = {}) {
162
+ const { config, env, paths } = resolveOptions(options);
163
+ const stored = await readStored(paths).catch(() => ({
164
+ profiles: {},
165
+ }));
166
+ const profile = selectedProfile(stored, options, config, env);
167
+ const entry = stored.profiles[profile];
168
+ if (envValue(config, env, 'API_KEY') !== undefined) {
169
+ const server = envValue(config, env, 'SERVER') ?? entry?.server;
170
+ return server === undefined
171
+ ? undefined
172
+ : { server: normalizeServer(server) };
173
+ }
174
+ if (entry === undefined)
175
+ return undefined;
176
+ return { server: envValue(config, env, 'SERVER') ?? entry.server, profile };
177
+ }
178
+ /**
179
+ * Stores the credential of `server` as a profile (the selected one, `default` at first) and makes it current: in the
180
+ * keychain, or in `config.json` (0600) with a warning when there is no usable keychain.
181
+ */
182
+ export async function saveUserConfig(server, key, options = {}) {
183
+ const { config, env, paths, store } = resolveOptions(options);
184
+ const stored = await readStored(paths);
185
+ const profile = checkProfileName(options.profile ??
186
+ envValue(config, env, 'PROFILE') ??
187
+ stored.current ??
188
+ DEFAULT_PROFILE);
189
+ const service = keychainService(config);
190
+ const account = profileAccount(paths.home, profile);
191
+ const kind = options.kind ?? 'apiKey';
192
+ const info = {
193
+ ...(options.keyId ? { keyId: options.keyId } : {}),
194
+ ...(options.keyName ? { keyName: options.keyName } : {}),
195
+ };
196
+ const save = async (entry) => writeStored(paths, {
197
+ current: profile,
198
+ profiles: { ...stored.profiles, [profile]: entry },
199
+ });
200
+ let reason = keychainDisabled(config, env) && config.keychainEnv !== undefined
201
+ ? `${config.keychainEnv} turns the system keychain off`
202
+ : 'There is no usable system keychain here';
203
+ if (store !== undefined && (await store.available())) {
204
+ try {
205
+ await store.set(service, account, key, keychainLabel(config, server));
206
+ await save({
207
+ server,
208
+ auth: { kind, storage: store.kind },
209
+ ...info,
210
+ });
211
+ return { storage: store.kind, profile };
212
+ }
213
+ catch (error) {
214
+ reason = error instanceof Error ? error.message : String(error);
215
+ }
216
+ }
217
+ await save({
218
+ server,
219
+ auth: { kind, storage: 'file', key },
220
+ ...info,
221
+ });
222
+ // A key an earlier login kept in the keychain is not the one in use any more.
223
+ if (store !== undefined)
224
+ await store.delete(service, account).catch(() => undefined);
225
+ return {
226
+ storage: 'file',
227
+ profile,
228
+ warning: `${reason.replace(/\.$/u, '')}; the ${kind === 'session' ? 'session token' : 'API key'} is stored in ${describeStorage('file', paths.userConfig)}.`,
229
+ };
230
+ }
231
+ /** The profiles, current first, without their keys. */
232
+ export async function listProfiles(options = {}) {
233
+ const { config, env, paths } = resolveOptions(options);
234
+ const stored = await readStored(paths);
235
+ const current = selectedProfile(stored, options, config, env);
236
+ return Object.entries(stored.profiles)
237
+ .map(([name, entry]) => ({
238
+ name,
239
+ server: entry.server,
240
+ storage: entry.auth.storage,
241
+ kind: entry.auth.kind,
242
+ ...(entry.keyName ? { keyName: entry.keyName } : {}),
243
+ current: name === current,
244
+ }))
245
+ .sort((a, b) => a.current === b.current
246
+ ? a.name.localeCompare(b.name)
247
+ : a.current
248
+ ? -1
249
+ : 1);
250
+ }
251
+ /** Makes `name` the current profile. */
252
+ export async function useProfile(name, options = {}) {
253
+ const { config, paths } = resolveOptions(options);
254
+ const stored = await readStored(paths);
255
+ if (!(name in stored.profiles))
256
+ throw new UsageError(`There is no profile ${name}. \`${config.bin} profile list\` shows them.`, EXIT_CODES.notFound);
257
+ await writeStored(paths, { ...stored, current: name });
258
+ }
259
+ /**
260
+ * Forgets a profile: its key leaves the keychain and `config.json`. The current profile becomes the first one left.
261
+ * Answers what was forgotten, or undefined when there was no such profile.
262
+ */
263
+ export async function removeProfile(name, options = {}) {
264
+ const { config, paths, store } = resolveOptions(options);
265
+ const stored = await readStored(paths);
266
+ const entry = stored.profiles[name];
267
+ if (entry === undefined)
268
+ return undefined;
269
+ const profiles = { ...stored.profiles };
270
+ delete profiles[name];
271
+ if (store !== undefined)
272
+ await store
273
+ .delete(keychainService(config), profileAccount(paths.home, name))
274
+ .catch(() => undefined);
275
+ const left = Object.keys(profiles).sort();
276
+ const current = stored.current === name ? left[0] : stored.current;
277
+ await writeStored(paths, {
278
+ ...(current === undefined ? {} : { current }),
279
+ profiles,
280
+ });
281
+ return { server: entry.server };
282
+ }
283
+ /** The headers a credential authenticates with: `Authorization: Bearer` for a session token, `x-api-key` for a key. */
284
+ export function credentialHeaders(credential) {
285
+ return credential.kind === 'session'
286
+ ? { authorization: `Bearer ${credential.key}` }
287
+ : { [HEADERS.apiKey]: credential.key };
288
+ }
289
+ export function userClient(config) {
290
+ return new ApiClient({
291
+ server: config.server,
292
+ headers: credentialHeaders(config),
293
+ });
294
+ }
295
+ export function runClient(credential) {
296
+ return new ApiClient({
297
+ server: credential.server,
298
+ headers: { [HEADERS.runToken]: credential.token },
299
+ });
300
+ }
301
+ /** Accepts `https://host/path` and `host:port`; drops a trailing slash. */
302
+ export function normalizeServer(server) {
303
+ const withScheme = /^https?:\/\//.test(server) ? server : `http://${server}`;
304
+ const url = new URL(withScheme);
305
+ return url.href.replace(/\/+$/, '');
306
+ }
307
+ /**
308
+ * The run's credentials file: the one the runner names for this process (`AGENT_RUN_CREDENTIALS`, set only for the CLI
309
+ * by the command the runner puts on the agent's PATH, so it works from a directory outside the run's own), else the
310
+ * nearest one at or above `from`.
311
+ */
312
+ export function findRunCredentials(from, config = appCliConfig(), env = process.env) {
313
+ const named = env[RUN_CREDENTIALS_ENV];
314
+ if (named !== undefined && named !== '' && existsSync(named))
315
+ return path.resolve(named);
316
+ let current = path.resolve(from);
317
+ for (;;) {
318
+ const candidate = path.join(current, config.runCredentialsFile);
319
+ if (existsSync(candidate))
320
+ return candidate;
321
+ const parent = path.dirname(current);
322
+ if (parent === current)
323
+ return undefined;
324
+ current = parent;
325
+ }
326
+ }
327
+ export async function readRunCredentials(file) {
328
+ return RunCliCredentialSchema.parse(JSON.parse(await readFile(file, 'utf8')));
329
+ }
330
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/lib/credentials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { type AppCliAuth } from '../config.ts';
2
+ /** What the server answers a new authorization: the codes, where to approve, and how often to ask. */
3
+ export interface DeviceAuthorization {
4
+ readonly deviceCode: string;
5
+ readonly userCode: string;
6
+ readonly verificationUri: string;
7
+ readonly verificationUriComplete: string;
8
+ /** Seconds. */
9
+ readonly expiresIn: number;
10
+ /** Seconds between polls. */
11
+ readonly interval: number;
12
+ }
13
+ /** What the server answers once the person approved: the session token, and seconds until it expires. */
14
+ export interface IssuedSession {
15
+ readonly token: string;
16
+ readonly expiresIn?: number | undefined;
17
+ }
18
+ /** What a CLI's requests say of it, which the server keeps with the session: the CLI, its version, the machine. */
19
+ export declare function cliUserAgent(client: {
20
+ readonly bin: string;
21
+ readonly version?: string | undefined;
22
+ }, host?: string): string;
23
+ export interface DeviceRequestOptions {
24
+ readonly fetch?: typeof fetch;
25
+ readonly userAgent?: string;
26
+ }
27
+ export declare function startDeviceAuthorization(server: string, auth: AppCliAuth, options?: DeviceRequestOptions): Promise<DeviceAuthorization>;
28
+ export interface PollOptions extends DeviceRequestOptions {
29
+ readonly sleep?: (ms: number) => Promise<void>;
30
+ readonly now?: () => number;
31
+ }
32
+ /**
33
+ * Polls until the server answers the session token; an `AppApiError` when the person declined (`ACCESS_DENIED`), the
34
+ * code expired (`EXPIRED_TOKEN`), or the server refused it (`INVALID_GRANT`). `SLOW_DOWN` adds five seconds to the
35
+ * interval, as RFC 8628 asks.
36
+ */
37
+ export declare function pollDeviceAuthorization(server: string, auth: AppCliAuth, started: DeviceAuthorization, options?: PollOptions): Promise<IssuedSession>;
38
+ /**
39
+ * The command that opens a page in this machine's browser, or undefined where there is none to see it: a session over
40
+ * SSH, or a Linux machine with no display. The sign-in page is then opened on another device.
41
+ */
42
+ export declare function browserOpener(platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): {
43
+ file: string;
44
+ args: (url: string) => string[];
45
+ } | undefined;
46
+ /** Opens `url` in the default browser; false when this machine has none to open it in. */
47
+ export declare function openBrowser(url: string, platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): boolean;
48
+ //# sourceMappingURL=device.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/lib/device.ts"],"names":[],"mappings":"AAYA,OAAO,EAA8B,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAa3E,sGAAsG;AACtG,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,uBAAuB,EAAE,MAAM,CAAC;IACzC,eAAe;IACf,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,6BAA6B;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAQD,yGAAyG;AACzG,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAOD,mHAAmH;AACnH,wBAAgB,YAAY,CAC1B,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,EACvE,IAAI,GAAE,MAAsB,GAC3B,MAAM,CAER;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAsDD,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CAsB9B;AAMD,MAAM,WAAW,WAAY,SAAQ,oBAAoB;IACvD,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,mBAAmB,EAC5B,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,aAAa,CAAC,CAoCxB;AAwBD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,CAiB/D;AAED,0FAA0F;AAC1F,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAcT"}
@@ -0,0 +1,189 @@
1
+ // Signing in through the browser (`AppCliConfig.auth`), RFC 8628 as Better Auth's `deviceAuthorization()` serves it:
2
+ // the CLI asks for a device code and a short user code, shows the code and opens the page where the signed-in person
3
+ // approves it, and polls until the server answers a session token, the person declines, or the code expires. The
4
+ // endpoints answer RFC 8628's bodies (`{ device_code, ... }`, `{ error, error_description }`), not the application's
5
+ // standard ones, so they are read here rather than through `ApiClient`.
6
+ import { spawn } from 'node:child_process';
7
+ import { accessSync, constants } from 'node:fs';
8
+ import os from 'node:os';
9
+ import path from 'node:path';
10
+ import { z } from 'zod';
11
+ import { authRouteOf, cliClientIdOf } from "../config.js";
12
+ import { serverPath, urlFor } from "../dynamic/session.js";
13
+ import { AppApiError } from "./http.js";
14
+ const StartedSchema = z.object({
15
+ device_code: z.string().min(1),
16
+ user_code: z.string().min(1),
17
+ verification_uri: z.string().min(1),
18
+ verification_uri_complete: z.string().min(1).optional(),
19
+ expires_in: z.number().positive(),
20
+ interval: z.number().positive().optional(),
21
+ });
22
+ const IssuedSchema = z.object({
23
+ access_token: z.string().min(1),
24
+ token_type: z.string().optional(),
25
+ expires_in: z.number().optional(),
26
+ });
27
+ const ErrorSchema = z.object({
28
+ error: z.string(),
29
+ error_description: z.string().optional(),
30
+ });
31
+ /** What a CLI's requests say of it, which the server keeps with the session: the CLI, its version, the machine. */
32
+ export function cliUserAgent(client, host = os.hostname()) {
33
+ return `${client.bin}/${client.version ?? '0'} (${host}; ${process.platform} ${process.arch}) node/${process.versions.node}`;
34
+ }
35
+ /**
36
+ * POSTs to a device endpoint. A failure is an `AppApiError` whose `reason` is the RFC 8628 `error` in capitals,
37
+ * such as `AUTHORIZATION_PENDING` or `ACCESS_DENIED`.
38
+ */
39
+ async function postDevice(server, route, body, options) {
40
+ const url = urlFor(server, route);
41
+ let response;
42
+ try {
43
+ response = await (options.fetch ?? fetch)(url, {
44
+ method: 'POST',
45
+ headers: {
46
+ 'content-type': 'application/json',
47
+ accept: 'application/json',
48
+ ...(options.userAgent ? { 'user-agent': options.userAgent } : {}),
49
+ },
50
+ body: JSON.stringify(body),
51
+ signal: AbortSignal.timeout(30_000),
52
+ });
53
+ }
54
+ catch (error) {
55
+ throw new AppApiError(0, 'NETWORK', `Could not reach ${url.origin}: ${error instanceof Error ? error.message : String(error)}`);
56
+ }
57
+ const text = await response.text().catch(() => '');
58
+ let parsed;
59
+ try {
60
+ parsed = text === '' ? undefined : JSON.parse(text);
61
+ }
62
+ catch {
63
+ parsed = undefined;
64
+ }
65
+ if (response.ok)
66
+ return parsed;
67
+ const failure = ErrorSchema.safeParse(parsed);
68
+ if (failure.success)
69
+ throw new AppApiError(response.status, failure.data.error.toUpperCase(), failure.data.error_description ?? failure.data.error);
70
+ throw new AppApiError(response.status, `HTTP_${response.status}`, `POST ${url.pathname} answered ${response.status}`);
71
+ }
72
+ export async function startDeviceAuthorization(server, auth, options = {}) {
73
+ const started = StartedSchema.parse(await postDevice(server, serverPath(server, authRouteOf(auth, '/device/code')), { client_id: cliClientIdOf(auth) }, options));
74
+ // The server may answer the page below its origin, not knowing the address it is reached at.
75
+ const origin = new URL(server).origin;
76
+ const verificationUri = new URL(started.verification_uri, origin).href;
77
+ return {
78
+ deviceCode: started.device_code,
79
+ userCode: started.user_code,
80
+ verificationUri,
81
+ verificationUriComplete: started.verification_uri_complete
82
+ ? new URL(started.verification_uri_complete, origin).href
83
+ : verificationUri,
84
+ expiresIn: started.expires_in,
85
+ interval: started.interval ?? 5,
86
+ };
87
+ }
88
+ /** Reasons the token endpoint answers while the person has not approved yet. */
89
+ const PENDING = 'AUTHORIZATION_PENDING';
90
+ const SLOW_DOWN = 'SLOW_DOWN';
91
+ /**
92
+ * Polls until the server answers the session token; an `AppApiError` when the person declined (`ACCESS_DENIED`), the
93
+ * code expired (`EXPIRED_TOKEN`), or the server refused it (`INVALID_GRANT`). `SLOW_DOWN` adds five seconds to the
94
+ * interval, as RFC 8628 asks.
95
+ */
96
+ export async function pollDeviceAuthorization(server, auth, started, options = {}) {
97
+ const sleep = options.sleep ??
98
+ ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
99
+ const now = options.now ?? Date.now;
100
+ const deadline = now() + started.expiresIn * 1000;
101
+ let interval = started.interval * 1000;
102
+ const route = serverPath(server, authRouteOf(auth, '/device/token'));
103
+ for (;;) {
104
+ await sleep(interval);
105
+ try {
106
+ const issued = IssuedSchema.parse(await postDevice(server, route, {
107
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
108
+ device_code: started.deviceCode,
109
+ client_id: cliClientIdOf(auth),
110
+ }, options));
111
+ return { token: issued.access_token, expiresIn: issued.expires_in };
112
+ }
113
+ catch (error) {
114
+ if (!(error instanceof AppApiError))
115
+ throw error;
116
+ if (error.reason === SLOW_DOWN)
117
+ interval += 5000;
118
+ else if (error.reason !== PENDING && !error.transient)
119
+ throw error;
120
+ if (now() >= deadline)
121
+ throw new AppApiError(400, 'EXPIRED_TOKEN', 'The code expired before it was approved. Sign in again.');
122
+ }
123
+ }
124
+ }
125
+ /** Linux and BSD openers, tried in order as GitHub CLI does: the desktop's own, Debian's alternatives, then WSL's. */
126
+ const UNIX_OPENERS = [
127
+ 'xdg-open',
128
+ 'x-www-browser',
129
+ 'www-browser',
130
+ 'wslview',
131
+ ];
132
+ function onPath(name, env) {
133
+ for (const dir of (env.PATH ?? '').split(path.delimiter)) {
134
+ if (!dir)
135
+ continue;
136
+ const file = path.join(dir, name);
137
+ try {
138
+ accessSync(file, constants.X_OK);
139
+ return file;
140
+ }
141
+ catch {
142
+ // Not here.
143
+ }
144
+ }
145
+ return undefined;
146
+ }
147
+ /**
148
+ * The command that opens a page in this machine's browser, or undefined where there is none to see it: a session over
149
+ * SSH, or a Linux machine with no display. The sign-in page is then opened on another device.
150
+ */
151
+ export function browserOpener(platform = process.platform, env = process.env) {
152
+ if (platform === 'darwin')
153
+ return env.SSH_CONNECTION || env.SSH_TTY
154
+ ? undefined
155
+ : { file: 'open', args: (url) => [url] };
156
+ if (platform === 'win32')
157
+ return {
158
+ file: 'cmd',
159
+ args: (url) => ['/c', 'start', '""', url.replaceAll('&', '^&')],
160
+ };
161
+ const wsl = Boolean(env.WSL_DISTRO_NAME);
162
+ if (!wsl && !env.DISPLAY && !env.WAYLAND_DISPLAY)
163
+ return undefined;
164
+ for (const name of UNIX_OPENERS) {
165
+ const file = onPath(name, env);
166
+ if (file)
167
+ return { file, args: (url) => [url] };
168
+ }
169
+ return undefined;
170
+ }
171
+ /** Opens `url` in the default browser; false when this machine has none to open it in. */
172
+ export function openBrowser(url, platform = process.platform, env = process.env) {
173
+ const opener = browserOpener(platform, env);
174
+ if (!opener)
175
+ return false;
176
+ try {
177
+ const child = spawn(opener.file, opener.args(url), {
178
+ stdio: 'ignore',
179
+ detached: true,
180
+ });
181
+ child.on('error', () => undefined);
182
+ child.unref();
183
+ return true;
184
+ }
185
+ catch {
186
+ return false;
187
+ }
188
+ }
189
+ //# sourceMappingURL=device.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device.js","sourceRoot":"","sources":["../../src/lib/device.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { type CommandErrorJson, type CommandJson, type CommandSuggestion } from '@nocobase/cli-envelope';
2
+ import { type ExitCode } from '@nocobase/agent-protocol';
3
+ export type Envelope = CommandJson;
4
+ /** A failure the CLI raises itself, with what the envelope says of it. */
5
+ export declare class CliCommandError extends Error {
6
+ readonly code: string;
7
+ readonly suggestions: readonly CommandSuggestion[];
8
+ readonly details: unknown;
9
+ /** The exit code; 1 when not given. */
10
+ readonly exit: ExitCode;
11
+ constructor(code: string, message: string, options?: {
12
+ readonly suggestions?: readonly CommandSuggestion[];
13
+ readonly details?: unknown;
14
+ readonly exit?: ExitCode;
15
+ });
16
+ }
17
+ /** A failure as the envelope's `error`. */
18
+ export declare function errorJsonOf(error: unknown, bin?: string): CommandErrorJson;
19
+ export declare function successEnvelope(command: string, result: unknown, warnings?: readonly string[], status?: 'success' | 'success-noop'): Envelope;
20
+ export declare function failureEnvelope(command: string, error: unknown, warnings?: readonly string[], bin?: string): Envelope;
21
+ //# sourceMappingURL=envelope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../src/lib/envelope.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAMrE,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC;AAEnC,0EAA0E;AAC1E,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACnD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;gBAGtB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QACP,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;QACpD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;KACrB;CAST;AAsBD,2CAA2C;AAC3C,wBAAgB,WAAW,CACzB,KAAK,EAAE,OAAO,EACd,GAAG,SAAiB,GACnB,gBAAgB,CAkClB;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,OAAO,EACf,QAAQ,GAAE,SAAS,MAAM,EAAO,EAChC,MAAM,GAAE,SAAS,GAAG,cAA0B,GAC7C,QAAQ,CAEV;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,EACd,QAAQ,GAAE,SAAS,MAAM,EAAO,EAChC,GAAG,CAAC,EAAE,MAAM,GACX,QAAQ,CAEV"}