cxtms 1.9.16 → 1.9.22
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/README.md +1 -1
- package/dist/cli.js +81 -48
- package/dist/cli.js.map +1 -1
- package/dist/workflowValidator.d.ts +1 -1
- package/dist/workflowValidator.js +1 -1
- package/package.json +4 -4
- package/schemas/components/README.md +1 -1
- package/schemas/components/appComponent.json +2 -2
- package/schemas/components/index.json +1 -1
- package/schemas/fields/README.md +3 -3
- package/schemas/fields/index.json +1 -1
- package/schemas/schemas.json +3 -3
- package/schemas/workflows/workflow.json +2 -2
- package/scripts/postinstall.js +2 -2
- package/skills/cxtms-developer/SKILL.md +2 -2
- package/skills/cxtms-developer/ref-cli-auth.md +15 -13
- package/skills/cxtms-module-builder/SKILL.md +6 -6
- package/skills/cxtms-workflow-builder/SKILL.md +5 -5
- package/skills/cxtms-workflow-builder/ref-expressions-ncalc.md +9 -4
- package/skills/cxtms-workflow-builder/ref-expressions-template.md +5 -0
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](https://github.com/cargoxplorer/cx-schema/actions)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
|
|
8
|
-
Schema validation package for
|
|
8
|
+
Schema validation package for CXTMS YAML modules and workflows. This package provides comprehensive validation for YAML-based configurations used in CXTMS.
|
|
9
9
|
|
|
10
10
|
## Features
|
|
11
11
|
|
package/dist/cli.js
CHANGED
|
@@ -64,6 +64,38 @@ function checkForUpdates() {
|
|
|
64
64
|
// Update check must never break the CLI.
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
+
const CX_SKILL_NAMES = ['cxtms-developer', 'cxtms-module-builder', 'cxtms-workflow-builder'];
|
|
68
|
+
function findCxProjectRoot() {
|
|
69
|
+
let dir = process.cwd();
|
|
70
|
+
while (dir !== path.dirname(dir)) {
|
|
71
|
+
if (fs.existsSync(path.join(dir, 'app.yaml')))
|
|
72
|
+
return dir;
|
|
73
|
+
dir = path.dirname(dir);
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
function checkSkillsInstalled(command) {
|
|
78
|
+
if (command === 'install-skills' || command === 'init')
|
|
79
|
+
return;
|
|
80
|
+
try {
|
|
81
|
+
const projectRoot = findCxProjectRoot();
|
|
82
|
+
if (!projectRoot)
|
|
83
|
+
return;
|
|
84
|
+
const missing = CX_SKILL_NAMES.filter(name => !fs.existsSync(path.join(projectRoot, '.claude', 'skills', name)));
|
|
85
|
+
if (missing.length === 0)
|
|
86
|
+
return;
|
|
87
|
+
console.error('');
|
|
88
|
+
console.error(chalk_1.default.yellow('╔═══════════════════════════════════════════════════════════╗'));
|
|
89
|
+
console.error(chalk_1.default.yellow('║ cxtms skills are not installed in this project. ║'));
|
|
90
|
+
console.error(chalk_1.default.yellow('╚═══════════════════════════════════════════════════════════╝'));
|
|
91
|
+
console.error(chalk_1.default.yellow(` Missing: ${missing.join(', ')}`));
|
|
92
|
+
console.error(chalk_1.default.cyan(' Install: ') + chalk_1.default.bold('npx cxtms install-skills'));
|
|
93
|
+
console.error('');
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Skills check must never break the CLI.
|
|
97
|
+
}
|
|
98
|
+
}
|
|
67
99
|
// ============================================================================
|
|
68
100
|
// .env loader — load KEY=VALUE pairs from .env in CWD into process.env
|
|
69
101
|
// ============================================================================
|
|
@@ -102,11 +134,11 @@ const PROGRAM_NAME = 'cxtms';
|
|
|
102
134
|
const HELP_TEXT = `
|
|
103
135
|
${chalk_1.default.bold.cyan('╔═══════════════════════════════════════════════════════════════════════════╗')}
|
|
104
136
|
${chalk_1.default.bold.cyan('║')} ${chalk_1.default.bold.white('CX SCHEMA VALIDATOR')} ${chalk_1.default.gray(`v${VERSION}`)} ${chalk_1.default.bold.cyan('║')}
|
|
105
|
-
${chalk_1.default.bold.cyan('║')} ${chalk_1.default.gray('Unified validation for
|
|
137
|
+
${chalk_1.default.bold.cyan('║')} ${chalk_1.default.gray('Unified validation for CXTMS YAML files')} ${chalk_1.default.bold.cyan('║')}
|
|
106
138
|
${chalk_1.default.bold.cyan('╚═══════════════════════════════════════════════════════════════════════════╝')}
|
|
107
139
|
|
|
108
140
|
${chalk_1.default.bold.yellow('DESCRIPTION:')}
|
|
109
|
-
Validates
|
|
141
|
+
Validates CXTMS YAML module and workflow files against JSON Schema
|
|
110
142
|
definitions. Provides detailed error feedback with examples and schema
|
|
111
143
|
references to help fix validation issues.
|
|
112
144
|
|
|
@@ -129,7 +161,7 @@ ${chalk_1.default.bold.yellow('COMMANDS:')}
|
|
|
129
161
|
${chalk_1.default.green('orgs')} List, select, or set active organization
|
|
130
162
|
${chalk_1.default.green('appmodule')} Manage app modules on a CX server (deploy, undeploy)
|
|
131
163
|
${chalk_1.default.green('workflow')} Manage workflows on a CX server (deploy, undeploy, execute, logs, log)
|
|
132
|
-
${chalk_1.default.green('
|
|
164
|
+
${chalk_1.default.green('deploy-all')} Deploy all modules and workflows to a CX server
|
|
133
165
|
${chalk_1.default.green('app')} Manage app manifests (install/upgrade from git, release to git, list)
|
|
134
166
|
${chalk_1.default.green('query')} Run a GraphQL query against the CX server
|
|
135
167
|
${chalk_1.default.green('gql')} Explore GraphQL schema (types, queries, mutations)
|
|
@@ -163,9 +195,9 @@ ${chalk_1.default.bold.yellow('OPTIONS:')}
|
|
|
163
195
|
${chalk_1.default.green('--console')} Print workflow log to stdout
|
|
164
196
|
${chalk_1.default.green('--json')} Download JSON log instead of text
|
|
165
197
|
${chalk_1.default.green('-m, --message <msg>')} Release message for app release (required)
|
|
166
|
-
${chalk_1.default.green('-b, --branch <branch>')} Branch override for app install/
|
|
167
|
-
${chalk_1.default.green('--force')} Force install (even if same version) or
|
|
168
|
-
${chalk_1.default.green('--skip-changed')} Skip modules with
|
|
198
|
+
${chalk_1.default.green('-b, --branch <branch>')} Branch override for app install/release
|
|
199
|
+
${chalk_1.default.green('--force')} Force install (even if same version) or release all
|
|
200
|
+
${chalk_1.default.green('--skip-changed')} Skip modules with unreleased changes during install
|
|
169
201
|
|
|
170
202
|
${chalk_1.default.bold.yellow('VALIDATION EXAMPLES:')}
|
|
171
203
|
${chalk_1.default.gray('# Validate a module YAML file')}
|
|
@@ -296,16 +328,16 @@ ${chalk_1.default.bold.yellow('WORKFLOW COMMANDS:')}
|
|
|
296
328
|
${chalk_1.default.cyan(`${PROGRAM_NAME} workflow log <executionId> --json`)} ${chalk_1.default.gray('# download JSON log (more detail)')}
|
|
297
329
|
${chalk_1.default.cyan(`${PROGRAM_NAME} workflow log <executionId> --json --console`)} ${chalk_1.default.gray('# JSON log to stdout')}
|
|
298
330
|
|
|
299
|
-
${chalk_1.default.bold.yellow('
|
|
300
|
-
${chalk_1.default.gray('#
|
|
301
|
-
${chalk_1.default.cyan(`${PROGRAM_NAME}
|
|
331
|
+
${chalk_1.default.bold.yellow('DEPLOY-ALL COMMANDS:')}
|
|
332
|
+
${chalk_1.default.gray('# Deploy all modules and workflows from current project to the CX server')}
|
|
333
|
+
${chalk_1.default.cyan(`${PROGRAM_NAME} deploy-all`)}
|
|
302
334
|
|
|
303
|
-
${chalk_1.default.gray('#
|
|
304
|
-
${chalk_1.default.cyan(`${PROGRAM_NAME}
|
|
305
|
-
${chalk_1.default.cyan(`${PROGRAM_NAME}
|
|
335
|
+
${chalk_1.default.gray('# Deploy only a specific feature directory')}
|
|
336
|
+
${chalk_1.default.cyan(`${PROGRAM_NAME} deploy-all --feature billing`)}
|
|
337
|
+
${chalk_1.default.cyan(`${PROGRAM_NAME} deploy-all billing`)}
|
|
306
338
|
|
|
307
|
-
${chalk_1.default.gray('#
|
|
308
|
-
${chalk_1.default.cyan(`${PROGRAM_NAME}
|
|
339
|
+
${chalk_1.default.gray('# Deploy with explicit org ID')}
|
|
340
|
+
${chalk_1.default.cyan(`${PROGRAM_NAME} deploy-all --org 42`)}
|
|
309
341
|
|
|
310
342
|
${chalk_1.default.bold.yellow('APP COMMANDS:')}
|
|
311
343
|
${chalk_1.default.gray('# Install/refresh app from git repository into the CX server')}
|
|
@@ -332,7 +364,7 @@ ${chalk_1.default.bold.yellow('APP COMMANDS:')}
|
|
|
332
364
|
${chalk_1.default.cyan(`${PROGRAM_NAME} app release -m "Update billing" workflows/a.yaml modules/b.yaml`)}
|
|
333
365
|
|
|
334
366
|
${chalk_1.default.gray('# Force release all modules and workflows')}
|
|
335
|
-
${chalk_1.default.cyan(`${PROGRAM_NAME} app release -m "Full
|
|
367
|
+
${chalk_1.default.cyan(`${PROGRAM_NAME} app release -m "Full re-release" --force`)}
|
|
336
368
|
|
|
337
369
|
${chalk_1.default.gray('# List installed app manifests on the server')}
|
|
338
370
|
${chalk_1.default.cyan(`${PROGRAM_NAME} app list`)}
|
|
@@ -362,8 +394,8 @@ ${chalk_1.default.bold.yellow('GRAPHQL SCHEMA EXPLORATION:')}
|
|
|
362
394
|
${chalk_1.default.cyan(`${PROGRAM_NAME} gql type AuditChangeEntry`)}
|
|
363
395
|
|
|
364
396
|
${chalk_1.default.bold.yellow('VALIDATION TYPES:')}
|
|
365
|
-
${chalk_1.default.bold('module')} -
|
|
366
|
-
${chalk_1.default.bold('workflow')} -
|
|
397
|
+
${chalk_1.default.bold('module')} - CXTMS UI module definitions (components, routes, entities)
|
|
398
|
+
${chalk_1.default.bold('workflow')} - CXTMS workflow definitions (activities, tasks, triggers)
|
|
367
399
|
${chalk_1.default.bold('auto')} - Auto-detect based on file content (checks for 'workflow:' vs 'module:')
|
|
368
400
|
|
|
369
401
|
${chalk_1.default.bold.yellow('OUTPUT FORMATS:')}
|
|
@@ -534,9 +566,9 @@ repository: ""
|
|
|
534
566
|
`;
|
|
535
567
|
}
|
|
536
568
|
function generateReadme() {
|
|
537
|
-
return `#
|
|
569
|
+
return `# CXTMS Application
|
|
538
570
|
|
|
539
|
-
This project contains
|
|
571
|
+
This project contains CXTMS modules and workflows.
|
|
540
572
|
|
|
541
573
|
## Project Structure
|
|
542
574
|
|
|
@@ -603,15 +635,15 @@ npx cxtms example workflow
|
|
|
603
635
|
|
|
604
636
|
## Documentation
|
|
605
637
|
|
|
606
|
-
- [CX Schema CLI Documentation](https://
|
|
607
|
-
- [Module Development Guide](https://
|
|
608
|
-
- [Workflow Development Guide](https://
|
|
638
|
+
- [CX Schema CLI Documentation](https://cxtms.com/docs/documents/cx-schema-cli)
|
|
639
|
+
- [Module Development Guide](https://cxtms.com/docs/development/app-modules)
|
|
640
|
+
- [Workflow Development Guide](https://cxtms.com/docs/development/workflows)
|
|
609
641
|
`;
|
|
610
642
|
}
|
|
611
643
|
function generateAgentsMd() {
|
|
612
|
-
return `# AI Assistant Instructions for
|
|
644
|
+
return `# AI Assistant Instructions for CXTMS Development
|
|
613
645
|
|
|
614
|
-
This file provides instructions for AI assistants (like Claude, GPT, Copilot) when working with this
|
|
646
|
+
This file provides instructions for AI assistants (like Claude, GPT, Copilot) when working with this CXTMS project.
|
|
615
647
|
|
|
616
648
|
## Validation Commands
|
|
617
649
|
|
|
@@ -1490,9 +1522,9 @@ function runUpdate() {
|
|
|
1490
1522
|
const CX_CLAUDE_MARKER = '<!-- cx-schema-instructions -->';
|
|
1491
1523
|
function generateClaudeMdContent() {
|
|
1492
1524
|
return `${CX_CLAUDE_MARKER}
|
|
1493
|
-
##
|
|
1525
|
+
## CXTMS Project
|
|
1494
1526
|
|
|
1495
|
-
This is a
|
|
1527
|
+
This is a CXTMS (CX) application. Modules and workflows are defined as YAML files validated against JSON schemas provided by \`@cxtms/cx-schema\`.
|
|
1496
1528
|
|
|
1497
1529
|
### Project Structure
|
|
1498
1530
|
|
|
@@ -2847,7 +2879,7 @@ async function runPatSetup() {
|
|
|
2847
2879
|
console.log(chalk_1.default.gray(' Or set `server` in app.yaml instead of CXTMS_SERVER.'));
|
|
2848
2880
|
}
|
|
2849
2881
|
}
|
|
2850
|
-
async function
|
|
2882
|
+
async function runDeployAll(featureDir, orgOverride) {
|
|
2851
2883
|
const session = resolveSession();
|
|
2852
2884
|
const domain = session.domain;
|
|
2853
2885
|
const token = session.access_token;
|
|
@@ -2861,7 +2893,7 @@ async function runPublish(featureDir, orgOverride) {
|
|
|
2861
2893
|
const appYaml = yaml_1.default.parse(fs.readFileSync(appYamlPath, 'utf-8'));
|
|
2862
2894
|
const appManifestId = appYaml?.id;
|
|
2863
2895
|
const appName = appYaml?.name || 'unknown';
|
|
2864
|
-
console.log(chalk_1.default.bold.cyan('\n
|
|
2896
|
+
console.log(chalk_1.default.bold.cyan('\n Deploy All\n'));
|
|
2865
2897
|
console.log(chalk_1.default.gray(` Server: ${new URL(domain).hostname}`));
|
|
2866
2898
|
console.log(chalk_1.default.gray(` Org: ${orgId}`));
|
|
2867
2899
|
console.log(chalk_1.default.gray(` App: ${appName}`));
|
|
@@ -2871,7 +2903,7 @@ async function runPublish(featureDir, orgOverride) {
|
|
|
2871
2903
|
console.log('');
|
|
2872
2904
|
// Step 1: Create or update app manifest
|
|
2873
2905
|
if (appManifestId) {
|
|
2874
|
-
console.log(chalk_1.default.gray('
|
|
2906
|
+
console.log(chalk_1.default.gray(' Deploying app manifest...'));
|
|
2875
2907
|
try {
|
|
2876
2908
|
const checkData = await graphqlRequest(domain, token, `
|
|
2877
2909
|
query ($organizationId: Int!, $appManifestId: UUID!) {
|
|
@@ -2960,14 +2992,14 @@ async function runPublish(featureDir, orgOverride) {
|
|
|
2960
2992
|
// Summary
|
|
2961
2993
|
console.log('');
|
|
2962
2994
|
if (failed === 0) {
|
|
2963
|
-
console.log(chalk_1.default.green(` ✓
|
|
2995
|
+
console.log(chalk_1.default.green(` ✓ Deployed ${succeeded} file(s) successfully\n`));
|
|
2964
2996
|
}
|
|
2965
2997
|
else {
|
|
2966
|
-
console.log(chalk_1.default.yellow(`
|
|
2998
|
+
console.log(chalk_1.default.yellow(` Deployed ${succeeded} file(s), ${failed} failed\n`));
|
|
2967
2999
|
}
|
|
2968
3000
|
}
|
|
2969
3001
|
// ============================================================================
|
|
2970
|
-
// App Manifest Commands (install from git,
|
|
3002
|
+
// App Manifest Commands (install from git, release to git, list)
|
|
2971
3003
|
// ============================================================================
|
|
2972
3004
|
function readAppYaml() {
|
|
2973
3005
|
const appYamlPath = path.join(process.cwd(), 'app.yaml');
|
|
@@ -3028,7 +3060,7 @@ async function runAppInstall(orgOverride, branch, force, skipChanged) {
|
|
|
3028
3060
|
if (manifest) {
|
|
3029
3061
|
console.log(chalk_1.default.green(` ✓ Installed ${manifest.name} v${manifest.currentVersion}`));
|
|
3030
3062
|
if (manifest.hasUnpublishedChanges) {
|
|
3031
|
-
console.log(chalk_1.default.yellow(` Has
|
|
3063
|
+
console.log(chalk_1.default.yellow(` Has unreleased changes`));
|
|
3032
3064
|
}
|
|
3033
3065
|
}
|
|
3034
3066
|
else {
|
|
@@ -3041,7 +3073,7 @@ async function runAppInstall(orgOverride, branch, force, skipChanged) {
|
|
|
3041
3073
|
}
|
|
3042
3074
|
console.log('');
|
|
3043
3075
|
}
|
|
3044
|
-
async function
|
|
3076
|
+
async function runAppRelease(orgOverride, message, branch, force, targetFiles) {
|
|
3045
3077
|
const session = resolveSession();
|
|
3046
3078
|
const domain = session.domain;
|
|
3047
3079
|
const token = session.access_token;
|
|
@@ -3094,15 +3126,15 @@ async function runAppPublish(orgOverride, message, branch, force, targetFiles) {
|
|
|
3094
3126
|
}
|
|
3095
3127
|
console.log('');
|
|
3096
3128
|
try {
|
|
3097
|
-
const
|
|
3129
|
+
const releaseValues = {
|
|
3098
3130
|
message: message || undefined,
|
|
3099
3131
|
branch: branch || undefined,
|
|
3100
3132
|
force: force || false,
|
|
3101
3133
|
};
|
|
3102
3134
|
if (workflowIds.length > 0)
|
|
3103
|
-
|
|
3135
|
+
releaseValues.workflowIds = workflowIds;
|
|
3104
3136
|
if (moduleIds.length > 0)
|
|
3105
|
-
|
|
3137
|
+
releaseValues.moduleIds = moduleIds;
|
|
3106
3138
|
const data = await graphqlRequest(domain, token, `
|
|
3107
3139
|
mutation ($input: PublishAppManifestInput!) {
|
|
3108
3140
|
publishAppManifest(input: $input) {
|
|
@@ -3118,19 +3150,19 @@ async function runAppPublish(orgOverride, message, branch, force, targetFiles) {
|
|
|
3118
3150
|
input: {
|
|
3119
3151
|
organizationId: orgId,
|
|
3120
3152
|
appManifestId,
|
|
3121
|
-
values:
|
|
3153
|
+
values: releaseValues,
|
|
3122
3154
|
}
|
|
3123
3155
|
});
|
|
3124
3156
|
const manifest = data?.publishAppManifest?.appManifest;
|
|
3125
3157
|
if (manifest) {
|
|
3126
|
-
console.log(chalk_1.default.green(` ✓
|
|
3158
|
+
console.log(chalk_1.default.green(` ✓ Released ${manifest.name} v${manifest.currentVersion}`));
|
|
3127
3159
|
}
|
|
3128
3160
|
else {
|
|
3129
|
-
console.log(chalk_1.default.green(' ✓
|
|
3161
|
+
console.log(chalk_1.default.green(' ✓ Release completed'));
|
|
3130
3162
|
}
|
|
3131
3163
|
}
|
|
3132
3164
|
catch (e) {
|
|
3133
|
-
console.error(chalk_1.default.red(` ✗
|
|
3165
|
+
console.error(chalk_1.default.red(` ✗ Release failed: ${e.message}`));
|
|
3134
3166
|
process.exit(1);
|
|
3135
3167
|
}
|
|
3136
3168
|
console.log('');
|
|
@@ -3170,7 +3202,7 @@ async function runAppList(orgOverride) {
|
|
|
3170
3202
|
if (!app.isEnabled)
|
|
3171
3203
|
flags.push(chalk_1.default.red('disabled'));
|
|
3172
3204
|
if (app.hasUnpublishedChanges)
|
|
3173
|
-
flags.push(chalk_1.default.yellow('
|
|
3205
|
+
flags.push(chalk_1.default.yellow('unreleased'));
|
|
3174
3206
|
if (app.isUpdateAvailable)
|
|
3175
3207
|
flags.push(chalk_1.default.cyan('update available'));
|
|
3176
3208
|
const flagStr = flags.length > 0 ? ` [${flags.join(', ')}]` : '';
|
|
@@ -3596,7 +3628,7 @@ function parseArgs(args) {
|
|
|
3596
3628
|
reportFormat: 'json'
|
|
3597
3629
|
};
|
|
3598
3630
|
// Check for commands
|
|
3599
|
-
const commands = ['validate', 'schema', 'example', 'list', 'help', 'version', 'report', 'init', 'create', 'extract', 'sync-schemas', 'install-skills', 'update', 'setup-claude', 'login', 'logout', 'pat', 'appmodule', 'orgs', 'workflow', '
|
|
3631
|
+
const commands = ['validate', 'schema', 'example', 'list', 'help', 'version', 'report', 'init', 'create', 'extract', 'sync-schemas', 'install-skills', 'update', 'setup-claude', 'login', 'logout', 'pat', 'appmodule', 'orgs', 'workflow', 'deploy-all', 'query', 'gql', 'app'];
|
|
3600
3632
|
if (args.length > 0 && commands.includes(args[0])) {
|
|
3601
3633
|
command = args[0];
|
|
3602
3634
|
args = args.slice(1);
|
|
@@ -4479,6 +4511,7 @@ async function main() {
|
|
|
4479
4511
|
checkForUpdates();
|
|
4480
4512
|
const args = process.argv.slice(2);
|
|
4481
4513
|
const { command, files, options } = parseArgs(args);
|
|
4514
|
+
checkSkillsInstalled(command);
|
|
4482
4515
|
// Handle help
|
|
4483
4516
|
if (options.help) {
|
|
4484
4517
|
if (command === 'schema') {
|
|
@@ -4613,9 +4646,9 @@ async function main() {
|
|
|
4613
4646
|
}
|
|
4614
4647
|
process.exit(0);
|
|
4615
4648
|
}
|
|
4616
|
-
// Handle
|
|
4617
|
-
if (command === '
|
|
4618
|
-
await
|
|
4649
|
+
// Handle deploy-all command (no schemas needed)
|
|
4650
|
+
if (command === 'deploy-all') {
|
|
4651
|
+
await runDeployAll(files[0] || options.feature, options.orgId);
|
|
4619
4652
|
process.exit(0);
|
|
4620
4653
|
}
|
|
4621
4654
|
// Handle app command (no schemas needed)
|
|
@@ -4624,8 +4657,8 @@ async function main() {
|
|
|
4624
4657
|
if (sub === 'install' || sub === 'upgrade') {
|
|
4625
4658
|
await runAppInstall(options.orgId, options.branch, options.force, options.skipChanged);
|
|
4626
4659
|
}
|
|
4627
|
-
else if (sub === 'release'
|
|
4628
|
-
await
|
|
4660
|
+
else if (sub === 'release') {
|
|
4661
|
+
await runAppRelease(options.orgId, options.message, options.branch, options.force, files.slice(1));
|
|
4629
4662
|
}
|
|
4630
4663
|
else if (sub === 'list' || !sub) {
|
|
4631
4664
|
await runAppList(options.orgId);
|