@tutorflow/cli 0.1.2 → 0.3.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 (52) hide show
  1. package/README.md +400 -89
  2. package/dist/client.d.ts +7 -1
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +53 -19
  5. package/dist/client.js.map +1 -1
  6. package/dist/commands/agent.d.ts +3 -0
  7. package/dist/commands/agent.d.ts.map +1 -0
  8. package/dist/commands/agent.js +123 -0
  9. package/dist/commands/agent.js.map +1 -0
  10. package/dist/commands/auth.d.ts.map +1 -1
  11. package/dist/commands/auth.js +48 -45
  12. package/dist/commands/auth.js.map +1 -1
  13. package/dist/commands/config.d.ts.map +1 -1
  14. package/dist/commands/config.js +34 -45
  15. package/dist/commands/config.js.map +1 -1
  16. package/dist/commands/course.d.ts.map +1 -1
  17. package/dist/commands/course.js +61 -75
  18. package/dist/commands/course.js.map +1 -1
  19. package/dist/commands/evaluate.d.ts.map +1 -1
  20. package/dist/commands/evaluate.js +49 -55
  21. package/dist/commands/evaluate.js.map +1 -1
  22. package/dist/commands/module.d.ts +3 -0
  23. package/dist/commands/module.d.ts.map +1 -0
  24. package/dist/commands/module.js +108 -0
  25. package/dist/commands/module.js.map +1 -0
  26. package/dist/commands/platform.d.ts +3 -0
  27. package/dist/commands/platform.d.ts.map +1 -0
  28. package/dist/commands/platform.js +36 -0
  29. package/dist/commands/platform.js.map +1 -0
  30. package/dist/commands/slide.d.ts.map +1 -1
  31. package/dist/commands/slide.js +65 -76
  32. package/dist/commands/slide.js.map +1 -1
  33. package/dist/commands/test.d.ts +3 -0
  34. package/dist/commands/test.d.ts.map +1 -0
  35. package/dist/commands/test.js +119 -0
  36. package/dist/commands/test.js.map +1 -0
  37. package/dist/commands/video.d.ts.map +1 -1
  38. package/dist/commands/video.js +66 -78
  39. package/dist/commands/video.js.map +1 -1
  40. package/dist/index.js +24 -2
  41. package/dist/index.js.map +1 -1
  42. package/dist/types.d.ts +75 -0
  43. package/dist/types.d.ts.map +1 -1
  44. package/dist/utils/output.d.ts +15 -2
  45. package/dist/utils/output.d.ts.map +1 -1
  46. package/dist/utils/output.js +66 -22
  47. package/dist/utils/output.js.map +1 -1
  48. package/dist/utils/runtime.d.ts +39 -0
  49. package/dist/utils/runtime.d.ts.map +1 -0
  50. package/dist/utils/runtime.js +105 -0
  51. package/dist/utils/runtime.js.map +1 -0
  52. package/package.json +18 -2
package/dist/client.js CHANGED
@@ -3,37 +3,71 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ApiClient = void 0;
4
4
  const undici_1 = require("undici");
5
5
  const config_1 = require("./config");
6
+ const runtime_1 = require("./utils/runtime");
7
+ const DEFAULT_BASE_URL = 'https://api.tutorflow.io';
8
+ /**
9
+ * Resolution order (env wins so CI/agents can override config without
10
+ * touching ~/.tutorflow/config.json):
11
+ *
12
+ * 1. TUTORFLOW_API_KEY / TUTORFLOW_BASE_URL env vars
13
+ * 2. ~/.tutorflow/config.json
14
+ * 3. baseUrl default
15
+ */
16
+ async function resolveConfig() {
17
+ const fileConfig = await (0, config_1.readConfig)();
18
+ return {
19
+ apiKey: process.env.TUTORFLOW_API_KEY ?? fileConfig.apiKey ?? '',
20
+ baseUrl: process.env.TUTORFLOW_BASE_URL ?? fileConfig.baseUrl ?? DEFAULT_BASE_URL,
21
+ };
22
+ }
6
23
  class ApiClient {
7
24
  constructor(config) {
8
- this.config = config || {
9
- apiKey: '',
10
- baseUrl: 'https://api.tutorflow.io',
11
- };
25
+ this.config = config || { apiKey: '', baseUrl: DEFAULT_BASE_URL };
12
26
  }
13
27
  static async create() {
14
- const config = await (0, config_1.readConfig)();
15
- return new ApiClient({
16
- apiKey: config.apiKey || '',
17
- baseUrl: config.baseUrl || 'https://api.tutorflow.io',
18
- });
28
+ return new ApiClient(await resolveConfig());
29
+ }
30
+ /**
31
+ * Like `create` but throws CliError if no API key is resolvable. Use this
32
+ * in any command that talks to the API so we get a single, consistent
33
+ * "not authenticated" path.
34
+ */
35
+ static async createAuthenticated() {
36
+ const config = await resolveConfig();
37
+ if (!config.apiKey) {
38
+ throw new runtime_1.CliError('Not authenticated. Run "tutorflow auth login --api-key <key>" or set TUTORFLOW_API_KEY.', { code: 'EAUTH', exitCode: 1 });
39
+ }
40
+ return new ApiClient(config);
19
41
  }
20
- async request(method, endpoint, body) {
42
+ async request(method, endpoint, body, headers) {
21
43
  const url = `${this.config.baseUrl}${endpoint}`;
22
- const headers = {
23
- 'Content-Type': 'application/json',
24
- 'X-API-Key': this.config.apiKey,
25
- };
26
44
  const init = {
27
45
  method,
28
- headers,
46
+ headers: {
47
+ 'Content-Type': 'application/json',
48
+ 'X-API-Key': this.config.apiKey,
49
+ ...headers,
50
+ },
29
51
  };
30
- if (body) {
52
+ if (body)
31
53
  init.body = JSON.stringify(body);
54
+ let response;
55
+ try {
56
+ response = await (0, undici_1.fetch)(url, init);
57
+ }
58
+ catch (err) {
59
+ throw new runtime_1.CliError(`Network error reaching ${url}: ${err instanceof Error ? err.message : String(err)}`, { code: 'ENETWORK' });
60
+ }
61
+ const text = await response.text();
62
+ let data = text;
63
+ try {
64
+ data = text.length ? JSON.parse(text) : {};
65
+ }
66
+ catch {
67
+ // non-JSON response; keep as text
32
68
  }
33
- const response = await (0, undici_1.fetch)(url, init);
34
- const data = await response.json();
35
69
  if (!response.ok) {
36
- throw new Error(`API Error: ${response.status} ${JSON.stringify(data)}`);
70
+ throw new runtime_1.CliError(`API error ${response.status}: ${typeof data === 'string' ? data : JSON.stringify(data)}`, { code: `EHTTP_${response.status}` });
37
71
  }
38
72
  return data;
39
73
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AAAA,mCAAyC;AACzC,qCAAsC;AAOtC,MAAa,SAAS;IAGpB,YAAY,MAAsB;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI;YACtB,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,0BAA0B;SACpC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM;QACjB,MAAM,MAAM,GAAG,MAAM,IAAA,mBAAU,GAAE,CAAC;QAClC,OAAO,IAAI,SAAS,CAAC;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;YAC3B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,0BAA0B;SACtD,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO,CACX,MAAc,EACd,QAAgB,EAChB,IAA8B;QAE9B,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,QAAQ,EAAE,CAAC;QAChD,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;YAClC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;SAChC,CAAC;QAEF,MAAM,IAAI,GAAuE;YAC/E,MAAM;YACN,OAAO;SACR,CAAC;QAEF,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAA,cAAM,EAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEnC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,cAAc,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3E,CAAC;QAED,OAAO,IAAS,CAAC;IACnB,CAAC;IAED,SAAS,CAAC,MAAc;QACtB,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;IAC9B,CAAC;IAED,UAAU,CAAC,OAAe;QACxB,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;IAChC,CAAC;CACF;AAvDD,8BAuDC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function agentCommand(): Command;
3
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/commands/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuBpC,wBAAgB,YAAY,IAAI,OAAO,CAiKtC"}
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.agentCommand = agentCommand;
4
+ const commander_1 = require("commander");
5
+ const prompts_1 = require("@clack/prompts");
6
+ const client_1 = require("../client");
7
+ const config_1 = require("../config");
8
+ const output_1 = require("../utils/output");
9
+ const runtime_1 = require("../utils/runtime");
10
+ const DEFAULT_BASE_URL = 'https://api.tutorflow.io';
11
+ function agentCommand() {
12
+ const agent = new commander_1.Command('agent').description('Manage TutorFlow agent platform account');
13
+ agent
14
+ .command('register')
15
+ .description('Self-register a TutorFlow Platform workspace and receive an API key')
16
+ .option('--name <name>', 'Workspace display name')
17
+ .option('--slug <slug>', 'Unique workspace slug')
18
+ .option('--email <email>', 'Contact email for the workspace')
19
+ .option('--agent-identity <identity>', 'Optional agent identity string')
20
+ .option('--no-save', 'Do not save the returned API key to ~/.tutorflow/config.json')
21
+ .action((0, runtime_1.command)(async (options) => {
22
+ const name = await requiredOptionOrPrompt(options.name, 'Workspace display name:', '--name <name>');
23
+ const slug = await requiredOptionOrPrompt(options.slug, 'Workspace slug:', '--slug <slug>');
24
+ const baseUrl = await resolveBaseUrl();
25
+ const client = await client_1.ApiClient.create();
26
+ const body = {
27
+ name,
28
+ slug,
29
+ email: options.email,
30
+ agentIdentity: options.agentIdentity,
31
+ };
32
+ Object.keys(body).forEach((key) => {
33
+ if (body[key] === undefined || body[key] === '')
34
+ delete body[key];
35
+ });
36
+ const response = await client.request('POST', '/v1/platform/agent/register', body);
37
+ if (options.save !== false) {
38
+ await (0, config_1.updateConfig)({ apiKey: response.apiKey, baseUrl });
39
+ }
40
+ (0, output_1.printResult)(response);
41
+ }));
42
+ agent
43
+ .command('account')
44
+ .description('Show the authenticated agent account')
45
+ .action((0, runtime_1.command)(async () => {
46
+ const client = await client_1.ApiClient.createAuthenticated();
47
+ const response = await client.request('GET', '/v1/platform/agent/account');
48
+ (0, output_1.printResult)(response);
49
+ }));
50
+ const billing = new commander_1.Command('billing').description('Manage agent billing');
51
+ billing
52
+ .command('status')
53
+ .description('Show billing status and currently restricted actions')
54
+ .action((0, runtime_1.command)(async () => {
55
+ const client = await client_1.ApiClient.createAuthenticated();
56
+ const response = await client.request('GET', '/v1/platform/agent/billing/status');
57
+ (0, output_1.printResult)(response);
58
+ }));
59
+ billing
60
+ .command('session')
61
+ .description('Create a TutorFlow-hosted checkout session URL')
62
+ .action((0, runtime_1.command)(async () => {
63
+ const client = await client_1.ApiClient.createAuthenticated();
64
+ const response = await client.request('POST', '/v1/platform/agent/billing/session');
65
+ (0, output_1.printResult)(response);
66
+ }));
67
+ agent.addCommand(billing);
68
+ const checkout = new commander_1.Command('checkout').description('Use public checkout token endpoints');
69
+ checkout
70
+ .command('info')
71
+ .description('Read workspace info for a TutorFlow checkout token')
72
+ .requiredOption('--token <token>', 'Checkout token from agent billing session URL')
73
+ .action((0, runtime_1.command)(async (options) => {
74
+ const client = await client_1.ApiClient.create();
75
+ const qs = new URLSearchParams({ token: options.token });
76
+ const response = await client.request('GET', `/v1/platform/agent/checkout?${qs.toString()}`);
77
+ (0, output_1.printResult)(response);
78
+ }));
79
+ checkout
80
+ .command('create')
81
+ .description('Create a Stripe Checkout URL from a TutorFlow checkout token')
82
+ .requiredOption('--token <token>', 'Checkout token from agent billing session URL')
83
+ .requiredOption('--amount-usd <amount>', 'Top-up amount in USD')
84
+ .action((0, runtime_1.command)(async (options) => {
85
+ const amountUsd = Number.parseFloat(options.amountUsd);
86
+ if (!Number.isFinite(amountUsd)) {
87
+ throw new runtime_1.CliError('--amount-usd must be a number', {
88
+ code: 'EINVAL',
89
+ exitCode: 2,
90
+ });
91
+ }
92
+ const client = await client_1.ApiClient.create();
93
+ const response = await client.request('POST', '/v1/platform/agent/checkout', { token: options.token, amountUsd });
94
+ (0, output_1.printResult)(response);
95
+ }));
96
+ agent.addCommand(checkout);
97
+ const verifyEmail = new commander_1.Command('verify-email').description('Manage agent email verification');
98
+ verifyEmail
99
+ .command('resend')
100
+ .description('Resend the platform email verification message')
101
+ .action((0, runtime_1.command)(async () => {
102
+ const client = await client_1.ApiClient.createAuthenticated();
103
+ const response = await client.request('POST', '/v1/platform/agent/verify-email/resend');
104
+ (0, output_1.printResult)(response);
105
+ }));
106
+ agent.addCommand(verifyEmail);
107
+ return agent;
108
+ }
109
+ async function requiredOptionOrPrompt(value, message, flagHint) {
110
+ if (value?.trim())
111
+ return value.trim();
112
+ (0, runtime_1.requireInteractive)(`Pass ${flagHint}.`);
113
+ const result = await (0, prompts_1.text)({ message });
114
+ if (!result || typeof result === 'symbol') {
115
+ throw new runtime_1.CliError('Cancelled', { code: 'ECANCELLED', exitCode: 130 });
116
+ }
117
+ return result;
118
+ }
119
+ async function resolveBaseUrl() {
120
+ const fileConfig = await (0, config_1.readConfig)();
121
+ return process.env.TUTORFLOW_BASE_URL ?? fileConfig.baseUrl ?? DEFAULT_BASE_URL;
122
+ }
123
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/commands/agent.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,WAAW,IAAI,OAAO,CAoErC"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,WAAW,IAAI,OAAO,CAiFrC"}
@@ -1,72 +1,75 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.authCommand = authCommand;
7
4
  const commander_1 = require("commander");
8
5
  const prompts_1 = require("@clack/prompts");
9
- const chalk_1 = __importDefault(require("chalk"));
10
6
  const config_1 = require("../config");
7
+ const runtime_1 = require("../utils/runtime");
8
+ const output_1 = require("../utils/output");
11
9
  function authCommand() {
12
10
  const auth = new commander_1.Command('auth').description('Manage authentication');
13
11
  auth
14
12
  .command('login')
15
13
  .description('Authenticate with your API key')
16
- .action(async () => {
17
- try {
18
- const apiKey = await (0, prompts_1.password)({
19
- message: 'Enter your TutorFlow API key:',
20
- });
21
- if (typeof apiKey === 'symbol') {
22
- console.log(chalk_1.default.red('Authentication cancelled'));
23
- return;
14
+ .option('--api-key <key>', 'API key (overrides interactive prompt; also reads TUTORFLOW_API_KEY)')
15
+ .action((0, runtime_1.command)(async (options) => {
16
+ let apiKey = options.apiKey ?? process.env.TUTORFLOW_API_KEY;
17
+ if (!apiKey) {
18
+ (0, runtime_1.requireInteractive)('Pass --api-key <key> or set TUTORFLOW_API_KEY.');
19
+ const result = await (0, prompts_1.password)({ message: 'Enter your TutorFlow API key:' });
20
+ if (typeof result === 'symbol') {
21
+ throw new runtime_1.CliError('Authentication cancelled', { code: 'ECANCELLED', exitCode: 130 });
24
22
  }
25
- await (0, config_1.updateConfig)({ apiKey });
26
- console.log(chalk_1.default.green('✓ Authentication successful!'));
27
- console.log(chalk_1.default.gray(`API key saved to ~/.tutorflow/config.json`));
23
+ apiKey = result;
28
24
  }
29
- catch (error) {
30
- console.error(chalk_1.default.red('✗ Authentication failed'), error);
25
+ if (!apiKey || !apiKey.trim()) {
26
+ throw new runtime_1.CliError('API key is empty', { code: 'EINVAL', exitCode: 2 });
31
27
  }
32
- });
28
+ await (0, config_1.updateConfig)({ apiKey });
29
+ (0, output_1.printStatus)('Authentication successful', 'success');
30
+ (0, output_1.printResult)({ ok: true, apiKeyPreview: `${apiKey.slice(0, 10)}...` });
31
+ }));
33
32
  auth
34
33
  .command('logout')
35
34
  .description('Remove stored credentials')
36
- .action(async () => {
37
- try {
38
- const confirmed = await (0, prompts_1.confirm)({
39
- message: 'Remove stored credentials?',
40
- });
41
- if (!confirmed) {
42
- console.log(chalk_1.default.gray('Cancelled'));
35
+ .option('-f, --force', 'Skip confirmation prompt')
36
+ .action((0, runtime_1.command)(async (options) => {
37
+ if (!options.force) {
38
+ // In non-interactive mode require --force so we never block silently.
39
+ if (!process.stdin.isTTY) {
40
+ throw new runtime_1.CliError('Pass --force to logout in non-interactive mode.', {
41
+ code: 'ENOINTERACTIVE',
42
+ exitCode: 2,
43
+ });
44
+ }
45
+ const confirmed = await (0, prompts_1.confirm)({ message: 'Remove stored credentials?' });
46
+ if (!confirmed || typeof confirmed === 'symbol') {
47
+ (0, output_1.printStatus)('Cancelled');
43
48
  return;
44
49
  }
45
- await (0, config_1.deleteConfig)();
46
- console.log(chalk_1.default.green('✓ Credentials removed'));
47
- }
48
- catch (error) {
49
- console.error(chalk_1.default.red('✗ Failed to logout'), error);
50
50
  }
51
- });
51
+ await (0, config_1.deleteConfig)();
52
+ (0, output_1.printStatus)('Credentials removed', 'success');
53
+ if ((0, runtime_1.isJsonMode)())
54
+ (0, output_1.printResult)({ ok: true });
55
+ }));
52
56
  auth
53
57
  .command('whoami')
54
58
  .description('Show current authenticated workspace')
55
- .action(async () => {
56
- try {
57
- const config = await (0, config_1.readConfig)();
58
- if (!config.apiKey) {
59
- console.log(chalk_1.default.yellow('Not authenticated'));
60
- return;
61
- }
62
- console.log(chalk_1.default.green('✓ Authenticated as:'));
63
- console.log(chalk_1.default.gray(` API Key: ${config.apiKey.slice(0, 10)}...`));
64
- console.log(chalk_1.default.gray(` Base URL: ${config.baseUrl || 'https://api.tutorflow.io'}`));
65
- }
66
- catch (error) {
67
- console.error(chalk_1.default.red('✗ Error:'), error);
59
+ .action((0, runtime_1.command)(async () => {
60
+ const fileConfig = await (0, config_1.readConfig)();
61
+ const apiKey = process.env.TUTORFLOW_API_KEY ?? fileConfig.apiKey;
62
+ const baseUrl = process.env.TUTORFLOW_BASE_URL ?? fileConfig.baseUrl ?? 'https://api.tutorflow.io';
63
+ if (!apiKey) {
64
+ throw new runtime_1.CliError('Not authenticated', { code: 'EAUTH', exitCode: 1 });
68
65
  }
69
- });
66
+ (0, output_1.printResult)({
67
+ authenticated: true,
68
+ apiKeyPreview: `${apiKey.slice(0, 10)}...`,
69
+ baseUrl,
70
+ source: process.env.TUTORFLOW_API_KEY ? 'env' : 'config',
71
+ });
72
+ }));
70
73
  return auth;
71
74
  }
72
75
  //# sourceMappingURL=auth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,aAAa,IAAI,OAAO,CAuDvC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,aAAa,IAAI,OAAO,CA4CvC"}
@@ -1,65 +1,54 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.configCommand = configCommand;
7
4
  const commander_1 = require("commander");
8
- const chalk_1 = __importDefault(require("chalk"));
9
5
  const config_1 = require("../config");
6
+ const output_1 = require("../utils/output");
7
+ const runtime_1 = require("../utils/runtime");
8
+ const VALID_KEYS = ['apiKey', 'baseUrl', 'workspace'];
10
9
  function configCommand() {
11
10
  const config = new commander_1.Command('config').description('Manage CLI configuration');
12
11
  config
13
12
  .command('set <key> <value>')
14
13
  .description('Set a configuration value')
15
- .action(async (key, value) => {
16
- try {
17
- const validKeys = ['apiKey', 'baseUrl', 'workspace'];
18
- if (!validKeys.includes(key)) {
19
- console.log(chalk_1.default.red(`✗ Unknown config key: ${key}`));
20
- console.log(chalk_1.default.gray(`Valid keys: ${validKeys.join(', ')}`));
21
- return;
22
- }
23
- const updatePayload = {};
24
- updatePayload[key] = value;
25
- await (0, config_1.updateConfig)(updatePayload);
26
- console.log(chalk_1.default.green(`✓ Config updated: ${key}`));
27
- }
28
- catch (error) {
29
- console.error(chalk_1.default.red('✗ Failed to update config'), error);
14
+ .action((0, runtime_1.command)(async (key, value) => {
15
+ if (!VALID_KEYS.includes(key)) {
16
+ throw new runtime_1.CliError(`Unknown config key "${key}". Valid keys: ${VALID_KEYS.join(', ')}`, { code: 'EINVAL', exitCode: 2 });
30
17
  }
31
- });
18
+ const updated = await (0, config_1.updateConfig)({ [key]: value });
19
+ (0, output_1.printResult)({ key, value: maskIfSecret(key, value), config: maskConfig(updated) });
20
+ }));
32
21
  config
33
22
  .command('get [key]')
34
- .description('Get a configuration value')
35
- .action(async (key) => {
36
- try {
37
- const cfg = await (0, config_1.readConfig)();
38
- if (key) {
39
- const value = cfg[key];
40
- if (value === undefined) {
41
- console.log(chalk_1.default.gray(`Config key not set: ${key}`));
42
- }
43
- else {
44
- console.log(`${key}=${value}`);
45
- }
23
+ .description('Get a configuration value (or all if no key)')
24
+ .action((0, runtime_1.command)(async (key) => {
25
+ const cfg = await (0, config_1.readConfig)();
26
+ if (key) {
27
+ if (!VALID_KEYS.includes(key)) {
28
+ throw new runtime_1.CliError(`Unknown config key "${key}". Valid keys: ${VALID_KEYS.join(', ')}`, { code: 'EINVAL', exitCode: 2 });
46
29
  }
47
- else {
48
- console.log(chalk_1.default.green('Current configuration:'));
49
- Object.entries(cfg).forEach(([k, v]) => {
50
- if (k === 'apiKey' && v) {
51
- console.log(chalk_1.default.gray(` ${k}: ${v.slice(0, 10)}...`));
52
- }
53
- else {
54
- console.log(chalk_1.default.gray(` ${k}: ${v}`));
55
- }
56
- });
30
+ const value = cfg[key];
31
+ if (value === undefined) {
32
+ throw new runtime_1.CliError(`Config key not set: ${key}`, { code: 'ENOTFOUND', exitCode: 1 });
57
33
  }
34
+ (0, output_1.printResult)({ [key]: maskIfSecret(key, value) });
58
35
  }
59
- catch (error) {
60
- console.error(chalk_1.default.red('✗ Failed to read config'), error);
36
+ else {
37
+ (0, output_1.printResult)(maskConfig(cfg));
61
38
  }
62
- });
39
+ }));
63
40
  return config;
64
41
  }
42
+ function maskIfSecret(key, value) {
43
+ if (key === 'apiKey' && value.length > 10)
44
+ return `${value.slice(0, 10)}...`;
45
+ return value;
46
+ }
47
+ function maskConfig(cfg) {
48
+ return {
49
+ apiKey: cfg.apiKey ? maskIfSecret('apiKey', cfg.apiKey) : undefined,
50
+ baseUrl: cfg.baseUrl,
51
+ workspace: cfg.workspace,
52
+ };
53
+ }
65
54
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":";;AAOA,sCA4CC;AAnDD,yCAAoC;AACpC,sCAA8D;AAC9D,4CAA8C;AAC9C,8CAAqD;AAErD,MAAM,UAAU,GAAsB,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AAEzE,SAAgB,aAAa;IAC3B,MAAM,MAAM,GAAG,IAAI,mBAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,0BAA0B,CAAC,CAAC;IAE7E,MAAM;SACH,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,2BAA2B,CAAC;SACxC,MAAM,CACL,IAAA,iBAAO,EAAC,KAAK,EAAE,GAAW,EAAE,KAAa,EAAE,EAAE;QAC3C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAoB,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,kBAAQ,CAChB,uBAAuB,GAAG,kBAAkB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EACnE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,CAChC,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,IAAA,qBAAY,EAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACrD,IAAA,oBAAW,EAAC,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACrF,CAAC,CAAC,CACH,CAAC;IAEJ,MAAM;SACH,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,8CAA8C,CAAC;SAC3D,MAAM,CACL,IAAA,iBAAO,EAAC,KAAK,EAAE,GAAY,EAAE,EAAE;QAC7B,MAAM,GAAG,GAAG,MAAM,IAAA,mBAAU,GAAE,CAAC;QAC/B,IAAI,GAAG,EAAE,CAAC;YACR,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAoB,CAAC,EAAE,CAAC;gBAC/C,MAAM,IAAI,kBAAQ,CAChB,uBAAuB,GAAG,kBAAkB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EACnE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,CAChC,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,GAAG,GAAG,CAAC,GAAoB,CAAC,CAAC;YACxC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,IAAI,kBAAQ,CAAC,uBAAuB,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;YACvF,CAAC;YACD,IAAA,oBAAW,EAAC,EAAE,CAAC,GAAG,CAAC,EAAE,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,IAAA,oBAAW,EAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEJ,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,YAAY,CAAC,GAAW,EAAE,KAAa;IAC9C,IAAI,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC;IAC7E,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,UAAU,CAAC,GAAY;IAC9B,OAAO;QACL,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;QACnE,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,SAAS,EAAE,GAAG,CAAC,SAAS;KACzB,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"course.d.ts","sourceRoot":"","sources":["../../src/commands/course.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,wBAAgB,aAAa,IAAI,OAAO,CAqHvC"}
1
+ {"version":3,"file":"course.d.ts","sourceRoot":"","sources":["../../src/commands/course.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,wBAAgB,aAAa,IAAI,OAAO,CA2GvC"}