@capawesome/cli 3.10.0 → 3.10.2

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 (34) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/commands/apps/builds/cancel.js +3 -3
  3. package/dist/commands/apps/builds/create.js +6 -6
  4. package/dist/commands/apps/builds/download.js +4 -4
  5. package/dist/commands/apps/builds/logs.js +3 -3
  6. package/dist/commands/apps/bundles/create.js +6 -6
  7. package/dist/commands/apps/bundles/delete.js +4 -4
  8. package/dist/commands/apps/bundles/delete.test.js +2 -2
  9. package/dist/commands/apps/bundles/update.js +3 -3
  10. package/dist/commands/apps/bundles/update.test.js +2 -2
  11. package/dist/commands/apps/channels/create.js +3 -3
  12. package/dist/commands/apps/channels/create.test.js +2 -2
  13. package/dist/commands/apps/channels/delete.js +4 -4
  14. package/dist/commands/apps/channels/delete.test.js +2 -2
  15. package/dist/commands/apps/channels/update.js +3 -3
  16. package/dist/commands/apps/channels/update.test.js +2 -2
  17. package/dist/commands/apps/create.js +3 -3
  18. package/dist/commands/apps/create.test.js +2 -2
  19. package/dist/commands/apps/delete.js +3 -3
  20. package/dist/commands/apps/delete.test.js +2 -2
  21. package/dist/commands/apps/deployments/cancel.js +3 -3
  22. package/dist/commands/apps/deployments/create.js +4 -4
  23. package/dist/commands/apps/deployments/logs.js +3 -3
  24. package/dist/commands/apps/devices/delete.js +4 -4
  25. package/dist/commands/apps/devices/delete.test.js +2 -2
  26. package/dist/commands/login.js +2 -2
  27. package/dist/commands/login.test.js +4 -4
  28. package/dist/commands/manifests/generate.js +2 -2
  29. package/dist/commands/manifests/generate.test.js +2 -2
  30. package/dist/commands/organizations/create.js +2 -2
  31. package/dist/commands/organizations/create.test.js +2 -2
  32. package/dist/services/app-bundle-files.js +3 -3
  33. package/dist/utils/environment.js +20 -0
  34. package/package.json +2 -3
package/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
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
+ ## [3.10.2](https://github.com/capawesome-team/cli/compare/v3.10.1...v3.10.2) (2025-12-30)
6
+
7
+ ## [3.10.1](https://github.com/capawesome-team/cli/compare/v3.10.0...v3.10.1) (2025-12-29)
8
+
9
+
10
+ ### Bug Fixes
11
+
12
+ * **apps:bundles:create:** adjust multipart upload threshold to 50 MB to prevent OOM issues ([ad0958c](https://github.com/capawesome-team/cli/commit/ad0958cc615bb5b5e97f8d04a55d4906c46418e1))
13
+
5
14
  ## [3.10.0](https://github.com/capawesome-team/cli/compare/v3.9.0...v3.10.0) (2025-12-20)
6
15
 
7
16
 
@@ -6,7 +6,7 @@ import organizationsService from '../../../services/organizations.js';
6
6
  import { prompt } from '../../../utils/prompt.js';
7
7
  import { defineCommand, defineOptions } from '@robingenz/zli';
8
8
  import consola from 'consola';
9
- import { hasTTY } from 'std-env';
9
+ import { isInteractive } from '../../../utils/environment.js';
10
10
  import { z } from 'zod';
11
11
  export default defineCommand({
12
12
  description: 'Cancel an app build.',
@@ -33,7 +33,7 @@ export default defineCommand({
33
33
  }
34
34
  // Prompt for app ID if not provided
35
35
  if (!appId) {
36
- if (!hasTTY) {
36
+ if (!isInteractive()) {
37
37
  consola.error('You must provide an app ID when running in non-interactive environment.');
38
38
  process.exit(1);
39
39
  }
@@ -70,7 +70,7 @@ export default defineCommand({
70
70
  }
71
71
  // Prompt for build ID if not provided
72
72
  if (!buildId) {
73
- if (!hasTTY) {
73
+ if (!isInteractive()) {
74
74
  consola.error('You must provide a build ID when running in non-interactive environment.');
75
75
  process.exit(1);
76
76
  }
@@ -12,7 +12,7 @@ import { defineCommand, defineOptions } from '@robingenz/zli';
12
12
  import consola from 'consola';
13
13
  import fs from 'fs/promises';
14
14
  import path from 'path';
15
- import { hasTTY } from 'std-env';
15
+ import { isInteractive } from '../../../utils/environment.js';
16
16
  import { z } from 'zod';
17
17
  const IOS_BUILD_TYPES = ['simulator', 'development', 'ad-hoc', 'app-store', 'enterprise'];
18
18
  const ANDROID_BUILD_TYPES = ['debug', 'release'];
@@ -76,7 +76,7 @@ export default defineCommand({
76
76
  }
77
77
  // Prompt for app ID if not provided
78
78
  if (!appId) {
79
- if (!hasTTY) {
79
+ if (!isInteractive()) {
80
80
  consola.error('You must provide an app ID when running in non-interactive environment.');
81
81
  process.exit(1);
82
82
  }
@@ -113,7 +113,7 @@ export default defineCommand({
113
113
  }
114
114
  // Prompt for platform if not provided
115
115
  if (!platform) {
116
- if (!hasTTY) {
116
+ if (!isInteractive()) {
117
117
  consola.error('You must provide a platform when running in non-interactive environment.');
118
118
  process.exit(1);
119
119
  }
@@ -132,7 +132,7 @@ export default defineCommand({
132
132
  }
133
133
  // Prompt for git ref if not provided
134
134
  if (!gitRef) {
135
- if (!hasTTY) {
135
+ if (!isInteractive()) {
136
136
  consola.error('You must provide a git ref when running in non-interactive environment.');
137
137
  process.exit(1);
138
138
  }
@@ -158,7 +158,7 @@ export default defineCommand({
158
158
  process.exit(1);
159
159
  }
160
160
  // Prompt for environment if not provided
161
- if (!environment && hasTTY) {
161
+ if (!environment && isInteractive()) {
162
162
  // @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
163
163
  const selectEnvironment = await prompt('Do you want to select an environment?', {
164
164
  type: 'confirm',
@@ -179,7 +179,7 @@ export default defineCommand({
179
179
  }
180
180
  }
181
181
  // Prompt for certificate if not provided
182
- if (!certificate && hasTTY) {
182
+ if (!certificate && isInteractive()) {
183
183
  // @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
184
184
  const selectCertificate = await prompt('Do you want to select a certificate?', {
185
185
  type: 'confirm',
@@ -7,7 +7,7 @@ import { defineCommand, defineOptions } from '@robingenz/zli';
7
7
  import consola from 'consola';
8
8
  import fs from 'fs/promises';
9
9
  import path from 'path';
10
- import { hasTTY } from 'std-env';
10
+ import { isInteractive } from '../../../utils/environment.js';
11
11
  import { z } from 'zod';
12
12
  export default defineCommand({
13
13
  description: 'Download an app build.',
@@ -46,7 +46,7 @@ export default defineCommand({
46
46
  }
47
47
  // Prompt for app ID if not provided
48
48
  if (!appId) {
49
- if (!hasTTY) {
49
+ if (!isInteractive()) {
50
50
  consola.error('You must provide an app ID when running in non-interactive environment.');
51
51
  process.exit(1);
52
52
  }
@@ -83,7 +83,7 @@ export default defineCommand({
83
83
  }
84
84
  // Prompt for build ID if not provided
85
85
  if (!buildId) {
86
- if (!hasTTY) {
86
+ if (!isInteractive()) {
87
87
  consola.error('You must provide a build ID when running in non-interactive environment.');
88
88
  process.exit(1);
89
89
  }
@@ -126,7 +126,7 @@ export default defineCommand({
126
126
  let downloadIpa = options.ipa;
127
127
  // Prompt for artifact types if none were provided
128
128
  if (!downloadApk && !downloadAab && !downloadIpa) {
129
- if (!hasTTY) {
129
+ if (!isInteractive()) {
130
130
  consola.error('You must specify at least one artifact type (--apk, --aab, or --ipa) when running in non-interactive environment.');
131
131
  process.exit(1);
132
132
  }
@@ -7,7 +7,7 @@ import { prompt } from '../../../utils/prompt.js';
7
7
  import { wait } from '../../../utils/wait.js';
8
8
  import { defineCommand, defineOptions } from '@robingenz/zli';
9
9
  import consola from 'consola';
10
- import { hasTTY } from 'std-env';
10
+ import { isInteractive } from '../../../utils/environment.js';
11
11
  import { z } from 'zod';
12
12
  export default defineCommand({
13
13
  description: 'Show logs of an app build.',
@@ -34,7 +34,7 @@ export default defineCommand({
34
34
  }
35
35
  // Prompt for app ID if not provided
36
36
  if (!appId) {
37
- if (!hasTTY) {
37
+ if (!isInteractive()) {
38
38
  consola.error('You must provide an app ID when running in non-interactive environment.');
39
39
  process.exit(1);
40
40
  }
@@ -71,7 +71,7 @@ export default defineCommand({
71
71
  }
72
72
  // Prompt for platform if not provided
73
73
  if (!buildId) {
74
- if (!hasTTY) {
74
+ if (!isInteractive()) {
75
75
  consola.error('You must provide a platform when running in non-interactive environment.');
76
76
  process.exit(1);
77
77
  }
@@ -19,9 +19,9 @@ import { exec } from 'child_process';
19
19
  import consola from 'consola';
20
20
  import { createReadStream } from 'fs';
21
21
  import pathModule from 'path';
22
- import { hasTTY } from 'std-env';
23
22
  import { promisify } from 'util';
24
23
  import { z } from 'zod';
24
+ import { isInteractive } from '../../../utils/environment.js';
25
25
  // Promisified exec for running build scripts
26
26
  const execAsync = promisify(exec);
27
27
  export default defineCommand({
@@ -138,7 +138,7 @@ export default defineCommand({
138
138
  }
139
139
  // If still no path, prompt the user
140
140
  if (!path) {
141
- if (!hasTTY) {
141
+ if (!isInteractive()) {
142
142
  consola.error('You must provide either a path or a url when running in non-interactive environment.');
143
143
  process.exit(1);
144
144
  }
@@ -164,7 +164,7 @@ export default defineCommand({
164
164
  if (!buildScript) {
165
165
  consola.warn('No build script (`capawesome:build` or `build`) found in package.json.');
166
166
  }
167
- else if (hasTTY) {
167
+ else if (isInteractive()) {
168
168
  const shouldBuild = await prompt('Do you want to run the build script before creating the bundle to ensure the latest assets are included?', {
169
169
  type: 'confirm',
170
170
  initial: true,
@@ -249,7 +249,7 @@ export default defineCommand({
249
249
  }
250
250
  // If still no appId, prompt the user
251
251
  if (!appId) {
252
- if (!hasTTY) {
252
+ if (!isInteractive()) {
253
253
  consola.error('You must provide an app ID when running in non-interactive environment.');
254
254
  process.exit(1);
255
255
  }
@@ -285,7 +285,7 @@ export default defineCommand({
285
285
  }
286
286
  }
287
287
  }
288
- if (!channel && hasTTY) {
288
+ if (!channel && isInteractive()) {
289
289
  const shouldDeployToChannel = await prompt('Do you want to deploy to a specific channel?', {
290
290
  type: 'confirm',
291
291
  initial: false,
@@ -338,7 +338,7 @@ export default defineCommand({
338
338
  const app = await appsService.findOne({ appId });
339
339
  const appName = app.name;
340
340
  // Final confirmation before creating bundle
341
- if (path && hasTTY) {
341
+ if (path && isInteractive()) {
342
342
  const relativePath = pathModule.relative(process.cwd(), path);
343
343
  const confirmed = await prompt(`Are you sure you want to create a bundle from path "${relativePath}" for app "${appName}" (${appId})?`, {
344
344
  type: 'confirm',
@@ -5,7 +5,7 @@ import organizationsService from '../../../services/organizations.js';
5
5
  import { prompt } from '../../../utils/prompt.js';
6
6
  import { defineCommand, defineOptions } from '@robingenz/zli';
7
7
  import consola from 'consola';
8
- import { hasTTY } from 'std-env';
8
+ import { isInteractive } from '../../../utils/environment.js';
9
9
  import { z } from 'zod';
10
10
  export default defineCommand({
11
11
  description: 'Delete an app bundle.',
@@ -21,7 +21,7 @@ export default defineCommand({
21
21
  }
22
22
  // Prompt for missing arguments
23
23
  if (!appId) {
24
- if (!hasTTY) {
24
+ if (!isInteractive()) {
25
25
  consola.error('You must provide an app ID when running in non-interactive environment.');
26
26
  process.exit(1);
27
27
  }
@@ -53,7 +53,7 @@ export default defineCommand({
53
53
  });
54
54
  }
55
55
  if (!bundleId) {
56
- if (!hasTTY) {
56
+ if (!isInteractive()) {
57
57
  consola.error('You must provide the bundle ID when running in non-interactive environment.');
58
58
  process.exit(1);
59
59
  }
@@ -62,7 +62,7 @@ export default defineCommand({
62
62
  });
63
63
  }
64
64
  // Confirm deletion
65
- if (hasTTY) {
65
+ if (isInteractive()) {
66
66
  const confirmed = await prompt('Are you sure you want to delete this bundle?', {
67
67
  type: 'confirm',
68
68
  });
@@ -11,8 +11,8 @@ vi.mock('@/utils/user-config.js');
11
11
  vi.mock('@/utils/prompt.js');
12
12
  vi.mock('@/services/authorization-service.js');
13
13
  vi.mock('consola');
14
- vi.mock('std-env', () => ({
15
- hasTTY: true,
14
+ vi.mock('@/utils/environment.js', () => ({
15
+ isInteractive: () => true,
16
16
  }));
17
17
  describe('apps-bundles-delete', () => {
18
18
  const mockUserConfig = vi.mocked(userConfig);
@@ -5,7 +5,7 @@ import organizationsService from '../../../services/organizations.js';
5
5
  import { prompt } from '../../../utils/prompt.js';
6
6
  import { defineCommand, defineOptions } from '@robingenz/zli';
7
7
  import consola from 'consola';
8
- import { hasTTY } from 'std-env';
8
+ import { isInteractive } from '../../../utils/environment.js';
9
9
  import { z } from 'zod';
10
10
  export default defineCommand({
11
11
  description: 'Update an app bundle.',
@@ -53,7 +53,7 @@ export default defineCommand({
53
53
  }
54
54
  // Prompt for missing arguments
55
55
  if (!appId) {
56
- if (!hasTTY) {
56
+ if (!isInteractive()) {
57
57
  consola.error('You must provide an app ID when running in non-interactive environment.');
58
58
  process.exit(1);
59
59
  }
@@ -85,7 +85,7 @@ export default defineCommand({
85
85
  });
86
86
  }
87
87
  if (!bundleId) {
88
- if (!hasTTY) {
88
+ if (!isInteractive()) {
89
89
  consola.error('You must provide the bundle ID when running in non-interactive environment.');
90
90
  process.exit(1);
91
91
  }
@@ -11,8 +11,8 @@ vi.mock('@/utils/user-config.js');
11
11
  vi.mock('@/utils/prompt.js');
12
12
  vi.mock('@/services/authorization-service.js');
13
13
  vi.mock('consola');
14
- vi.mock('std-env', () => ({
15
- hasTTY: true,
14
+ vi.mock('@/utils/environment.js', () => ({
15
+ isInteractive: () => true,
16
16
  }));
17
17
  describe('apps-bundles-update', () => {
18
18
  const mockUserConfig = vi.mocked(userConfig);
@@ -6,7 +6,7 @@ import { getMessageFromUnknownError } from '../../../utils/error.js';
6
6
  import { prompt } from '../../../utils/prompt.js';
7
7
  import { defineCommand, defineOptions } from '@robingenz/zli';
8
8
  import consola from 'consola';
9
- import { hasTTY } from 'std-env';
9
+ import { isInteractive } from '../../../utils/environment.js';
10
10
  import { z } from 'zod';
11
11
  export default defineCommand({
12
12
  description: 'Create a new app channel.',
@@ -43,7 +43,7 @@ export default defineCommand({
43
43
  }
44
44
  // Validate the app ID
45
45
  if (!appId) {
46
- if (!hasTTY) {
46
+ if (!isInteractive()) {
47
47
  consola.error('You must provide an app ID when running in non-interactive environment.');
48
48
  process.exit(1);
49
49
  }
@@ -76,7 +76,7 @@ export default defineCommand({
76
76
  }
77
77
  // Validate the channel name
78
78
  if (!name) {
79
- if (!hasTTY) {
79
+ if (!isInteractive()) {
80
80
  consola.error('You must provide the channel name when running in non-interactive environment.');
81
81
  process.exit(1);
82
82
  }
@@ -11,8 +11,8 @@ vi.mock('@/utils/user-config.js');
11
11
  vi.mock('@/utils/prompt.js');
12
12
  vi.mock('@/services/authorization-service.js');
13
13
  vi.mock('consola');
14
- vi.mock('std-env', () => ({
15
- hasTTY: true,
14
+ vi.mock('@/utils/environment.js', () => ({
15
+ isInteractive: () => true,
16
16
  }));
17
17
  describe('apps-channels-create', () => {
18
18
  const mockUserConfig = vi.mocked(userConfig);
@@ -5,7 +5,7 @@ import organizationsService from '../../../services/organizations.js';
5
5
  import { prompt } from '../../../utils/prompt.js';
6
6
  import { defineCommand, defineOptions } from '@robingenz/zli';
7
7
  import consola from 'consola';
8
- import { hasTTY } from 'std-env';
8
+ import { isInteractive } from '../../../utils/environment.js';
9
9
  import { z } from 'zod';
10
10
  export default defineCommand({
11
11
  description: 'Delete an app channel.',
@@ -27,7 +27,7 @@ export default defineCommand({
27
27
  process.exit(1);
28
28
  }
29
29
  if (!appId) {
30
- if (!hasTTY) {
30
+ if (!isInteractive()) {
31
31
  consola.error('You must provide an app ID when running in non-interactive environment.');
32
32
  process.exit(1);
33
33
  }
@@ -60,7 +60,7 @@ export default defineCommand({
60
60
  }
61
61
  // Prompt for channel ID or name if neither is provided
62
62
  if (!channelId && !name) {
63
- if (!hasTTY) {
63
+ if (!isInteractive()) {
64
64
  consola.error('You must provide either the channel ID or name when running in non-interactive environment.');
65
65
  process.exit(1);
66
66
  }
@@ -69,7 +69,7 @@ export default defineCommand({
69
69
  });
70
70
  }
71
71
  // Confirm deletion
72
- if (hasTTY) {
72
+ if (isInteractive()) {
73
73
  const confirmed = await prompt('Are you sure you want to delete this channel?', {
74
74
  type: 'confirm',
75
75
  });
@@ -11,8 +11,8 @@ vi.mock('@/utils/user-config.js');
11
11
  vi.mock('@/utils/prompt.js');
12
12
  vi.mock('@/services/authorization-service.js');
13
13
  vi.mock('consola');
14
- vi.mock('std-env', () => ({
15
- hasTTY: true,
14
+ vi.mock('@/utils/environment.js', () => ({
15
+ isInteractive: () => true,
16
16
  }));
17
17
  describe('apps-channels-delete', () => {
18
18
  const mockUserConfig = vi.mocked(userConfig);
@@ -5,7 +5,7 @@ import organizationsService from '../../../services/organizations.js';
5
5
  import { prompt } from '../../../utils/prompt.js';
6
6
  import { defineCommand, defineOptions } from '@robingenz/zli';
7
7
  import consola from 'consola';
8
- import { hasTTY } from 'std-env';
8
+ import { isInteractive } from '../../../utils/environment.js';
9
9
  import { z } from 'zod';
10
10
  export default defineCommand({
11
11
  description: 'Update an existing app channel.',
@@ -26,7 +26,7 @@ export default defineCommand({
26
26
  }
27
27
  // Prompt app ID if not provided
28
28
  if (!appId) {
29
- if (!hasTTY) {
29
+ if (!isInteractive()) {
30
30
  consola.error('You must provide an app ID when running in non-interactive environment.');
31
31
  process.exit(1);
32
32
  }
@@ -59,7 +59,7 @@ export default defineCommand({
59
59
  }
60
60
  // Prompt for channel ID if not provided
61
61
  if (!channelId) {
62
- if (!hasTTY) {
62
+ if (!isInteractive()) {
63
63
  consola.error('You must provide the channel ID when running in non-interactive environment.');
64
64
  process.exit(1);
65
65
  }
@@ -11,8 +11,8 @@ vi.mock('@/utils/user-config.js');
11
11
  vi.mock('@/utils/prompt.js');
12
12
  vi.mock('@/services/authorization-service.js');
13
13
  vi.mock('consola');
14
- vi.mock('std-env', () => ({
15
- hasTTY: true,
14
+ vi.mock('@/utils/environment.js', () => ({
15
+ isInteractive: () => true,
16
16
  }));
17
17
  describe('apps-channels-update', () => {
18
18
  const mockUserConfig = vi.mocked(userConfig);
@@ -1,10 +1,10 @@
1
1
  import appsService from '../../services/apps.js';
2
2
  import authorizationService from '../../services/authorization-service.js';
3
3
  import organizationsService from '../../services/organizations.js';
4
+ import { isInteractive } from '../../utils/environment.js';
4
5
  import { prompt } from '../../utils/prompt.js';
5
6
  import { defineCommand, defineOptions } from '@robingenz/zli';
6
7
  import consola from 'consola';
7
- import { hasTTY } from 'std-env';
8
8
  import { z } from 'zod';
9
9
  export default defineCommand({
10
10
  description: 'Create a new app.',
@@ -19,7 +19,7 @@ export default defineCommand({
19
19
  process.exit(1);
20
20
  }
21
21
  if (!organizationId) {
22
- if (!hasTTY) {
22
+ if (!isInteractive()) {
23
23
  consola.error('You must provide the organization ID when running in non-interactive environment.');
24
24
  process.exit(1);
25
25
  }
@@ -39,7 +39,7 @@ export default defineCommand({
39
39
  }
40
40
  }
41
41
  if (!name) {
42
- if (!hasTTY) {
42
+ if (!isInteractive()) {
43
43
  consola.error('You must provide the app name when running in non-interactive environment.');
44
44
  process.exit(1);
45
45
  }
@@ -11,8 +11,8 @@ vi.mock('@/utils/user-config.js');
11
11
  vi.mock('@/utils/prompt.js');
12
12
  vi.mock('@/services/authorization-service.js');
13
13
  vi.mock('consola');
14
- vi.mock('std-env', () => ({
15
- hasTTY: true,
14
+ vi.mock('@/utils/environment.js', () => ({
15
+ isInteractive: () => true,
16
16
  }));
17
17
  describe('apps-create', () => {
18
18
  const mockUserConfig = vi.mocked(userConfig);
@@ -1,10 +1,10 @@
1
1
  import appsService from '../../services/apps.js';
2
2
  import authorizationService from '../../services/authorization-service.js';
3
3
  import organizationsService from '../../services/organizations.js';
4
+ import { isInteractive } from '../../utils/environment.js';
4
5
  import { prompt } from '../../utils/prompt.js';
5
6
  import { defineCommand, defineOptions } from '@robingenz/zli';
6
7
  import consola from 'consola';
7
- import { hasTTY } from 'std-env';
8
8
  import { z } from 'zod';
9
9
  export default defineCommand({
10
10
  description: 'Delete an app.',
@@ -18,7 +18,7 @@ export default defineCommand({
18
18
  process.exit(1);
19
19
  }
20
20
  if (!appId) {
21
- if (!hasTTY) {
21
+ if (!isInteractive()) {
22
22
  consola.error('You must provide the app ID when running in non-interactive environment.');
23
23
  process.exit(1);
24
24
  }
@@ -49,7 +49,7 @@ export default defineCommand({
49
49
  options: apps.map((app) => ({ label: app.name, value: app.id })),
50
50
  });
51
51
  }
52
- if (hasTTY) {
52
+ if (isInteractive()) {
53
53
  const confirmed = await prompt('Are you sure you want to delete this app?', {
54
54
  type: 'confirm',
55
55
  });
@@ -11,8 +11,8 @@ vi.mock('@/utils/user-config.js');
11
11
  vi.mock('@/utils/prompt.js');
12
12
  vi.mock('@/services/authorization-service.js');
13
13
  vi.mock('consola');
14
- vi.mock('std-env', () => ({
15
- hasTTY: true,
14
+ vi.mock('@/utils/environment.js', () => ({
15
+ isInteractive: () => true,
16
16
  }));
17
17
  describe('apps-delete', () => {
18
18
  const mockUserConfig = vi.mocked(userConfig);
@@ -6,7 +6,7 @@ import organizationsService from '../../../services/organizations.js';
6
6
  import { prompt } from '../../../utils/prompt.js';
7
7
  import { defineCommand, defineOptions } from '@robingenz/zli';
8
8
  import consola from 'consola';
9
- import { hasTTY } from 'std-env';
9
+ import { isInteractive } from '../../../utils/environment.js';
10
10
  import { z } from 'zod';
11
11
  export default defineCommand({
12
12
  description: 'Cancel an ongoing app deployment.',
@@ -33,7 +33,7 @@ export default defineCommand({
33
33
  }
34
34
  // Prompt for app ID if not provided
35
35
  if (!appId) {
36
- if (!hasTTY) {
36
+ if (!isInteractive()) {
37
37
  consola.error('You must provide an app ID when running in non-interactive environment.');
38
38
  process.exit(1);
39
39
  }
@@ -70,7 +70,7 @@ export default defineCommand({
70
70
  }
71
71
  // Prompt for deployment ID if not provided
72
72
  if (!deploymentId) {
73
- if (!hasTTY) {
73
+ if (!isInteractive()) {
74
74
  consola.error('You must provide a deployment ID when running in non-interactive environment.');
75
75
  process.exit(1);
76
76
  }
@@ -10,7 +10,7 @@ import { prompt } from '../../../utils/prompt.js';
10
10
  import { wait } from '../../../utils/wait.js';
11
11
  import { defineCommand, defineOptions } from '@robingenz/zli';
12
12
  import consola from 'consola';
13
- import { hasTTY } from 'std-env';
13
+ import { isInteractive } from '../../../utils/environment.js';
14
14
  import { z } from 'zod';
15
15
  export default defineCommand({
16
16
  description: 'Create a new app deployment.',
@@ -42,7 +42,7 @@ export default defineCommand({
42
42
  }
43
43
  // Prompt for app ID if not provided
44
44
  if (!appId) {
45
- if (!hasTTY) {
45
+ if (!isInteractive()) {
46
46
  consola.error('You must provide an app ID when running in non-interactive environment.');
47
47
  process.exit(1);
48
48
  }
@@ -79,7 +79,7 @@ export default defineCommand({
79
79
  }
80
80
  // Prompt for build ID if not provided
81
81
  if (!buildId) {
82
- if (!hasTTY) {
82
+ if (!isInteractive()) {
83
83
  consola.error('You must provide a build ID when running in non-interactive environment.');
84
84
  process.exit(1);
85
85
  }
@@ -105,7 +105,7 @@ export default defineCommand({
105
105
  const build = await appBuildsService.findOne({ appId, appBuildId: buildId });
106
106
  // Prompt for destination if not provided
107
107
  if (!destination) {
108
- if (!hasTTY) {
108
+ if (!isInteractive()) {
109
109
  consola.error('You must provide a destination when running in non-interactive environment.');
110
110
  process.exit(1);
111
111
  }
@@ -7,7 +7,7 @@ import { prompt } from '../../../utils/prompt.js';
7
7
  import { wait } from '../../../utils/wait.js';
8
8
  import { defineCommand, defineOptions } from '@robingenz/zli';
9
9
  import consola from 'consola';
10
- import { hasTTY } from 'std-env';
10
+ import { isInteractive } from '../../../utils/environment.js';
11
11
  import { z } from 'zod';
12
12
  export default defineCommand({
13
13
  description: 'View the deployment logs of an app.',
@@ -34,7 +34,7 @@ export default defineCommand({
34
34
  }
35
35
  // Prompt for app ID if not provided
36
36
  if (!appId) {
37
- if (!hasTTY) {
37
+ if (!isInteractive()) {
38
38
  consola.error('You must provide an app ID when running in non-interactive environment.');
39
39
  process.exit(1);
40
40
  }
@@ -71,7 +71,7 @@ export default defineCommand({
71
71
  }
72
72
  // Prompt for deployment ID if not provided
73
73
  if (!deploymentId) {
74
- if (!hasTTY) {
74
+ if (!isInteractive()) {
75
75
  consola.error('You must provide a deployment ID when running in non-interactive environment.');
76
76
  process.exit(1);
77
77
  }
@@ -5,7 +5,7 @@ import organizationsService from '../../../services/organizations.js';
5
5
  import { prompt } from '../../../utils/prompt.js';
6
6
  import { defineCommand, defineOptions } from '@robingenz/zli';
7
7
  import consola from 'consola';
8
- import { hasTTY } from 'std-env';
8
+ import { isInteractive } from '../../../utils/environment.js';
9
9
  import { z } from 'zod';
10
10
  export default defineCommand({
11
11
  description: 'Delete an app device.',
@@ -21,7 +21,7 @@ export default defineCommand({
21
21
  }
22
22
  // Prompt for app ID if not provided
23
23
  if (!appId) {
24
- if (!hasTTY) {
24
+ if (!isInteractive()) {
25
25
  consola.error('You must provide an app ID when running in non-interactive environment.');
26
26
  process.exit(1);
27
27
  }
@@ -54,7 +54,7 @@ export default defineCommand({
54
54
  }
55
55
  // Prompt for device ID if not provided
56
56
  if (!deviceId) {
57
- if (!hasTTY) {
57
+ if (!isInteractive()) {
58
58
  consola.error('You must provide the device ID when running in non-interactive environment.');
59
59
  process.exit(1);
60
60
  }
@@ -63,7 +63,7 @@ export default defineCommand({
63
63
  });
64
64
  }
65
65
  // Confirm deletion
66
- if (hasTTY) {
66
+ if (isInteractive()) {
67
67
  const confirmed = await prompt('Are you sure you want to delete this device?', {
68
68
  type: 'confirm',
69
69
  });
@@ -11,8 +11,8 @@ vi.mock('@/utils/user-config.js');
11
11
  vi.mock('@/utils/prompt.js');
12
12
  vi.mock('@/services/authorization-service.js');
13
13
  vi.mock('consola');
14
- vi.mock('std-env', () => ({
15
- hasTTY: true,
14
+ vi.mock('@/utils/environment.js', () => ({
15
+ isInteractive: () => true,
16
16
  }));
17
17
  describe('apps-devices-delete', () => {
18
18
  const mockUserConfig = vi.mocked(userConfig);
@@ -2,13 +2,13 @@ import configService from '../services/config.js';
2
2
  import sessionCodesService from '../services/session-code.js';
3
3
  import sessionsService from '../services/sessions.js';
4
4
  import usersService from '../services/users.js';
5
+ import { isInteractive } from '../utils/environment.js';
5
6
  import { prompt } from '../utils/prompt.js';
6
7
  import userConfig from '../utils/user-config.js';
7
8
  import { defineCommand, defineOptions } from '@robingenz/zli';
8
9
  import { AxiosError } from 'axios';
9
10
  import consola from 'consola';
10
11
  import open from 'open';
11
- import { hasTTY } from 'std-env';
12
12
  import { z } from 'zod';
13
13
  export default defineCommand({
14
14
  description: 'Sign in to the Capawesome Cloud Console.',
@@ -19,7 +19,7 @@ export default defineCommand({
19
19
  const consoleBaseUrl = await configService.getValueForKey('CONSOLE_BASE_URL');
20
20
  let { token: sessionIdOrToken } = options;
21
21
  if (sessionIdOrToken === undefined) {
22
- if (!hasTTY) {
22
+ if (!isInteractive()) {
23
23
  consola.error('You must provide a token when running in non-interactive environment.');
24
24
  process.exit(1);
25
25
  }
@@ -17,11 +17,11 @@ vi.mock('@/services/config.js');
17
17
  vi.mock('open');
18
18
  vi.mock('consola');
19
19
  vi.mock('@/utils/prompt.js');
20
- vi.mock('std-env', () => ({
21
- hasTTY: true,
20
+ vi.mock('@/utils/environment.js', () => ({
21
+ isInteractive: () => true,
22
22
  }));
23
- vi.mock('std-env', () => ({
24
- hasTTY: true,
23
+ vi.mock('@/utils/environment.js', () => ({
24
+ isInteractive: () => true,
25
25
  }));
26
26
  describe('login', () => {
27
27
  const mockUserConfig = vi.mocked(userConfig);
@@ -3,7 +3,7 @@ import { generateManifestJson } from '../../utils/manifest.js';
3
3
  import { prompt } from '../../utils/prompt.js';
4
4
  import { defineCommand, defineOptions } from '@robingenz/zli';
5
5
  import consola from 'consola';
6
- import { hasTTY } from 'std-env';
6
+ import { isInteractive } from '../../utils/environment.js';
7
7
  import { z } from 'zod';
8
8
  export default defineCommand({
9
9
  description: 'Generate a manifest file.',
@@ -13,7 +13,7 @@ export default defineCommand({
13
13
  action: async (options, args) => {
14
14
  let path = options.path;
15
15
  if (!path) {
16
- if (!hasTTY) {
16
+ if (!isInteractive()) {
17
17
  consola.error('You must provide the path to the web assets folder when running in non-interactive environment.');
18
18
  process.exit(1);
19
19
  }
@@ -9,8 +9,8 @@ vi.mock('@/utils/file.js');
9
9
  vi.mock('@/utils/manifest.js');
10
10
  vi.mock('@/utils/prompt.js');
11
11
  vi.mock('consola');
12
- vi.mock('std-env', () => ({
13
- hasTTY: true,
12
+ vi.mock('@/utils/environment.js', () => ({
13
+ isInteractive: () => true,
14
14
  }));
15
15
  describe('manifests-generate', () => {
16
16
  const mockFileExistsAtPath = vi.mocked(fileExistsAtPath);
@@ -1,9 +1,9 @@
1
1
  import authorizationService from '../../services/authorization-service.js';
2
2
  import organizationsService from '../../services/organizations.js';
3
+ import { isInteractive } from '../../utils/environment.js';
3
4
  import { prompt } from '../../utils/prompt.js';
4
5
  import { defineCommand, defineOptions } from '@robingenz/zli';
5
6
  import consola from 'consola';
6
- import { hasTTY } from 'std-env';
7
7
  import { z } from 'zod';
8
8
  export default defineCommand({
9
9
  description: 'Create a new organization.',
@@ -17,7 +17,7 @@ export default defineCommand({
17
17
  process.exit(1);
18
18
  }
19
19
  if (!name) {
20
- if (!hasTTY) {
20
+ if (!isInteractive()) {
21
21
  consola.error('You must provide the organization name when running in non-interactive environment.');
22
22
  process.exit(1);
23
23
  }
@@ -11,8 +11,8 @@ vi.mock('@/utils/user-config.js');
11
11
  vi.mock('@/utils/prompt.js');
12
12
  vi.mock('@/services/authorization-service.js');
13
13
  vi.mock('consola');
14
- vi.mock('std-env', () => ({
15
- hasTTY: true,
14
+ vi.mock('@/utils/environment.js', () => ({
15
+ isInteractive: () => true,
16
16
  }));
17
17
  describe('organizations-create', () => {
18
18
  const mockUserConfig = vi.mocked(userConfig);
@@ -1,7 +1,7 @@
1
- import FormData from 'form-data';
2
1
  import { MAX_CONCURRENT_UPLOADS } from '../config/index.js';
3
- import httpClient from '../utils/http-client.js';
4
2
  import authorizationService from '../services/authorization-service.js';
3
+ import httpClient from '../utils/http-client.js';
4
+ import FormData from 'form-data';
5
5
  class AppBundleFilesServiceImpl {
6
6
  httpClient;
7
7
  constructor(httpClient) {
@@ -9,7 +9,7 @@ class AppBundleFilesServiceImpl {
9
9
  }
10
10
  async create(dto) {
11
11
  const sizeInBytes = dto.buffer.byteLength;
12
- const useMultipartUpload = sizeInBytes >= 100 * 1024 * 1024; // 100 MB
12
+ const useMultipartUpload = sizeInBytes >= 50 * 1024 * 1024; // 50 MB
13
13
  const formData = new FormData();
14
14
  formData.append('checksum', dto.checksum);
15
15
  if (!useMultipartUpload) {
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Detects if the current environment supports interactive prompts.
3
+ *
4
+ * For interactive prompts to work, we need:
5
+ * 1. stdin to be a TTY (to read user input)
6
+ * 2. stdout to be a TTY (to display the prompt)
7
+ * 3. Not running in a CI environment
8
+ *
9
+ * This is more robust than just checking stdout.isTTY (like std-env's hasTTY),
10
+ * because interactive prompts require BOTH input and output TTYs.
11
+ */
12
+ export const isInteractive = () => {
13
+ // Check if both stdin AND stdout are TTYs
14
+ const hasInputTTY = Boolean(process.stdin?.isTTY);
15
+ const hasOutputTTY = Boolean(process.stdout?.isTTY);
16
+ // Check for CI environment
17
+ const isCI = Boolean(process.env.CI);
18
+ // Need BOTH input and output TTY, and not in CI
19
+ return hasInputTTY && hasOutputTTY && !isCI;
20
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capawesome/cli",
3
- "version": "3.10.0",
3
+ "version": "3.10.2",
4
4
  "description": "The Capawesome Cloud Command Line Interface (CLI) to manage Live Updates and more.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -67,8 +67,7 @@
67
67
  "open": "10.2.0",
68
68
  "rc9": "2.1.2",
69
69
  "semver": "7.6.3",
70
- "std-env": "3.9.0",
71
- "systeminformation": "5.25.11",
70
+ "systeminformation": "5.28.5",
72
71
  "zod": "4.0.17"
73
72
  },
74
73
  "devDependencies": {