@invinite-org/invinite-data-cli 3.0.0 → 4.1.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 (129) hide show
  1. package/README.md +341 -374
  2. package/claude-plugin/.claude-plugin/plugin.json +1 -1
  3. package/claude-plugin/agents/invinite-data.md +59 -28
  4. package/claude-plugin/commands/analyze-earnings-call.md +15 -14
  5. package/claude-plugin/commands/analyze-filing.md +8 -7
  6. package/claude-plugin/commands/compare-companies.md +5 -5
  7. package/claude-plugin/commands/financial-research.md +9 -9
  8. package/claude-plugin/commands/ownership-review.md +6 -6
  9. package/claude-plugin/skills/invinite-data-cli/SKILL.md +466 -570
  10. package/dist/bin/invd.js +11 -2
  11. package/dist/bin/invd.js.map +1 -1
  12. package/dist/src/cli.d.ts +2 -0
  13. package/dist/src/cli.js +48 -29
  14. package/dist/src/cli.js.map +1 -1
  15. package/dist/src/client/api-client.d.ts +24 -24
  16. package/dist/src/client/api-client.js +52 -70
  17. package/dist/src/client/api-client.js.map +1 -1
  18. package/dist/src/client/pagination.d.ts +12 -11
  19. package/dist/src/client/pagination.js +47 -56
  20. package/dist/src/client/pagination.js.map +1 -1
  21. package/dist/src/commands/agent-setup.d.ts +21 -0
  22. package/dist/src/commands/agent-setup.js +112 -0
  23. package/dist/src/commands/agent-setup.js.map +1 -0
  24. package/dist/src/commands/api.d.ts +27 -0
  25. package/dist/src/commands/api.js +180 -0
  26. package/dist/src/commands/api.js.map +1 -0
  27. package/dist/src/commands/auth.d.ts +37 -0
  28. package/dist/src/commands/auth.js +336 -0
  29. package/dist/src/commands/auth.js.map +1 -0
  30. package/dist/src/commands/completion.d.ts +7 -0
  31. package/dist/src/commands/completion.js +115 -0
  32. package/dist/src/commands/completion.js.map +1 -0
  33. package/dist/src/commands/config.d.ts +4 -0
  34. package/dist/src/commands/config.js +85 -48
  35. package/dist/src/commands/config.js.map +1 -1
  36. package/dist/src/commands/plugin.d.ts +8 -0
  37. package/dist/src/commands/plugin.js +8 -10
  38. package/dist/src/commands/plugin.js.map +1 -1
  39. package/dist/src/config/auth.d.ts +17 -1
  40. package/dist/src/config/auth.js +50 -36
  41. package/dist/src/config/auth.js.map +1 -1
  42. package/dist/src/config/config-manager.d.ts +56 -4
  43. package/dist/src/config/config-manager.js +173 -29
  44. package/dist/src/config/config-manager.js.map +1 -1
  45. package/dist/src/config/toml.d.ts +7 -0
  46. package/dist/src/config/toml.js +79 -0
  47. package/dist/src/config/toml.js.map +1 -0
  48. package/dist/src/examples.d.ts +22 -0
  49. package/dist/src/examples.js +56 -0
  50. package/dist/src/examples.js.map +1 -0
  51. package/dist/src/generated/cli-manifest.json +5573 -5140
  52. package/dist/src/hand-written-commands.d.ts +11 -41
  53. package/dist/src/hand-written-commands.js +7 -17
  54. package/dist/src/hand-written-commands.js.map +1 -1
  55. package/dist/src/output/jq.d.ts +15 -0
  56. package/dist/src/output/jq.js +234 -0
  57. package/dist/src/output/jq.js.map +1 -0
  58. package/dist/src/output/options.d.ts +29 -0
  59. package/dist/src/output/options.js +72 -0
  60. package/dist/src/output/options.js.map +1 -0
  61. package/dist/src/output/render.d.ts +54 -0
  62. package/dist/src/output/render.js +160 -0
  63. package/dist/src/output/render.js.map +1 -0
  64. package/dist/src/shared/errors.d.ts +59 -15
  65. package/dist/src/shared/errors.js +126 -38
  66. package/dist/src/shared/errors.js.map +1 -1
  67. package/dist/src/shared/prompt.d.ts +10 -0
  68. package/dist/src/shared/prompt.js +24 -0
  69. package/dist/src/shared/prompt.js.map +1 -0
  70. package/dist/src/shared/spinner.js +2 -1
  71. package/dist/src/shared/spinner.js.map +1 -1
  72. package/dist/src/spec-commands.d.ts +14 -6
  73. package/dist/src/spec-commands.js +454 -174
  74. package/dist/src/spec-commands.js.map +1 -1
  75. package/dist/src/spec-flags.d.ts +11 -6
  76. package/dist/src/spec-flags.js +14 -7
  77. package/dist/src/spec-flags.js.map +1 -1
  78. package/dist/src/spec-manifest.d.ts +416 -116
  79. package/dist/src/spec-manifest.js +44 -13
  80. package/dist/src/spec-manifest.js.map +1 -1
  81. package/dist/src/update-notifier.d.ts +9 -0
  82. package/dist/src/update-notifier.js +63 -0
  83. package/dist/src/update-notifier.js.map +1 -0
  84. package/package.json +2 -3
  85. package/dist/src/client/earnings-live.d.ts +0 -194
  86. package/dist/src/client/earnings-live.js +0 -300
  87. package/dist/src/client/earnings-live.js.map +0 -1
  88. package/dist/src/client/news-live.d.ts +0 -72
  89. package/dist/src/client/news-live.js +0 -120
  90. package/dist/src/client/news-live.js.map +0 -1
  91. package/dist/src/client/pdf.d.ts +0 -15
  92. package/dist/src/client/pdf.js +0 -15
  93. package/dist/src/client/pdf.js.map +0 -1
  94. package/dist/src/client/websocket-client.d.ts +0 -19
  95. package/dist/src/client/websocket-client.js +0 -174
  96. package/dist/src/client/websocket-client.js.map +0 -1
  97. package/dist/src/commands/earnings.d.ts +0 -16
  98. package/dist/src/commands/earnings.js +0 -464
  99. package/dist/src/commands/earnings.js.map +0 -1
  100. package/dist/src/commands/login.d.ts +0 -15
  101. package/dist/src/commands/login.js +0 -249
  102. package/dist/src/commands/login.js.map +0 -1
  103. package/dist/src/commands/news.d.ts +0 -2
  104. package/dist/src/commands/news.js +0 -69
  105. package/dist/src/commands/news.js.map +0 -1
  106. package/dist/src/commands/sec.d.ts +0 -47
  107. package/dist/src/commands/sec.js +0 -191
  108. package/dist/src/commands/sec.js.map +0 -1
  109. package/dist/src/commands/ws.d.ts +0 -33
  110. package/dist/src/commands/ws.js +0 -116
  111. package/dist/src/commands/ws.js.map +0 -1
  112. package/dist/src/formatters/json-formatter.d.ts +0 -1
  113. package/dist/src/formatters/json-formatter.js +0 -4
  114. package/dist/src/formatters/json-formatter.js.map +0 -1
  115. package/dist/src/formatters/table-formatter.d.ts +0 -4
  116. package/dist/src/formatters/table-formatter.js +0 -73
  117. package/dist/src/formatters/table-formatter.js.map +0 -1
  118. package/dist/src/formatters/time.d.ts +0 -2
  119. package/dist/src/formatters/time.js +0 -14
  120. package/dist/src/formatters/time.js.map +0 -1
  121. package/dist/src/shared/output.d.ts +0 -3
  122. package/dist/src/shared/output.js +0 -13
  123. package/dist/src/shared/output.js.map +0 -1
  124. package/dist/src/shared/readiness.d.ts +0 -4
  125. package/dist/src/shared/readiness.js +0 -60
  126. package/dist/src/shared/readiness.js.map +0 -1
  127. package/dist/src/shared/types.d.ts +0 -11
  128. package/dist/src/shared/types.js +0 -2
  129. package/dist/src/shared/types.js.map +0 -1
@@ -0,0 +1,336 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import { createServer } from 'node:http';
3
+ import { hostname } from 'node:os';
4
+ import { spawn } from 'node:child_process';
5
+ import { createInterface } from 'node:readline/promises';
6
+ import chalk from 'chalk';
7
+ import { apiCall } from '../client/api-client.js';
8
+ import { clearApiKey, keyHint, resolveApiKey, setApiKey } from '../config/auth.js';
9
+ import { DASHBOARD_URL, getBaseUrl } from '../config/config-manager.js';
10
+ import { AuthRequiredError, UsageError, withErrorHandling } from '../shared/errors.js';
11
+ import { readStdin } from '../shared/prompt.js';
12
+ const CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
13
+ const KEY_LIFETIME_MS = 90 * 24 * 60 * 60 * 1000;
14
+ const MAX_BIND_ATTEMPTS = 3;
15
+ async function readLine(prompt, signal) {
16
+ const rl = createInterface({ input: process.stdin, output: process.stderr });
17
+ try {
18
+ return await rl.question(prompt, { signal });
19
+ }
20
+ finally {
21
+ rl.close();
22
+ }
23
+ }
24
+ const defaultDependencies = {
25
+ fetch: globalThis.fetch,
26
+ openBrowser,
27
+ timeoutMs: CALLBACK_TIMEOUT_MS,
28
+ readPasted: readLine,
29
+ };
30
+ function errorMessage(error) {
31
+ return error instanceof Error ? error.message : String(error);
32
+ }
33
+ async function parseEnvelope(response) {
34
+ try {
35
+ return await response.json();
36
+ }
37
+ catch {
38
+ return undefined;
39
+ }
40
+ }
41
+ function browserCommand(url) {
42
+ if (process.platform === 'darwin')
43
+ return { command: 'open', args: [url] };
44
+ if (process.platform === 'win32')
45
+ return { command: 'cmd', args: ['/c', 'start', '', url] };
46
+ return { command: 'xdg-open', args: [url] };
47
+ }
48
+ async function openBrowser(url) {
49
+ const target = browserCommand(url);
50
+ await new Promise((resolve, reject) => {
51
+ const child = spawn(target.command, target.args, { detached: true, stdio: 'ignore' });
52
+ child.once('error', reject);
53
+ child.once('spawn', () => {
54
+ child.unref();
55
+ resolve();
56
+ });
57
+ });
58
+ }
59
+ function callbackHtml(title, message) {
60
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8"><title>${title}</title></head><body><main><h1>${title}</h1><p>${message}</p></main></body></html>`;
61
+ }
62
+ async function closeServer(server) {
63
+ if (!server.listening)
64
+ return;
65
+ await new Promise((resolve) => server.close(() => resolve()));
66
+ }
67
+ async function listenOnRandomPort(server) {
68
+ for (let attempt = 0; attempt < MAX_BIND_ATTEMPTS; attempt += 1) {
69
+ const port = 49_152 + randomBytes(2).readUInt16BE(0) % (65_535 - 49_152 + 1);
70
+ try {
71
+ await new Promise((resolve, reject) => {
72
+ const handleError = (error) => reject(error);
73
+ server.once('error', handleError);
74
+ server.listen(port, '127.0.0.1', () => {
75
+ server.off('error', handleError);
76
+ resolve();
77
+ });
78
+ });
79
+ return port;
80
+ }
81
+ catch (error) {
82
+ if (error.code !== 'EADDRINUSE' || attempt === MAX_BIND_ATTEMPTS - 1)
83
+ throw error;
84
+ }
85
+ }
86
+ throw new Error('Could not start the login callback server');
87
+ }
88
+ /** The exchange code and state of a pasted redirect URL (`http://127.0.0.1:…/callback?code=…&state=…`), or a bare code. */
89
+ export function parsePastedCallback(text) {
90
+ const trimmed = text.trim();
91
+ try {
92
+ const url = new URL(trimmed);
93
+ return { code: url.searchParams.get('code') ?? undefined, state: url.searchParams.get('state') ?? undefined };
94
+ }
95
+ catch {
96
+ return trimmed ? { code: trimmed } : {};
97
+ }
98
+ }
99
+ async function exchange(dependencies, baseUrl, code) {
100
+ const exchangeResponse = await dependencies.fetch(`${baseUrl}/auth/exchange`, {
101
+ method: 'POST',
102
+ headers: { 'Content-Type': 'application/json' },
103
+ body: JSON.stringify({ code }),
104
+ });
105
+ const envelope = await parseEnvelope(exchangeResponse);
106
+ if (!exchangeResponse.ok || !envelope?.ok) {
107
+ if (exchangeResponse.status === 401)
108
+ throw new Error('Login expired, run `invd auth login` again');
109
+ throw new Error(envelope && !envelope.ok ? envelope.error : `Login exchange failed (${exchangeResponse.status})`);
110
+ }
111
+ await setApiKey(envelope.data.key);
112
+ return envelope.data;
113
+ }
114
+ /**
115
+ * Browser sign-in: a loopback callback server receives the exchange code. With `noBrowser` (SSH sessions) the URL
116
+ * is printed instead and the person pastes the address their browser was sent to (the page itself may not load —
117
+ * the code is in its URL); whichever arrives first wins.
118
+ */
119
+ export async function login(dependencies = defaultDependencies, opts = {}) {
120
+ const state = randomBytes(16).toString('hex');
121
+ let resolveCallback = () => undefined;
122
+ let rejectCallback = () => undefined;
123
+ const callback = new Promise((resolve, reject) => {
124
+ resolveCallback = resolve;
125
+ rejectCallback = reject;
126
+ });
127
+ let settled = false;
128
+ const settleError = (error) => {
129
+ if (settled)
130
+ return;
131
+ settled = true;
132
+ rejectCallback(error);
133
+ };
134
+ const settleSuccess = (data) => {
135
+ if (settled)
136
+ return;
137
+ settled = true;
138
+ resolveCallback(data);
139
+ };
140
+ const baseUrl = getBaseUrl().replace(/\/$/u, '');
141
+ const server = createServer(async (request, response) => {
142
+ const callbackUrl = new URL(request.url ?? '/', 'http://127.0.0.1');
143
+ if (request.method !== 'GET' || callbackUrl.pathname !== '/callback') {
144
+ response.writeHead(404).end();
145
+ return;
146
+ }
147
+ if (callbackUrl.searchParams.get('state') !== state) {
148
+ response.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });
149
+ response.end(callbackHtml('Login failed', 'State verification failed. Return to the terminal and try again.'));
150
+ settleError(new Error('Login state verification failed'));
151
+ return;
152
+ }
153
+ const code = callbackUrl.searchParams.get('code');
154
+ if (!code) {
155
+ response.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });
156
+ response.end(callbackHtml('Login failed', 'The callback did not include an exchange code.'));
157
+ settleError(new Error('Login callback did not include an exchange code'));
158
+ return;
159
+ }
160
+ try {
161
+ const data = await exchange(dependencies, baseUrl, code);
162
+ response.writeHead(200, { 'Cache-Control': 'no-store', 'Content-Type': 'text/html; charset=utf-8' });
163
+ response.end(callbackHtml('Login complete', 'You can close this tab and return to the terminal.'));
164
+ settleSuccess(data);
165
+ }
166
+ catch (error) {
167
+ response.writeHead(502, { 'Cache-Control': 'no-store', 'Content-Type': 'text/html; charset=utf-8' });
168
+ response.end(callbackHtml('Login failed', 'The credential exchange failed. Return to the terminal and try again.'));
169
+ settleError(error instanceof Error ? error : new Error(String(error)));
170
+ }
171
+ });
172
+ const port = await listenOnRandomPort(server);
173
+ const loginUrl = new URL(`${baseUrl}/auth/login`);
174
+ loginUrl.searchParams.set('port', String(port));
175
+ loginUrl.searchParams.set('state', state);
176
+ loginUrl.searchParams.set('hostname', hostname().slice(0, 64));
177
+ const handleInterrupt = () => settleError(new Error('Login cancelled'));
178
+ process.once('SIGINT', handleInterrupt);
179
+ const timeout = setTimeout(() => settleError(new Error('Login timed out. Run `invd auth login` again.')), dependencies.timeoutMs);
180
+ const pasteAbort = new AbortController();
181
+ try {
182
+ const preflight = await dependencies.fetch(loginUrl, { redirect: 'manual' });
183
+ if (preflight.status === 503) {
184
+ throw new Error('OAuth login is not enabled on this deployment. Use `invd auth login --with-token` instead.');
185
+ }
186
+ if (preflight.status < 300 || preflight.status >= 400) {
187
+ const envelope = await parseEnvelope(preflight);
188
+ throw new Error(envelope && !envelope.ok ? envelope.error : `Could not start login (${preflight.status})`);
189
+ }
190
+ if (opts.noBrowser) {
191
+ console.error('Open this URL in a browser on any machine and sign in:');
192
+ console.error(loginUrl.toString());
193
+ const read = dependencies.readPasted ?? readLine;
194
+ void read('Then paste the address the browser was sent to (it starts with http://127.0.0.1): ', pasteAbort.signal).then(async (text) => {
195
+ const pasted = parsePastedCallback(text);
196
+ if (pasted.state !== undefined && pasted.state !== state)
197
+ throw new Error('Login state verification failed');
198
+ if (!pasted.code)
199
+ throw new Error('The pasted text has no exchange code');
200
+ settleSuccess(await exchange(dependencies, baseUrl, pasted.code));
201
+ }).catch((error) => settleError(error instanceof Error ? error : new Error(String(error))));
202
+ }
203
+ else {
204
+ try {
205
+ await dependencies.openBrowser(loginUrl.toString());
206
+ console.error(chalk.dim('Opening your browser to complete login...'));
207
+ }
208
+ catch {
209
+ console.error(chalk.yellow('Could not open a browser automatically. Open this URL:'));
210
+ console.error(loginUrl.toString());
211
+ }
212
+ }
213
+ const data = await callback;
214
+ const approximateExpiry = new Date(Date.now() + KEY_LIFETIME_MS).toLocaleDateString();
215
+ console.log(chalk.green('Logged in successfully.'));
216
+ console.log(` Key hint: ${data.keyHint}`);
217
+ console.log(` Label: ${data.label}`);
218
+ console.log(` Expires: approximately ${approximateExpiry} (90 days)`);
219
+ console.log(chalk.dim(`This sign-in is also listed on your keys page: ${DASHBOARD_URL}/keys`));
220
+ return data;
221
+ }
222
+ finally {
223
+ clearTimeout(timeout);
224
+ pasteAbort.abort();
225
+ process.off('SIGINT', handleInterrupt);
226
+ await closeServer(server);
227
+ }
228
+ }
229
+ export async function logout(dependencies = defaultDependencies) {
230
+ let resolved;
231
+ try {
232
+ resolved = await resolveApiKey();
233
+ }
234
+ catch (error) {
235
+ if (error instanceof AuthRequiredError) {
236
+ console.log('Not logged in.');
237
+ return;
238
+ }
239
+ throw error;
240
+ }
241
+ const baseUrl = getBaseUrl().replace(/\/$/u, '');
242
+ try {
243
+ const response = await dependencies.fetch(`${baseUrl}/auth/revoke`, {
244
+ method: 'POST',
245
+ headers: { Authorization: `Bearer ${resolved.key}` },
246
+ });
247
+ if (!response.ok) {
248
+ const envelope = await parseEnvelope(response);
249
+ console.warn(chalk.yellow(`Warning: remote revocation failed: ${envelope && !envelope.ok ? envelope.error : response.status}`));
250
+ }
251
+ }
252
+ catch (error) {
253
+ console.warn(chalk.yellow(`Warning: remote revocation failed: ${errorMessage(error)}`));
254
+ }
255
+ if (resolved.source === 'environment') {
256
+ console.log(`The active key comes from ${resolved.origin}. Remove that environment variable to finish logging out.`);
257
+ return;
258
+ }
259
+ if (resolved.source === 'dotenv') {
260
+ console.log(`The active key comes from the current directory's ${resolved.origin}. Remove it from that file to finish logging out.`);
261
+ return;
262
+ }
263
+ await clearApiKey();
264
+ console.log(chalk.green('Logged out locally.'));
265
+ }
266
+ /** `invd auth status`: where the key comes from and, unless `offline`, what `GET /v2/me` says about it (free). */
267
+ export async function status(opts = {}) {
268
+ const resolved = await resolveApiKey();
269
+ const summary = {
270
+ host: getBaseUrl(),
271
+ key: keyHint(resolved.key),
272
+ source: resolved.source,
273
+ origin: resolved.origin,
274
+ };
275
+ if (!opts.offline) {
276
+ const { body } = await apiCall({ path: '/v2/me', silent: true });
277
+ const account = body?.account;
278
+ const plan = body?.plan;
279
+ if (typeof account === 'object' && account !== null) {
280
+ const fields = account;
281
+ summary.account = fields.email ?? fields.name ?? fields.id ?? account;
282
+ }
283
+ else {
284
+ summary.account = account;
285
+ }
286
+ summary.plan = typeof plan === 'object' && plan !== null ? plan.name ?? plan : plan;
287
+ }
288
+ if (opts.json) {
289
+ console.log(JSON.stringify(summary, null, 2));
290
+ return;
291
+ }
292
+ console.log(chalk.green('Logged in.'));
293
+ for (const [key, value] of Object.entries(summary)) {
294
+ console.log(` ${key.padEnd(8)} ${typeof value === 'object' ? JSON.stringify(value) : String(value)}`);
295
+ }
296
+ }
297
+ export function registerAuthCommands(program) {
298
+ const auth = program.command('auth').description('Sign in, inspect and remove the API key invd uses');
299
+ auth
300
+ .command('login')
301
+ .description('Sign in through your browser (the key belongs to your Invinite Data account)')
302
+ .option('--no-browser', 'Print the sign-in URL and paste the redirect address back (SSH sessions)')
303
+ .option('--with-token', 'Read an API key from stdin instead (e.g. invd auth login --with-token < key.txt)')
304
+ .addHelpText('before', 'Examples:\n $ invd auth login\n $ invd auth login --no-browser\n')
305
+ .action(withErrorHandling(async (opts) => {
306
+ if (opts.withToken) {
307
+ const key = (await readStdin()).trim();
308
+ if (!key)
309
+ throw new UsageError('--with-token: stdin held no key');
310
+ const where = await setApiKey(key);
311
+ console.log(chalk.green(`API key saved (${where === 'keychain' ? 'OS keychain' : 'config.toml'}): ${keyHint(key)}`));
312
+ return;
313
+ }
314
+ await login(defaultDependencies, { noBrowser: opts.browser === false });
315
+ }));
316
+ auth
317
+ .command('status')
318
+ .description('Show which key is active, where it comes from, and the account it belongs to (GET /v2/me, free)')
319
+ .option('--offline', 'Do not call the API')
320
+ .option('--json', 'Print JSON')
321
+ .addHelpText('before', 'Examples:\n $ invd auth status\n $ invd auth status --offline --json\n')
322
+ .action(withErrorHandling(async (opts) => status(opts)));
323
+ auth
324
+ .command('token')
325
+ .description('Print the active API key to stdout (for scripts: curl -H "Authorization: Bearer $(invd auth token)")')
326
+ .addHelpText('before', 'Examples:\n $ invd auth token\n $ export INVD_API_KEY="$(invd auth token)"\n')
327
+ .action(withErrorHandling(async () => {
328
+ process.stdout.write(`${(await resolveApiKey()).key}\n`);
329
+ }));
330
+ auth
331
+ .command('logout')
332
+ .description('Revoke the current login and clear the stored key')
333
+ .addHelpText('before', 'Examples:\n $ invd auth logout\n $ INVD_API_KEY= invd auth logout\n')
334
+ .action(withErrorHandling(async () => logout()));
335
+ }
336
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAe,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAuB,MAAM,mBAAmB,CAAC;AACxG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAC1C,MAAM,eAAe,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACjD,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAqB5B,KAAK,UAAU,QAAQ,CAAC,MAAc,EAAE,MAAmB;IACzD,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/C,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAED,MAAM,mBAAmB,GAAsB;IAC7C,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,WAAW;IACX,SAAS,EAAE,mBAAmB;IAC9B,UAAU,EAAE,QAAQ;CACrB,CAAC;AAEF,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,KAAK,UAAU,aAAa,CAAI,QAAkB;IAChD,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAoB,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IAC3E,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;IAC5F,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;AAC9C,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,GAAW;IACpC,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACtF,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;YACvB,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,KAAa,EAAE,OAAe;IAClD,OAAO,qEAAqE,KAAK,kCAAkC,KAAK,WAAW,OAAO,2BAA2B,CAAC;AACxK,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,MAAc;IACvC,IAAI,CAAC,MAAM,CAAC,SAAS;QAAE,OAAO;IAC9B,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AACtE,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,MAAc;IAC9C,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,iBAAiB,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,GAAG,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7E,IAAI,CAAC;YACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,MAAM,WAAW,GAAG,CAAC,KAAY,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACpD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;gBAClC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;oBACpC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;oBACjC,OAAO,EAAE,CAAC;gBACZ,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,YAAY,IAAI,OAAO,KAAK,iBAAiB,GAAG,CAAC;gBAAE,MAAM,KAAK,CAAC;QAC/G,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;AAC/D,CAAC;AAED,2HAA2H;AAC3H,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,SAAS,EAAE,KAAK,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,SAAS,EAAE,CAAC;IAChH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,YAA+B,EAAE,OAAe,EAAE,IAAY;IACpF,MAAM,gBAAgB,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,GAAG,OAAO,gBAAgB,EAAE;QAC5E,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;KAC/B,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAe,gBAAgB,CAAC,CAAC;IACrE,IAAI,CAAC,gBAAgB,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC;QAC1C,IAAI,gBAAgB,CAAC,MAAM,KAAK,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QACnG,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,0BAA0B,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC;IACpH,CAAC;IACD,MAAM,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnC,OAAO,QAAQ,CAAC,IAAI,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,eAAkC,mBAAmB,EACrD,OAAgC,EAAE;IAElC,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,IAAI,eAAe,GAAkC,GAAG,EAAE,CAAC,SAAS,CAAC;IACrE,IAAI,cAAc,GAA4B,GAAG,EAAE,CAAC,SAAS,CAAC;IAC9D,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC7D,eAAe,GAAG,OAAO,CAAC;QAC1B,cAAc,GAAG,MAAM,CAAC;IAC1B,CAAC,CAAC,CAAC;IACH,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,WAAW,GAAG,CAAC,KAAY,EAAQ,EAAE;QACzC,IAAI,OAAO;YAAE,OAAO;QACpB,OAAO,GAAG,IAAI,CAAC;QACf,cAAc,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC,CAAC;IACF,MAAM,aAAa,GAAG,CAAC,IAAkB,EAAQ,EAAE;QACjD,IAAI,OAAO;YAAE,OAAO;QACpB,OAAO,GAAG,IAAI,CAAC;QACf,eAAe,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;QACtD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC;QACpE,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,WAAW,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YACrE,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAC9B,OAAO;QACT,CAAC;QACD,IAAI,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,EAAE,CAAC;YACpD,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;YACxE,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,cAAc,EAAE,kEAAkE,CAAC,CAAC,CAAC;YAC/G,WAAW,CAAC,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;YACxE,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,cAAc,EAAE,gDAAgD,CAAC,CAAC,CAAC;YAC7F,WAAW,CAAC,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC,CAAC;YAC1E,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;YACzD,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;YACrG,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,gBAAgB,EAAE,oDAAoD,CAAC,CAAC,CAAC;YACnG,aAAa,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;YACrG,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,cAAc,EAAE,uEAAuE,CAAC,CAAC,CAAC;YACpH,WAAW,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACzE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,OAAO,aAAa,CAAC,CAAC;IAClD,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC1C,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAE/D,MAAM,eAAe,GAAG,GAAS,EAAE,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC9E,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IAClI,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC7E,IAAI,SAAS,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,4FAA4F,CAAC,CAAC;QAChH,CAAC;QACD,IAAI,SAAS,CAAC,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;YACtD,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAQ,SAAS,CAAC,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,0BAA0B,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QAC7G,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;YACxE,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;YACnC,MAAM,IAAI,GAAG,YAAY,CAAC,UAAU,IAAI,QAAQ,CAAC;YACjD,KAAK,IAAI,CAAC,oFAAoF,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;gBACrI,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;gBACzC,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK;oBAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;gBAC7G,IAAI,CAAC,MAAM,CAAC,IAAI;oBAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;gBAC1E,aAAa,CAAC,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YACpE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACvG,CAAC;aAAM,CAAC;YACN,IAAI,CAAC;gBACH,MAAM,YAAY,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACpD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC,CAAC;YACxE,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,wDAAwD,CAAC,CAAC,CAAC;gBACtF,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC;QAC5B,MAAM,iBAAiB,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,eAAe,CAAC,CAAC,kBAAkB,EAAE,CAAC;QACtF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,+BAA+B,iBAAiB,YAAY,CAAC,CAAC;QAC1E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kDAAkD,aAAa,OAAO,CAAC,CAAC,CAAC;QAC/F,OAAO,IAAI,CAAC;IACd,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,OAAO,CAAC,CAAC;QACtB,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;QACvC,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,eAAiD,mBAAmB;IAC/F,IAAI,QAAwB,CAAC;IAC7B,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,aAAa,EAAE,CAAC;IACnC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,iBAAiB,EAAE,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YAC9B,OAAO;QACT,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACjD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,GAAG,OAAO,cAAc,EAAE;YAClE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,QAAQ,CAAC,GAAG,EAAE,EAAE;SACrD,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAQ,QAAQ,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,sCAAsC,QAAQ,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAClI,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,sCAAsC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1F,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,aAAa,EAAE,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,6BAA6B,QAAQ,CAAC,MAAM,2DAA2D,CAAC,CAAC;QACrH,OAAO;IACT,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,qDAAqD,QAAQ,CAAC,MAAM,mDAAmD,CAAC,CAAC;QACrI,OAAO;IACT,CAAC;IAED,MAAM,WAAW,EAAE,CAAC;IACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,kHAAkH;AAClH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAA8C,EAAE;IAC3E,MAAM,QAAQ,GAAG,MAAM,aAAa,EAAE,CAAC;IACvC,MAAM,OAAO,GAA4B;QACvC,IAAI,EAAE,UAAU,EAAE;QAClB,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;QAC1B,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,MAAM,EAAE,QAAQ,CAAC,MAAM;KACxB,CAAC;IACF,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,CAA0B,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1F,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,CAAC;QACxB,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACpD,MAAM,MAAM,GAAG,OAAkC,CAAC;YAClD,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,EAAE,IAAI,OAAO,CAAC;QACxE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;QAC5B,CAAC;QACD,OAAO,CAAC,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAE,IAAgC,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACnH,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;IACvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC1G,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,mDAAmD,CAAC,CAAC;IAEtG,IAAI;SACD,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,8EAA8E,CAAC;SAC3F,MAAM,CAAC,cAAc,EAAE,0EAA0E,CAAC;SAClG,MAAM,CAAC,cAAc,EAAE,kFAAkF,CAAC;SAC1G,WAAW,CAAC,QAAQ,EAAE,oEAAoE,CAAC;SAC3F,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,IAAgD,EAAE,EAAE;QACnF,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,MAAM,GAAG,GAAG,CAAC,MAAM,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACvC,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,UAAU,CAAC,iCAAiC,CAAC,CAAC;YAClE,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,kBAAkB,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,MAAM,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YACrH,OAAO;QACT,CAAC;QACD,MAAM,KAAK,CAAC,mBAAmB,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC,CAAC;IAEN,IAAI;SACD,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,iGAAiG,CAAC;SAC9G,MAAM,CAAC,WAAW,EAAE,qBAAqB,CAAC;SAC1C,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC;SAC9B,WAAW,CAAC,QAAQ,EAAE,0EAA0E,CAAC;SACjG,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,IAA2C,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAElG,IAAI;SACD,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,sGAAsG,CAAC;SACnH,WAAW,CAAC,QAAQ,EAAE,gFAAgF,CAAC;SACvG,MAAM,CAAC,iBAAiB,CAAC,KAAK,IAAI,EAAE;QACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,aAAa,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC,CAAC;IAEN,IAAI;SACD,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,mDAAmD,CAAC;SAChE,WAAW,CAAC,QAAQ,EAAE,uEAAuE,CAAC;SAC9F,MAAM,CAAC,iBAAiB,CAAC,KAAK,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AACrD,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { Command } from 'commander';
2
+ /** Every command path of the tree (`''` = the root) with the words completed after it: subcommands and flags. */
3
+ export declare function completionTable(program: Command): Map<string, string[]>;
4
+ export declare const SHELLS: readonly ["bash", "zsh", "fish"];
5
+ export declare function completionScript(shell: string, program: Command, apiPaths: readonly string[]): string;
6
+ /** `invd completion bash|zsh|fish`: the script, generated from the live command tree and the spec's paths. */
7
+ export declare function registerCompletionCommand(program: Command, apiPaths: () => readonly string[]): void;
@@ -0,0 +1,115 @@
1
+ import { UsageError } from '../shared/errors.js';
2
+ /** Every command path of the tree (`''` = the root) with the words completed after it: subcommands and flags. */
3
+ export function completionTable(program) {
4
+ const table = new Map();
5
+ const walk = (command, path) => {
6
+ const words = [
7
+ ...command.commands.map(child => child.name()),
8
+ ...command.options.flatMap(option => [option.long, option.short].filter((flag) => Boolean(flag))),
9
+ '--help',
10
+ ];
11
+ table.set(path.join(' '), [...new Set(words)]);
12
+ for (const child of command.commands)
13
+ walk(child, [...path, child.name()]);
14
+ };
15
+ walk(program, []);
16
+ return table;
17
+ }
18
+ const shellQuote = (text) => `'${text.replace(/'/g, "'\\''")}'`;
19
+ function bashScript(table, apiPaths) {
20
+ const cases = [...table].map(([path, words]) => ` ${shellQuote(path)}) echo ${shellQuote(words.join(' '))} ;;`).join('\n');
21
+ return `# invd completion for bash (eval "$(invd completion bash)", or save it under bash-completion's completions dir)
22
+ __invd_words() {
23
+ case "$1" in
24
+ ${cases}
25
+ esac
26
+ }
27
+ __invd_api_paths=${shellQuote(apiPaths.join(' '))}
28
+ _invd() {
29
+ local cur="\${COMP_WORDS[COMP_CWORD]}" path="" w i words
30
+ for ((i = 1; i < COMP_CWORD; i++)); do
31
+ w="\${COMP_WORDS[i]}"
32
+ [[ $w == -* ]] && continue
33
+ words=" $(__invd_words "$path") "
34
+ [[ $words == *" $w "* ]] && path="\${path:+$path }$w"
35
+ done
36
+ if [[ $path == api && $cur != -* ]]; then
37
+ words="$__invd_api_paths GET POST PATCH DELETE"
38
+ else
39
+ words="$(__invd_words "$path")"
40
+ fi
41
+ COMPREPLY=($(compgen -W "$words" -- "$cur"))
42
+ }
43
+ complete -o default -F _invd invd
44
+ `;
45
+ }
46
+ function zshScript(table, apiPaths) {
47
+ return `#compdef invd
48
+ # invd completion for zsh (eval "$(invd completion zsh)" in ~/.zshrc)
49
+ autoload -U +X bashcompinit && bashcompinit
50
+ ${bashScript(table, apiPaths).split('\n').slice(1).join('\n')}`;
51
+ }
52
+ function fishScript(table, apiPaths) {
53
+ const cases = [...table].map(([path, words]) => ` case ${shellQuote(path)}\n printf '%s\\n' ${words.map(shellQuote).join(' ')}`).join('\n');
54
+ return `# invd completion for fish (invd completion fish > ~/.config/fish/completions/invd.fish)
55
+ function __invd_words
56
+ switch $argv[1]
57
+ ${cases}
58
+ end
59
+ end
60
+ function __invd_path
61
+ set -l tokens (commandline -opc)
62
+ set -e tokens[1]
63
+ set -l path ''
64
+ for t in $tokens
65
+ string match -q -- '-*' $t; and continue
66
+ if contains -- $t (__invd_words "$path")
67
+ set path (string trim -- "$path $t")
68
+ end
69
+ end
70
+ echo $path
71
+ end
72
+ function __invd_complete
73
+ set -l path (__invd_path)
74
+ if test "$path" = api
75
+ printf '%s\\n' ${apiPaths.map(shellQuote).join(' ')}
76
+ end
77
+ __invd_words "$path"
78
+ end
79
+ complete -c invd -f -a '(__invd_complete)'
80
+ `;
81
+ }
82
+ export const SHELLS = ['bash', 'zsh', 'fish'];
83
+ export function completionScript(shell, program, apiPaths) {
84
+ const table = completionTable(program);
85
+ if (shell === 'bash')
86
+ return bashScript(table, apiPaths);
87
+ if (shell === 'zsh')
88
+ return zshScript(table, apiPaths);
89
+ if (shell === 'fish')
90
+ return fishScript(table, apiPaths);
91
+ throw new UsageError(`Unknown shell ${shell}: ${SHELLS.join(', ')}`);
92
+ }
93
+ /** `invd completion bash|zsh|fish`: the script, generated from the live command tree and the spec's paths. */
94
+ export function registerCompletionCommand(program, apiPaths) {
95
+ program
96
+ .command('completion')
97
+ .description('Print the shell completion script (commands, flags, and the API paths after invd api)')
98
+ .argument('<shell>', SHELLS.join(' | '))
99
+ .addHelpText('before', [
100
+ 'Examples:',
101
+ ' $ eval "$(invd completion zsh)"',
102
+ ' $ invd completion fish > ~/.config/fish/completions/invd.fish',
103
+ '',
104
+ ].join('\n'))
105
+ .action((shell) => {
106
+ try {
107
+ process.stdout.write(completionScript(shell, program, apiPaths()));
108
+ }
109
+ catch (error) {
110
+ console.error(error instanceof Error ? error.message : String(error));
111
+ process.exit(2);
112
+ }
113
+ });
114
+ }
115
+ //# sourceMappingURL=completion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion.js","sourceRoot":"","sources":["../../../src/commands/completion.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,iHAAiH;AACjH,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC1C,MAAM,IAAI,GAAG,CAAC,OAAgB,EAAE,IAAc,EAAE,EAAE;QAChD,MAAM,KAAK,GAAG;YACZ,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAC9C,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YACjH,QAAQ;SACT,CAAC;QACF,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/C,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ;YAAE,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7E,CAAC,CAAC;IACF,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAClB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;AAExE,SAAS,UAAU,CAAC,KAA4B,EAAE,QAA2B;IAC3E,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,OAAO,UAAU,CAAC,IAAI,CAAC,UAAU,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9H,OAAO;;;EAGP,KAAK;;;mBAGY,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;;;;;;;;;;;;;;;;;CAiBhD,CAAC;AACF,CAAC;AAED,SAAS,SAAS,CAAC,KAA4B,EAAE,QAA2B;IAC1E,OAAO;;;EAGP,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAChE,CAAC;AAED,SAAS,UAAU,CAAC,KAA4B,EAAE,QAA2B;IAC3E,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,YAAY,UAAU,CAAC,IAAI,CAAC,0BAA0B,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpJ,OAAO;;;EAGP,KAAK;;;;;;;;;;;;;;;;;;qBAkBc,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;;;;;CAKtD,CAAC;AACF,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAU,CAAC;AAEvD,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,OAAgB,EAAE,QAA2B;IAC3F,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACvD,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACzD,MAAM,IAAI,UAAU,CAAC,iBAAiB,KAAK,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,8GAA8G;AAC9G,MAAM,UAAU,yBAAyB,CAAC,OAAgB,EAAE,QAAiC;IAC3F,OAAO;SACJ,OAAO,CAAC,YAAY,CAAC;SACrB,WAAW,CAAC,uFAAuF,CAAC;SACpG,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACvC,WAAW,CAAC,QAAQ,EAAE;QACrB,WAAW;QACX,mCAAmC;QACnC,iEAAiE;QACjE,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACZ,MAAM,CAAC,CAAC,KAAa,EAAE,EAAE;QACxB,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QACrE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1,2 +1,6 @@
1
1
  import { Command } from 'commander';
2
+ /**
3
+ * `invd config`: the settings in `$XDG_CONFIG_HOME/invd/config.toml` (`INVD_CONFIG_DIR` replaces the directory)
4
+ * and the project file `./.invd.toml` (`--local`). Precedence: flags > env > `./.invd.toml` > `config.toml`.
5
+ */
2
6
  export declare function registerConfigCommands(program: Command): void;
@@ -1,56 +1,93 @@
1
1
  import chalk from 'chalk';
2
- import { setApiKey } from '../config/auth.js';
3
- import { setBaseUrl, showConfig, resetConfig } from '../config/config-manager.js';
2
+ import { SETTINGS, getSetting, globalConfigPath, isSettingKey, localConfigPath, setSetting, unsetSetting, } from '../config/config-manager.js';
3
+ import { OUTPUT_FORMATS } from '../output/render.js';
4
+ import { UsageError, withErrorHandling } from '../shared/errors.js';
5
+ function settingKey(key) {
6
+ if (!isSettingKey(key))
7
+ throw new UsageError(`Unknown setting ${key}. Settings: ${Object.keys(SETTINGS).join(', ')}`);
8
+ return key;
9
+ }
10
+ function checkValue(key, value) {
11
+ if (key === 'output' && value !== '' && !OUTPUT_FORMATS.includes(value)) {
12
+ throw new UsageError(`output must be one of ${OUTPUT_FORMATS.join(', ')}`);
13
+ }
14
+ if (key === 'confirm_credits' && !/^\d+$/.test(value))
15
+ throw new UsageError('confirm_credits must be a whole number');
16
+ if (key === 'base_url') {
17
+ try {
18
+ new URL(value);
19
+ }
20
+ catch {
21
+ throw new UsageError(`base_url must be a URL (got ${value})`);
22
+ }
23
+ }
24
+ }
25
+ const shown = (key, value) => (key === 'api_key' && value ? `${value.slice(0, 4)}…` : value);
26
+ /**
27
+ * `invd config`: the settings in `$XDG_CONFIG_HOME/invd/config.toml` (`INVD_CONFIG_DIR` replaces the directory)
28
+ * and the project file `./.invd.toml` (`--local`). Precedence: flags > env > `./.invd.toml` > `config.toml`.
29
+ */
4
30
  export function registerConfigCommands(program) {
5
- const configCmd = program
31
+ const config = program
6
32
  .command('config')
7
- .description('Manage CLI configuration');
8
- configCmd
9
- .command('set-key')
10
- .description('Set API key (interactive, masked input)')
11
- .action(async () => {
12
- const { default: Enquirer } = await import('enquirer');
13
- const enquirer = new Enquirer();
14
- const response = await enquirer.prompt({
15
- type: 'password',
16
- name: 'key',
17
- message: 'Enter your Invinite API key:',
33
+ .description('Local settings: config.toml (XDG) and ./.invd.toml; flags > env > local > global');
34
+ config
35
+ .command('list')
36
+ .description('Every setting with its value and where it comes from')
37
+ .option('--json', 'Print JSON')
38
+ .addHelpText('before', 'Examples:\n $ invd config list\n $ invd config list --json\n')
39
+ .action(withErrorHandling(async (opts) => {
40
+ const rows = Object.keys(SETTINGS).map(key => {
41
+ const { value, source } = getSetting(key);
42
+ return { key, value: shown(key, value), source, env: SETTINGS[key].env };
18
43
  });
19
- await setApiKey(response.key);
20
- console.log(chalk.green('API key saved successfully.'));
21
- });
22
- configCmd
23
- .command('set-url')
24
- .description('Set API base URL')
25
- .argument('<url>', 'Base URL for the API')
26
- .action((url) => {
27
- setBaseUrl(url);
28
- console.log(chalk.green(`Base URL set to ${url}`));
29
- });
30
- configCmd
31
- .command('show')
32
- .description('Display current configuration')
33
- .action(() => {
34
- const cfg = showConfig();
35
- console.log(chalk.bold('Current Configuration:'));
36
- console.log(` Base URL: ${cfg.baseUrl}`);
37
- console.log(` API Key: ${cfg.apiKeySet ? chalk.green('configured') : chalk.yellow('not set')}`);
38
- });
39
- configCmd
40
- .command('reset')
41
- .description('Reset all configuration')
42
- .action(async () => {
43
- const { default: Enquirer } = await import('enquirer');
44
- const enquirer = new Enquirer();
45
- const response = await enquirer.prompt({
46
- type: 'confirm',
47
- name: 'confirm',
48
- message: 'Are you sure you want to reset all configuration?',
49
- });
50
- if (response.confirm) {
51
- resetConfig();
52
- console.log(chalk.green('Configuration reset.'));
44
+ if (opts.json) {
45
+ console.log(JSON.stringify({ global: globalConfigPath(), local: localConfigPath(), settings: rows }, null, 2));
46
+ return;
53
47
  }
48
+ for (const row of rows) {
49
+ console.log(` ${chalk.bold(row.key.padEnd(16))} ${row.value === '' ? chalk.dim('(unset)') : row.value} ${chalk.dim(`${row.source} · $${row.env}`)}`);
50
+ }
51
+ console.log(chalk.dim(`\nglobal: ${globalConfigPath()}\nlocal: ${localConfigPath()}`));
52
+ }));
53
+ config
54
+ .command('get')
55
+ .description('Print one setting\'s effective value')
56
+ .argument('<key>', `One of ${Object.keys(SETTINGS).join(', ')}`)
57
+ .addHelpText('before', 'Examples:\n $ invd config get base_url\n $ invd config get output\n')
58
+ .action(withErrorHandling(async (key) => {
59
+ const name = settingKey(key);
60
+ console.log(shown(name, getSetting(name).value));
61
+ }));
62
+ config
63
+ .command('set')
64
+ .description('Write a setting to config.toml (or ./.invd.toml with --local)')
65
+ .argument('<key>', `One of ${Object.keys(SETTINGS).join(', ')}`)
66
+ .argument('<value>', 'The value')
67
+ .option('--local', 'Write ./.invd.toml (this project) instead of the global file')
68
+ .addHelpText('before', 'Examples:\n $ invd config set output json\n $ invd config set base_url http://localhost:4000 --local\n')
69
+ .action(withErrorHandling(async (key, value, opts) => {
70
+ const name = settingKey(key);
71
+ checkValue(name, value);
72
+ const path = setSetting(name, value, opts.local ? 'local' : 'global');
73
+ console.log(chalk.green(`${name} = ${shown(name, value)}`) + chalk.dim(` (${path})`));
74
+ }));
75
+ config
76
+ .command('unset')
77
+ .description('Remove a setting from config.toml (or ./.invd.toml with --local)')
78
+ .argument('<key>', `One of ${Object.keys(SETTINGS).join(', ')}`)
79
+ .option('--local', 'Edit ./.invd.toml instead of the global file')
80
+ .addHelpText('before', 'Examples:\n $ invd config unset output\n $ invd config unset base_url --local\n')
81
+ .action(withErrorHandling(async (key, opts) => {
82
+ const path = unsetSetting(settingKey(key), opts.local ? 'local' : 'global');
83
+ console.log(chalk.green(`${key} unset`) + chalk.dim(` (${path})`));
84
+ }));
85
+ config
86
+ .command('path')
87
+ .description('Print the global config file path')
88
+ .addHelpText('before', 'Examples:\n $ invd config path\n $ cat "$(invd config path)"\n')
89
+ .action(() => {
90
+ console.log(globalConfigPath());
54
91
  });
55
92
  }
56
93
  //# sourceMappingURL=config.js.map