cxtms 1.9.15 → 1.9.21

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
@@ -47,10 +47,55 @@ const https = __importStar(require("https"));
47
47
  const crypto = __importStar(require("crypto"));
48
48
  const os = __importStar(require("os"));
49
49
  const chalk_1 = __importDefault(require("chalk"));
50
+ const update_notifier_1 = __importDefault(require("update-notifier"));
50
51
  const yaml_1 = __importStar(require("yaml"));
51
52
  const validator_1 = require("./validator");
52
53
  const workflowValidator_1 = require("./workflowValidator");
53
54
  const extractUtils_1 = require("./extractUtils");
55
+ const pkg = require('../package.json');
56
+ function checkForUpdates() {
57
+ try {
58
+ (0, update_notifier_1.default)({
59
+ pkg,
60
+ updateCheckInterval: 1000 * 60 * 60 * 24,
61
+ }).notify({ isGlobal: true });
62
+ }
63
+ catch {
64
+ // Update check must never break the CLI.
65
+ }
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
+ }
54
99
  // ============================================================================
55
100
  // .env loader — load KEY=VALUE pairs from .env in CWD into process.env
56
101
  // ============================================================================
@@ -89,11 +134,11 @@ const PROGRAM_NAME = 'cxtms';
89
134
  const HELP_TEXT = `
90
135
  ${chalk_1.default.bold.cyan('╔═══════════════════════════════════════════════════════════════════════════╗')}
91
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('║')}
92
- ${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('║')}
93
138
  ${chalk_1.default.bold.cyan('╚═══════════════════════════════════════════════════════════════════════════╝')}
94
139
 
95
140
  ${chalk_1.default.bold.yellow('DESCRIPTION:')}
96
- Validates CargoXplorer YAML module and workflow files against JSON Schema
141
+ Validates CXTMS YAML module and workflow files against JSON Schema
97
142
  definitions. Provides detailed error feedback with examples and schema
98
143
  references to help fix validation issues.
99
144
 
@@ -116,7 +161,7 @@ ${chalk_1.default.bold.yellow('COMMANDS:')}
116
161
  ${chalk_1.default.green('orgs')} List, select, or set active organization
117
162
  ${chalk_1.default.green('appmodule')} Manage app modules on a CX server (deploy, undeploy)
118
163
  ${chalk_1.default.green('workflow')} Manage workflows on a CX server (deploy, undeploy, execute, logs, log)
119
- ${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
120
165
  ${chalk_1.default.green('app')} Manage app manifests (install/upgrade from git, release to git, list)
121
166
  ${chalk_1.default.green('query')} Run a GraphQL query against the CX server
122
167
  ${chalk_1.default.green('gql')} Explore GraphQL schema (types, queries, mutations)
@@ -150,9 +195,9 @@ ${chalk_1.default.bold.yellow('OPTIONS:')}
150
195
  ${chalk_1.default.green('--console')} Print workflow log to stdout
151
196
  ${chalk_1.default.green('--json')} Download JSON log instead of text
152
197
  ${chalk_1.default.green('-m, --message <msg>')} Release message for app release (required)
153
- ${chalk_1.default.green('-b, --branch <branch>')} Branch override for app install/publish
154
- ${chalk_1.default.green('--force')} Force install (even if same version) or publish all
155
- ${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
156
201
 
157
202
  ${chalk_1.default.bold.yellow('VALIDATION EXAMPLES:')}
158
203
  ${chalk_1.default.gray('# Validate a module YAML file')}
@@ -283,16 +328,16 @@ ${chalk_1.default.bold.yellow('WORKFLOW COMMANDS:')}
283
328
  ${chalk_1.default.cyan(`${PROGRAM_NAME} workflow log <executionId> --json`)} ${chalk_1.default.gray('# download JSON log (more detail)')}
284
329
  ${chalk_1.default.cyan(`${PROGRAM_NAME} workflow log <executionId> --json --console`)} ${chalk_1.default.gray('# JSON log to stdout')}
285
330
 
286
- ${chalk_1.default.bold.yellow('PUBLISH COMMANDS:')}
287
- ${chalk_1.default.gray('# Publish all modules and workflows from current project')}
288
- ${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`)}
289
334
 
290
- ${chalk_1.default.gray('# Publish only a specific feature directory')}
291
- ${chalk_1.default.cyan(`${PROGRAM_NAME} publish --feature billing`)}
292
- ${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`)}
293
338
 
294
- ${chalk_1.default.gray('# Publish with explicit org ID')}
295
- ${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`)}
296
341
 
297
342
  ${chalk_1.default.bold.yellow('APP COMMANDS:')}
298
343
  ${chalk_1.default.gray('# Install/refresh app from git repository into the CX server')}
@@ -319,7 +364,7 @@ ${chalk_1.default.bold.yellow('APP COMMANDS:')}
319
364
  ${chalk_1.default.cyan(`${PROGRAM_NAME} app release -m "Update billing" workflows/a.yaml modules/b.yaml`)}
320
365
 
321
366
  ${chalk_1.default.gray('# Force release all modules and workflows')}
322
- ${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`)}
323
368
 
324
369
  ${chalk_1.default.gray('# List installed app manifests on the server')}
325
370
  ${chalk_1.default.cyan(`${PROGRAM_NAME} app list`)}
@@ -349,8 +394,8 @@ ${chalk_1.default.bold.yellow('GRAPHQL SCHEMA EXPLORATION:')}
349
394
  ${chalk_1.default.cyan(`${PROGRAM_NAME} gql type AuditChangeEntry`)}
350
395
 
351
396
  ${chalk_1.default.bold.yellow('VALIDATION TYPES:')}
352
- ${chalk_1.default.bold('module')} - CargoXplorer UI module definitions (components, routes, entities)
353
- ${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)
354
399
  ${chalk_1.default.bold('auto')} - Auto-detect based on file content (checks for 'workflow:' vs 'module:')
355
400
 
356
401
  ${chalk_1.default.bold.yellow('OUTPUT FORMATS:')}
@@ -521,9 +566,9 @@ repository: ""
521
566
  `;
522
567
  }
523
568
  function generateReadme() {
524
- return `# CargoXplorer Application
569
+ return `# CXTMS Application
525
570
 
526
- This project contains CargoXplorer modules and workflows.
571
+ This project contains CXTMS modules and workflows.
527
572
 
528
573
  ## Project Structure
529
574
 
@@ -590,15 +635,15 @@ npx cxtms example workflow
590
635
 
591
636
  ## Documentation
592
637
 
593
- - [CX Schema CLI Documentation](https://docs.cargoxplorer.com/docs/documents/cx-schema-cli)
594
- - [Module Development Guide](https://docs.cargoxplorer.com/docs/development/app-modules)
595
- - [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)
596
641
  `;
597
642
  }
598
643
  function generateAgentsMd() {
599
- return `# AI Assistant Instructions for CargoXplorer Development
644
+ return `# AI Assistant Instructions for CXTMS Development
600
645
 
601
- 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.
602
647
 
603
648
  ## Validation Commands
604
649
 
@@ -1477,9 +1522,9 @@ function runUpdate() {
1477
1522
  const CX_CLAUDE_MARKER = '<!-- cx-schema-instructions -->';
1478
1523
  function generateClaudeMdContent() {
1479
1524
  return `${CX_CLAUDE_MARKER}
1480
- ## CargoXplorer Project
1525
+ ## CXTMS Project
1481
1526
 
1482
- 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\`.
1483
1528
 
1484
1529
  ### Project Structure
1485
1530
 
@@ -2834,7 +2879,7 @@ async function runPatSetup() {
2834
2879
  console.log(chalk_1.default.gray(' Or set `server` in app.yaml instead of CXTMS_SERVER.'));
2835
2880
  }
2836
2881
  }
2837
- async function runPublish(featureDir, orgOverride) {
2882
+ async function runDeployAll(featureDir, orgOverride) {
2838
2883
  const session = resolveSession();
2839
2884
  const domain = session.domain;
2840
2885
  const token = session.access_token;
@@ -2848,7 +2893,7 @@ async function runPublish(featureDir, orgOverride) {
2848
2893
  const appYaml = yaml_1.default.parse(fs.readFileSync(appYamlPath, 'utf-8'));
2849
2894
  const appManifestId = appYaml?.id;
2850
2895
  const appName = appYaml?.name || 'unknown';
2851
- console.log(chalk_1.default.bold.cyan('\n Publish\n'));
2896
+ console.log(chalk_1.default.bold.cyan('\n Deploy All\n'));
2852
2897
  console.log(chalk_1.default.gray(` Server: ${new URL(domain).hostname}`));
2853
2898
  console.log(chalk_1.default.gray(` Org: ${orgId}`));
2854
2899
  console.log(chalk_1.default.gray(` App: ${appName}`));
@@ -2858,7 +2903,7 @@ async function runPublish(featureDir, orgOverride) {
2858
2903
  console.log('');
2859
2904
  // Step 1: Create or update app manifest
2860
2905
  if (appManifestId) {
2861
- console.log(chalk_1.default.gray(' Publishing app manifest...'));
2906
+ console.log(chalk_1.default.gray(' Deploying app manifest...'));
2862
2907
  try {
2863
2908
  const checkData = await graphqlRequest(domain, token, `
2864
2909
  query ($organizationId: Int!, $appManifestId: UUID!) {
@@ -2947,14 +2992,14 @@ async function runPublish(featureDir, orgOverride) {
2947
2992
  // Summary
2948
2993
  console.log('');
2949
2994
  if (failed === 0) {
2950
- 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`));
2951
2996
  }
2952
2997
  else {
2953
- 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`));
2954
2999
  }
2955
3000
  }
2956
3001
  // ============================================================================
2957
- // App Manifest Commands (install from git, publish to git, list)
3002
+ // App Manifest Commands (install from git, release to git, list)
2958
3003
  // ============================================================================
2959
3004
  function readAppYaml() {
2960
3005
  const appYamlPath = path.join(process.cwd(), 'app.yaml');
@@ -3015,7 +3060,7 @@ async function runAppInstall(orgOverride, branch, force, skipChanged) {
3015
3060
  if (manifest) {
3016
3061
  console.log(chalk_1.default.green(` ✓ Installed ${manifest.name} v${manifest.currentVersion}`));
3017
3062
  if (manifest.hasUnpublishedChanges) {
3018
- console.log(chalk_1.default.yellow(` Has unpublished changes`));
3063
+ console.log(chalk_1.default.yellow(` Has unreleased changes`));
3019
3064
  }
3020
3065
  }
3021
3066
  else {
@@ -3028,7 +3073,7 @@ async function runAppInstall(orgOverride, branch, force, skipChanged) {
3028
3073
  }
3029
3074
  console.log('');
3030
3075
  }
3031
- async function runAppPublish(orgOverride, message, branch, force, targetFiles) {
3076
+ async function runAppRelease(orgOverride, message, branch, force, targetFiles) {
3032
3077
  const session = resolveSession();
3033
3078
  const domain = session.domain;
3034
3079
  const token = session.access_token;
@@ -3081,15 +3126,15 @@ async function runAppPublish(orgOverride, message, branch, force, targetFiles) {
3081
3126
  }
3082
3127
  console.log('');
3083
3128
  try {
3084
- const publishValues = {
3129
+ const releaseValues = {
3085
3130
  message: message || undefined,
3086
3131
  branch: branch || undefined,
3087
3132
  force: force || false,
3088
3133
  };
3089
3134
  if (workflowIds.length > 0)
3090
- publishValues.workflowIds = workflowIds;
3135
+ releaseValues.workflowIds = workflowIds;
3091
3136
  if (moduleIds.length > 0)
3092
- publishValues.moduleIds = moduleIds;
3137
+ releaseValues.moduleIds = moduleIds;
3093
3138
  const data = await graphqlRequest(domain, token, `
3094
3139
  mutation ($input: PublishAppManifestInput!) {
3095
3140
  publishAppManifest(input: $input) {
@@ -3105,19 +3150,19 @@ async function runAppPublish(orgOverride, message, branch, force, targetFiles) {
3105
3150
  input: {
3106
3151
  organizationId: orgId,
3107
3152
  appManifestId,
3108
- values: publishValues,
3153
+ values: releaseValues,
3109
3154
  }
3110
3155
  });
3111
3156
  const manifest = data?.publishAppManifest?.appManifest;
3112
3157
  if (manifest) {
3113
- 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}`));
3114
3159
  }
3115
3160
  else {
3116
- console.log(chalk_1.default.green(' ✓ Publish completed'));
3161
+ console.log(chalk_1.default.green(' ✓ Release completed'));
3117
3162
  }
3118
3163
  }
3119
3164
  catch (e) {
3120
- console.error(chalk_1.default.red(` ✗ Publish failed: ${e.message}`));
3165
+ console.error(chalk_1.default.red(` ✗ Release failed: ${e.message}`));
3121
3166
  process.exit(1);
3122
3167
  }
3123
3168
  console.log('');
@@ -3157,7 +3202,7 @@ async function runAppList(orgOverride) {
3157
3202
  if (!app.isEnabled)
3158
3203
  flags.push(chalk_1.default.red('disabled'));
3159
3204
  if (app.hasUnpublishedChanges)
3160
- flags.push(chalk_1.default.yellow('unpublished'));
3205
+ flags.push(chalk_1.default.yellow('unreleased'));
3161
3206
  if (app.isUpdateAvailable)
3162
3207
  flags.push(chalk_1.default.cyan('update available'));
3163
3208
  const flagStr = flags.length > 0 ? ` [${flags.join(', ')}]` : '';
@@ -3583,7 +3628,7 @@ function parseArgs(args) {
3583
3628
  reportFormat: 'json'
3584
3629
  };
3585
3630
  // Check for commands
3586
- 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'];
3587
3632
  if (args.length > 0 && commands.includes(args[0])) {
3588
3633
  command = args[0];
3589
3634
  args = args.slice(1);
@@ -4463,8 +4508,10 @@ async function validateFile(filePath, options, schemasPath) {
4463
4508
  // Main
4464
4509
  // ============================================================================
4465
4510
  async function main() {
4511
+ checkForUpdates();
4466
4512
  const args = process.argv.slice(2);
4467
4513
  const { command, files, options } = parseArgs(args);
4514
+ checkSkillsInstalled(command);
4468
4515
  // Handle help
4469
4516
  if (options.help) {
4470
4517
  if (command === 'schema') {
@@ -4599,9 +4646,9 @@ async function main() {
4599
4646
  }
4600
4647
  process.exit(0);
4601
4648
  }
4602
- // Handle publish command (no schemas needed)
4603
- if (command === 'publish') {
4604
- 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);
4605
4652
  process.exit(0);
4606
4653
  }
4607
4654
  // Handle app command (no schemas needed)
@@ -4610,8 +4657,8 @@ async function main() {
4610
4657
  if (sub === 'install' || sub === 'upgrade') {
4611
4658
  await runAppInstall(options.orgId, options.branch, options.force, options.skipChanged);
4612
4659
  }
4613
- else if (sub === 'release' || sub === 'publish') {
4614
- 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));
4615
4662
  }
4616
4663
  else if (sub === 'list' || !sub) {
4617
4664
  await runAppList(options.orgId);