@capawesome/cli 4.7.0 → 4.8.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
4
 
5
+ ## [4.8.0](https://github.com/capawesome-team/cli/compare/v4.7.0...v4.8.0) (2026-04-08)
6
+
7
+
8
+ ### Features
9
+
10
+ * **apps:** add `--json` option to `apps:create` ([#147](https://github.com/capawesome-team/cli/issues/147)) ([3573d60](https://github.com/capawesome-team/cli/commit/3573d6021574111e12a6758d212b41002a357ae8))
11
+ * **apps:** add `--link` option to `apps:create` ([#145](https://github.com/capawesome-team/cli/issues/145)) ([c9e38b8](https://github.com/capawesome-team/cli/commit/c9e38b8e3e360bc856cbff4bf66b68fadedd3b04))
12
+ * **apps:** add prompt to connect git repository after app creation ([#143](https://github.com/capawesome-team/cli/issues/143)) ([3427e6d](https://github.com/capawesome-team/cli/commit/3427e6da277fa61902dac5b9045c433535188142))
13
+ * **apps:** print app URL after `apps:create` ([#146](https://github.com/capawesome-team/cli/issues/146)) ([ed7e04a](https://github.com/capawesome-team/cli/commit/ed7e04a5b379187d8c69856d180256f246931571))
14
+ * **error:** add `UserError` class to skip user errors in Sentry ([#144](https://github.com/capawesome-team/cli/issues/144)) ([f7728d0](https://github.com/capawesome-team/cli/commit/f7728d0849cf4883c761de5bfd673eb5c3c37409))
15
+
5
16
  ## [4.7.0](https://github.com/capawesome-team/cli/compare/v4.6.0...v4.7.0) (2026-04-04)
6
17
 
7
18
 
@@ -1,3 +1,4 @@
1
+ import { DEFAULT_CONSOLE_BASE_URL } from '../../config/consts.js';
1
2
  import appsService from '../../services/apps.js';
2
3
  import { withAuth } from '../../utils/auth.js';
3
4
  import { isInteractive } from '../../utils/environment.js';
@@ -8,11 +9,14 @@ import { z } from 'zod';
8
9
  export default defineCommand({
9
10
  description: 'Create a new app.',
10
11
  options: defineOptions(z.object({
12
+ json: z.boolean().optional().describe('Output in JSON format.'),
13
+ link: z.boolean().optional().describe('Connect the created app to the local git repository.'),
11
14
  name: z.string().optional().describe('Name of the app.'),
12
15
  organizationId: z.string().optional().describe('ID of the organization to create the app in.'),
13
- })),
16
+ yes: z.boolean().optional().describe('Skip all confirmation prompts.'),
17
+ }), { y: 'yes' }),
14
18
  action: withAuth(async (options, args) => {
15
- let { name, organizationId } = options;
19
+ let { json, name, organizationId } = options;
16
20
  if (!organizationId) {
17
21
  if (!isInteractive()) {
18
22
  consola.error('You must provide the organization ID when running in non-interactive environment.');
@@ -28,7 +32,22 @@ export default defineCommand({
28
32
  name = await prompt('Enter the name of the app:', { type: 'text' });
29
33
  }
30
34
  const response = await appsService.create({ name, organizationId });
31
- consola.info(`App ID: ${response.id}`);
32
- consola.success('App created successfully.');
35
+ if (!json) {
36
+ consola.info(`App ID: ${response.id}`);
37
+ consola.info(`App URL: ${DEFAULT_CONSOLE_BASE_URL}/apps/${response.id}`);
38
+ consola.success('App created successfully.');
39
+ }
40
+ let shouldLink = options.link ?? false;
41
+ if (!shouldLink && !options.yes && !json && isInteractive()) {
42
+ shouldLink = await prompt('Do you want to connect a git repository?', {
43
+ type: 'confirm',
44
+ });
45
+ }
46
+ if (shouldLink) {
47
+ await (await import('../../commands/apps/link.js').then((mod) => mod.default)).action({ appId: response.id }, undefined);
48
+ }
49
+ if (json) {
50
+ console.log(JSON.stringify({ id: response.id }, null, 2));
51
+ }
33
52
  }),
34
53
  });
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import configService from './services/config.js';
3
3
  import updateService from './services/update.js';
4
- import { getMessageFromUnknownError } from './utils/error.js';
4
+ import { getMessageFromUnknownError, UserError } from './utils/error.js';
5
5
  import { defineConfig, processConfig, ZliError } from '@robingenz/zli';
6
6
  import * as Sentry from '@sentry/node';
7
7
  import { AxiosError } from 'axios';
@@ -76,6 +76,14 @@ const config = defineConfig({
76
76
  },
77
77
  });
78
78
  const captureException = async (error) => {
79
+ // Ignore failed HTTP requests
80
+ if (error instanceof AxiosError) {
81
+ return;
82
+ }
83
+ // Ignore expected user errors
84
+ if (error instanceof UserError) {
85
+ return;
86
+ }
79
87
  // Ignore errors from the CLI itself (e.g. "No command found.")
80
88
  if (error instanceof ZliError) {
81
89
  return;
@@ -84,10 +92,6 @@ const captureException = async (error) => {
84
92
  if (error instanceof ZodError) {
85
93
  return;
86
94
  }
87
- // Ignore failed HTTP requests
88
- if (error instanceof AxiosError) {
89
- return;
90
- }
91
95
  const environment = await configService.getValueForKey('ENVIRONMENT');
92
96
  if (environment !== 'production') {
93
97
  return;
@@ -1,5 +1,11 @@
1
1
  import { AxiosError } from 'axios';
2
2
  import { ZodError } from 'zod';
3
+ export class UserError extends Error {
4
+ constructor(message) {
5
+ super(message);
6
+ this.name = 'UserError';
7
+ }
8
+ }
3
9
  export const getMessageFromUnknownError = (error) => {
4
10
  let message = 'An unknown error has occurred.';
5
11
  if (error instanceof AxiosError) {
package/dist/utils/git.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { execSync } from 'child_process';
2
+ import { UserError } from '../utils/error.js';
2
3
  const HOSTNAME_TO_PROVIDER = {
3
4
  'github.com': 'github',
4
5
  'gitlab.com': 'gitlab',
@@ -15,7 +16,7 @@ const getGitRemoteUrl = () => {
15
16
  return execSync('git remote get-url origin', { encoding: 'utf-8' }).trim();
16
17
  }
17
18
  catch {
18
- throw new Error('Could not read the git remote URL. Make sure you are inside a git repository with an origin remote.');
19
+ throw new UserError('Could not read the git remote URL. Make sure you are inside a git repository with an origin remote.');
19
20
  }
20
21
  };
21
22
  export const parseGitRemoteUrl = (remoteUrl) => {
@@ -55,7 +56,7 @@ export const parseGitRemoteUrl = (remoteUrl) => {
55
56
  const hostname = sshMatch[1];
56
57
  const provider = HOSTNAME_TO_PROVIDER[hostname];
57
58
  if (!provider) {
58
- throw new Error(`Unsupported git provider for hostname "${hostname}".`);
59
+ throw new UserError(`Unsupported git provider for hostname "${hostname}".`);
59
60
  }
60
61
  return {
61
62
  ownerSlug: sshMatch[2],
@@ -71,7 +72,7 @@ export const parseGitRemoteUrl = (remoteUrl) => {
71
72
  const hostname = url.hostname;
72
73
  const provider = HOSTNAME_TO_PROVIDER[hostname];
73
74
  if (!provider) {
74
- throw new Error(`Unsupported git provider for hostname "${hostname}".`);
75
+ throw new UserError(`Unsupported git provider for hostname "${hostname}".`);
75
76
  }
76
77
  const pathSegments = url.pathname.split('/').filter(Boolean);
77
78
  const repositorySlug = pathSegments.pop()?.replace(/\.git$/, '');
@@ -83,9 +84,9 @@ export const parseGitRemoteUrl = (remoteUrl) => {
83
84
  }
84
85
  }
85
86
  catch (error) {
86
- if (error instanceof Error && error.message.startsWith('Unsupported git provider')) {
87
+ if (error instanceof UserError) {
87
88
  throw error;
88
89
  }
89
90
  }
90
- throw new Error('Could not parse git remote URL.');
91
+ throw new UserError('Could not parse git remote URL.');
91
92
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capawesome/cli",
3
- "version": "4.7.0",
3
+ "version": "4.8.0",
4
4
  "description": "The Capawesome Cloud Command Line Interface (CLI) to manage Live Updates and more.",
5
5
  "type": "module",
6
6
  "scripts": {