@cxtms/cx-schema 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 CHANGED
@@ -5,7 +5,7 @@
5
5
  [![Build Status](https://github.com/cargoxplorer/cx-schema/workflows/Publish%20to%20npm/badge.svg)](https://github.com/cargoxplorer/cx-schema/actions)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
7
7
 
8
- Schema validation package for CargoXplorer YAML modules and workflows. This package provides comprehensive validation for YAML-based configurations used in the CargoXplorer Transportation Management System (TMS).
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 CargoXplorer YAML files')} ${chalk_1.default.bold.cyan('║')}
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 CargoXplorer YAML module and workflow files against JSON Schema
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('publish')} Publish all modules and workflows to a CX server
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/publish
167
- ${chalk_1.default.green('--force')} Force install (even if same version) or publish all
168
- ${chalk_1.default.green('--skip-changed')} Skip modules with unpublished changes during install
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('PUBLISH COMMANDS:')}
300
- ${chalk_1.default.gray('# Publish all modules and workflows from current project')}
301
- ${chalk_1.default.cyan(`${PROGRAM_NAME} publish`)}
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('# Publish only a specific feature directory')}
304
- ${chalk_1.default.cyan(`${PROGRAM_NAME} publish --feature billing`)}
305
- ${chalk_1.default.cyan(`${PROGRAM_NAME} publish billing`)}
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('# Publish with explicit org ID')}
308
- ${chalk_1.default.cyan(`${PROGRAM_NAME} publish --org 42`)}
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 republish" --force`)}
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')} - CargoXplorer UI module definitions (components, routes, entities)
366
- ${chalk_1.default.bold('workflow')} - CargoXplorer workflow definitions (activities, tasks, triggers)
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 `# CargoXplorer Application
569
+ return `# CXTMS Application
538
570
 
539
- This project contains CargoXplorer modules and workflows.
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://docs.cargoxplorer.com/docs/documents/cx-schema-cli)
607
- - [Module Development Guide](https://docs.cargoxplorer.com/docs/development/app-modules)
608
- - [Workflow Development Guide](https://docs.cargoxplorer.com/docs/development/workflows)
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 CargoXplorer Development
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 CargoXplorer project.
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
- ## CargoXplorer Project
1525
+ ## CXTMS Project
1494
1526
 
1495
- This is a CargoXplorer (CX) application. Modules and workflows are defined as YAML files validated against JSON schemas provided by \`@cxtms/cx-schema\`.
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 runPublish(featureDir, orgOverride) {
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 Publish\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(' Publishing app manifest...'));
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(` ✓ Published ${succeeded} file(s) successfully\n`));
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(` Published ${succeeded} file(s), ${failed} failed\n`));
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, publish to git, list)
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 unpublished changes`));
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 runAppPublish(orgOverride, message, branch, force, targetFiles) {
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 publishValues = {
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
- publishValues.workflowIds = workflowIds;
3135
+ releaseValues.workflowIds = workflowIds;
3104
3136
  if (moduleIds.length > 0)
3105
- publishValues.moduleIds = moduleIds;
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: publishValues,
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(` ✓ Published ${manifest.name} v${manifest.currentVersion}`));
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(' ✓ Publish completed'));
3161
+ console.log(chalk_1.default.green(' ✓ Release completed'));
3130
3162
  }
3131
3163
  }
3132
3164
  catch (e) {
3133
- console.error(chalk_1.default.red(` ✗ Publish failed: ${e.message}`));
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('unpublished'));
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', 'publish', 'query', 'gql', 'app'];
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 publish command (no schemas needed)
4617
- if (command === 'publish') {
4618
- await runPublish(files[0] || options.feature, options.orgId);
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' || sub === 'publish') {
4628
- await runAppPublish(options.orgId, options.message, options.branch, options.force, files.slice(1));
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);