Cross-platform modern workflow management tool.
A command-line interface (CLI) tool for managing vNext workflows, tasks, schemas, views, functions, extensions, and mappings. This tool helps you synchronize your local workflow definitions with the vNext API and database.
Package: @burgan-tech/vnext-workflow-cli
NPM: https://www.npmjs.com/package/@burgan-tech/vnext-workflow-cli
GitHub: https://github.com/burgan-tech/vnext-workflow-cli
# Install globally
npm install -g @burgan-tech/vnext-workflow-cli
# Or install as a project dependency
npm install @burgan-tech/vnext-workflow-cliAfter installation, you can use the CLI with any of these aliases:
wf --version # short alias
vnext --version # alternative alias (recommended for Windows)
workflow --version # full name# Clone the repository
git clone https://github.com/burgan-tech/vnext-workflow-cli.git
cd vnext-workflow-cli
# Install dependencies
npm install
# Link globally (for development)
npm link- Node.js >= 14.0.0
- npm or yarn
- PostgreSQL (for database operations)
- Docker (optional, for PostgreSQL container)
Every vNext workspace must have at least one solution file in the project root. The default solution file is vnext.config.json; a workspace that hosts several domains adds one vnext.{domain}.config.json per extra domain (see Multiple solutions in one workspace). A solution file defines the domain and component paths.
{
"version": "1.0.0",
"domain": "core",
"paths": {
"componentsRoot": "core",
"tasks": "Tasks",
"views": "Views",
"functions": "Functions",
"extensions": "Extensions",
"workflows": "Workflows",
"schemas": "Schemas",
"mappings": "Mappings"
}
}| Property | Description |
|---|---|
domain |
Domain name of this solution. Must match a CLI domain profile (wf domain add <name>) and the domain field of every component under this solution |
paths.componentsRoot |
Root folder where all components are located |
paths.tasks |
Tasks folder name under componentsRoot |
paths.workflows |
Workflows folder name under componentsRoot |
paths.schemas |
Schemas folder name under componentsRoot |
paths.views |
Views folder name under componentsRoot |
paths.functions |
Functions folder name under componentsRoot |
paths.extensions |
Extensions folder name under componentsRoot |
paths.mappings |
Mappings folder name under componentsRoot |
The CLI scans componentsRoot recursively and:
- Includes all
.jsonfiles in subfolders - Ignores
.metafolders - Ignores
*.diagram.jsonfiles - Ignores
package*.jsonand*config*.jsonfiles
A single workspace can hold several domains side by side. Each domain gets its own solution file in the project root and its own componentsRoot:
my-workspace/
βββ vnext.config.json # domain "core" β componentsRoot "core"
βββ vnext.partner.config.json # domain "partner" β componentsRoot "partner"
βββ core/
β βββ Workflows/ β¦
β βββ Tasks/ β¦
βββ partner/
βββ Workflows/ β¦
βββ Views/ β¦
Rules:
- File name:
vnext.config.json(default) orvnext.{domain}.config.json. The{domain}part is only used to find the file; thedomainfield inside the file is authoritative. If the two differ, a warning is printed and the field wins. - Separate folders: every solution points at its own
paths.componentsRoot. Discovery,--file,--folderand Git-changed detection are all scoped to that folder. - Profiles: each solution's
domainis looked up in the CLI domain profiles (wf domain list). A solution with no matching profile is skipped with a warning bycheck/sync/update/reset(csxneeds no profile and always runs). - Component domain check: every component JSON must carry a
domainequal to its solution'sdomain. A missing or different value fails that component withDOMAIN_MISMATCH; the rest of the batch continues. - Sequential processing: with no
--domainoption, every workspace command runs once per solution, in order, each under its own banner, followed by aWORKSPACE SUMMARYand a combined error table with aDomaincolumn. --domain <name>: global option that restricts any command to one solution. Works before or after the command name (wf update --domain partner,wf --domain partner update).- Duplicate domains: two solution files declaring the same
domainare both rejected.
After installation, navigate to your vNext project and run:
# Go to your vNext project directory
cd /path/to/your/vnext-project
# Database settings (if using Docker)
wf config set USE_DOCKER true
wf config set DOCKER_POSTGRES_CONTAINER vnext-postgres
# Verify configuration
wf checkNote: The CLI automatically uses the current working directory as the project root. Just cd into your project folder before running commands.
Tip: All examples use
wfbut you can also usevnextorworkflowinterchangeably. Thevnextalias is recommended on Windows wherewfmay conflict with existing system commands.
# System status check
wf check
# Update CSX + JSON files (automatically finds changed files)
wf update
# Add missing workflows to database
wf sync
# Reset workflows (delete from DB and re-add)
wf resetAll workspace commands (check, csx, sync, update, reset) accept the global --domain <name> option. Without it they run once per solution file found in the project root.
Purpose: Generate offline attribute-index SQL for planned execution by your DBA team.
From a domain workspace containing vnext.config.json:
wf indexes generate --output ./index-sql
wf indexes generate --flow money-transfer --output ./index-sqlEach invocation writes a new batch folder containing one .sql per workflow, a manifest.json
(source paths, versions, SHA-256 checksums, physical index definitions), and execution notes. Earlier
batches are preserved. The command never connects to API/DB and never executes SQL; sync, update
and Master publication do not invoke it.
The generator resolves local workflow β Master references from the configured component directories.
All local versions of a workflow contribute requirements. Full -pkg. revisions remain pinned; latest,
artifact, minor and major selectors use runtime version ordering. Build metadata is ignored. Referenced
schemas must exist locally; incomplete references, duplicate versions and incompatible types fail.
Indexed fields use x-indexed: true. Nested scalar string/number/integer/boolean fields are supported;
dates use format: "date-time". Filtering/sorting permissions remain x-filterOperators/x-sortable.
The generator preserves the runtime v1:latest column/key contract; readable index names include a hash
of their physical definition.
The DBA reviews and executes each SQL file in a maintenance window:
psql -X -v ON_ERROR_STOP=1 --dbname=vNext_MyDomainDb --file=index-sql/<batch>/money_transfer.sqlSQL takes an advisory lock plus an ACCESS EXCLUSIVE table lock.
It validates current/history data, adds stored generated columns in one table rewrite, reuses structurally
matching indexes (including legacy names), rebuilds changed owned indexes, and updates the runtime ready
catalog atomically. Index comparison covers keys, includes, ordering, collation, access method, operator
classes and partial predicates. Unmanaged collisions abort; no CASCADE is issued. Replaying an unchanged
batch preserves index OIDs and skips data validation, rewrites and ANALYZE. Missing/invalid values are not
silently coerced; conversion errors identify the field and roll back all changes.
This is not concurrent DDL. Plan disk/WAL/replica capacity for generated-column rewrites; the script's
5-second lock timeout may be adjusted during DBA review. Text-search indexes require pg_trgm in public
and tr-TR-x-icu. Runtime routing uses AttributeIndexes:Enabled; catalog refresh defaults to 30 seconds.
Obsolete projections are retained by default for other deployed versions. To explicitly retire them:
wf indexes generate --flow money-transfer --retire-obsoleteInclude every still-active workflow version locally and drain readers/writers for this maintenance.
Retirement removes obsolete expressions/owned indexes and marks catalog entries not ready; columns and
stored values remain. This is required when an old numeric/date cast would reject values after a type
change. The offline tool cannot verify deployed versions: compare the source manifest before execution.
Roll back query routing through the runtime's AttributeIndexes:DisabledFlows; schedule physical cleanup
separately. See the runtime maintenance runbook.
Tests (Node 18+ test runner):
node --test test/indexes.test.js
# Use only a disposable PostgreSQL database; the test owns uniquely named fixture schemas.
VNEXT_INDEX_TEST_URL=postgresql://user:password@localhost:5432/disposable_test \
node --test test/indexes.postgres.test.jsPurpose: System health check
For every solution, checks and displays:
- Solution file status, domain and components root
- API connection status (skipped with a
wf domain addhint when the domain has no CLI profile) - Database connection status
- Component folders found
wf check # every solution in the workspace
wf check --domain partner # one solutionPurpose: Add missing components to database (skip existing)
What it does:
- Scans all CSX files and updates JSON files with base64 encoded content
- For each component JSON file:
- Checks if it exists in DB (by key)
- If exists β Skip (already synced)
- If not exists β Publish to API
- Signals
definitions/publish/completedonce β the runtime's post-deployment hook
Use when: Initial setup, adding new components without affecting existing ones
wf syncsync, update and reset each end with one call to the runtime:
POST {baseUrl}/api/{version}/definitions/publish/completed
It runs the runtime's post-deployment hooks once per command. Today that means forcing a re-read of the domain discovery registry β and that matters more than it looks: the runtime's discovery endpoint cache carries no TTL, so this call is its only automatic invalidation. Without it a runtime keeps resolving cross-domain calls by whatever it learned at startup, until its pod restarts.
The response is always HTTP 200; a failed hook is reported in the body, and the CLI prints each hook's outcome:
β Publish-completed ran 1 hook(s)
discovery-cache: Refreshed
Refreshed is the normal outcome. SkippedNotOwner is also fine β another replica is reading the
registry and its result applies cluster-wide. Disabled means that runtime has no discovery cache
(ServiceDiscovery:Provider=dapr, or the cache switched off). Failed means the registry could not
be read and nothing else will retry it.
Requires a runtime that exposes
definitions/publish/completed. It replacesdefinitions/re-initialize, which older runtimes served as a no-op and current ones have removed. Against an older runtime this call 404s and the CLI prints the warning above without failing the command.
Purpose: Update changed components (delete + re-add)
What it does:
- Finds changed CSX files (Git) and updates JSON files
- For each component JSON file:
- Checks if it exists in DB (by key)
- If exists β Delete from DB, then publish to API
- If not exists β Publish to API
- Signals
definitions/publish/completedonce β the runtime's post-deployment hook
Use when: You modified existing components and want to update them
wf update # Process changed files in Git (CSX + JSON), every solution
wf update --all # Update all (asks for confirmation once, for all domains)
wf update --file x.json # Process a single file (its solution is derived from the path)
wf update --folder person # Process every component under a feature folder, ignoring Git
wf update --domain partner --all # Only the "partner" solutionIn a multi-solution workspace --file is routed to the solution whose componentsRoot contains the file; combining it with a different --domain is an error. --folder is resolved inside each solution separately (an exact path is only accepted inside that solution's componentsRoot).
--folder <name> (-d): Updates every component belonging to a feature, across all component types, regardless of Git status. It resolves <name> in two ways:
- Feature name (e.g.
person): matches<name>under every component-type root (Workflows/person,Tasks/person,Views/person,Schemas/person, β¦) and updates all of them together. - Exact path (e.g.
Workflows/personor an absolute path): updates only that specific folder.
If nothing matches, the command lists the feature folder names it did find so you can correct a typo. --file takes precedence over --folder, which takes precedence over --all.
wf update --folder person # Every "person" folder across all component types
wf update -d Workflows/person # Only Workflows/personPurpose: Force reset components (always delete + re-add)
What it does:
- Shows interactive menu to select component type
- For each component JSON file:
- Checks if it exists in DB (by key)
- If exists β Delete from DB, then publish to API
- If not exists β Publish to API
- Signals
definitions/publish/completedonce β the runtime's post-deployment hook
Use when: You need to force reset components regardless of changes
wf reset # Select folder from interactive menu
wf reset --domain core # Skip the domain picker in a multi-solution workspaceIn a workspace with several solution files, wf reset first asks which domain to reset (unless --domain is given), then shows the folder menu for that solution.
Menu Options:
? Which folder should be reset?
β― tasks (Tasks/)
views (Views/)
functions (Functions/)
extensions (Extensions/)
workflows (Workflows/)
schemas (Schemas/)
mappings (Mappings/)
ββββββββββββββ
TUMU (All folders)
Purpose: Convert CSX files to Base64 and embed in JSON files
What it does:
- Finds CSX files (changed or all)
- Converts to Base64
- Updates ALL JSON files that reference the CSX file
- Updates ALL matching
locationreferences in each JSON
Use when: You only want to update CSX content in JSONs without publishing to API
wf csx # Process changed files in Git, every solution
wf csx --all # Process all CSX files
wf csx --file x.csx # Process a single file
wf csx --domain partner # Only the "partner" solutioncsx does not need a CLI domain profile, so it also runs for solutions whose domain has no profile yet.
Purpose: Configuration management
wf config get # Show all settings (active domain)
wf config get PROJECT_ROOT # Show a specific setting
wf config set DB_PASSWORD pass # Change a setting (on active domain)Note: config get and config set always operate on the active domain. Use wf domain use <name> to switch domains.
Purpose: Multidomain management
Manage multiple domain configurations (API/DB connection profiles). Workspace commands pick the profile whose name equals each solution's domain; wf config get/set operate on the active domain (wf domain use).
# Show active domain name
wf domain active
# List all domains
wf domain list
wf domain --list
# Add a new domain
wf domain add staging --API_BASE_URL http://staging.example.com:4201 --DB_NAME vNext_StagingDb
# Add a domain with multiple settings
wf domain add production \
--API_BASE_URL http://prod.example.com:4201 \
--DB_NAME vNext_ProdDb \
--DB_HOST prod-db.example.com \
--DB_USER prod_user \
--DB_PASSWORD prod_pass
# Switch active domain
wf domain use staging
# Remove a domain
wf domain remove stagingNotes:
- When adding a domain, any unspecified settings are inherited from the
defaultdomain. - The
defaultdomain cannot be removed. - If the active domain is removed, the CLI automatically switches to
default.
Config file location: ~/.config/vnext-workflow-cli/config.json
The config file uses a domain-aware structure. Each domain has its own set of configuration values:
{
"ACTIVE_DOMAIN": "default",
"DOMAINS": [
{
"DOMAIN_NAME": "default",
"AUTO_DISCOVER": true,
"API_BASE_URL": "http://localhost:4201",
"API_VERSION": "v1",
"DB_HOST": "localhost",
"DB_PORT": 5432,
"DB_NAME": "vNext_WorkflowDb",
"DB_USER": "postgres",
"DB_PASSWORD": "postgres",
"USE_DOCKER": false,
"DOCKER_POSTGRES_CONTAINER": "vnext-postgres",
"DEBUG_MODE": false
}
]
}| Variable | Default | Description |
|---|---|---|
PROJECT_ROOT |
process.cwd() |
Auto. Always uses current working directory (cannot be changed) |
AUTO_DISCOVER |
true |
Enable automatic component folder discovery |
API_BASE_URL |
http://localhost:4201 |
vNext API base URL |
API_VERSION |
v1 |
API version |
DB_HOST |
localhost |
PostgreSQL host |
DB_PORT |
5432 |
PostgreSQL port |
DB_NAME |
vNext_WorkflowDb |
PostgreSQL database name |
DB_USER |
postgres |
PostgreSQL username |
DB_PASSWORD |
postgres |
PostgreSQL password |
USE_DOCKER |
false |
Use Docker for PostgreSQL connection |
DOCKER_POSTGRES_CONTAINER |
vnext-postgres |
Docker container name for PostgreSQL |
DEBUG_MODE |
false |
Enable debug logging |
Note: PROJECT_ROOT is always the current working directory (process.cwd()). Simply cd into your project folder before running any command.
# API settings (applied to active domain)
wf config set API_BASE_URL http://localhost:4201
wf config set API_VERSION v1
# Database settings (direct connection)
wf config set DB_HOST localhost
wf config set DB_PORT 5432
wf config set DB_NAME vNext_WorkflowDb
wf config set DB_USER postgres
wf config set DB_PASSWORD your_password
wf config set USE_DOCKER false
# Database settings (Docker)
wf config set USE_DOCKER true
wf config set DOCKER_POSTGRES_CONTAINER vnext-postgres
# Other settings
wf config set AUTO_DISCOVER true
wf config set DEBUG_MODE false# Go to your vNext project
cd /path/to/project
# Check system status
wf check
# Sync all components (add missing ones)
wf sync# Edit CSX or JSON files
vim MyTask.csx
# Update only changed components
wf update# Force update all components
wf update --all# Interactive menu
wf reset# Update CSX content in JSON files without publishing
wf csx# Update every "person" component across Workflows/, Tasks/, Views/, Schemas/, ...
wf update --folder person
# Or target one exact folder
wf update --folder Workflows/person# Add domain profiles (one-time setup)
wf domain add core --API_BASE_URL http://localhost:4201 --DB_NAME vNext_Core
wf domain add partner --API_BASE_URL http://localhost:4221 --DB_NAME vNext_Partner
# One workspace, two solution files
cd ~/projects/my-workspace # vnext.config.json ("core") + vnext.partner.config.json ("partner")
wf check # both domains, each with its own banner
wf update # git-changed files of core, then of partner
wf update --domain partner # only partner
# Separate workspaces still work exactly as before
cd ~/projects/core-app # vnext.config.json has "domain": "core"
wf update # uses the "core" profile
# See all profiles
wf domain list| Command | DB Check | Existing Action | New Action | Use Case |
|---|---|---|---|---|
sync |
Yes | Skip | Publish | Add missing components |
update |
Yes | Delete + Publish | Publish | Update changed components |
update --folder <name> |
Yes | Delete + Publish | Publish | Update every component in a feature folder (ignores Git) |
reset |
Yes | Delete + Publish | Publish | Force reset components |
csx |
No | N/A | N/A | Only update CSX in JSONs |
The CLI supports managing multiple domain configurations. Each domain has its own API_BASE_URL, DB_NAME, and other settings, stored as a domain profile. A workspace may contain one or many solution files, and each solution is processed with the profile that matches its domain.
Before a workspace command runs, the CLI:
- Lists the solution files in the current directory:
vnext.config.jsonplus everyvnext.{domain}.config.json. - Reads the
domainfield of each one. - Looks up a CLI domain profile with the same name (
DOMAINS[].DOMAIN_NAME). - Runs the command once per solution, sequentially, with that profile's API/DB settings. A solution without a profile is skipped with a hint:
β No CLI domain profile for "partner" β skipped. Run: wf domain add partner --API_BASE_URL <url> --DB_NAME <db>
ACTIVE_DOMAIN is not changed by running commands in a workspace. It only affects wf domain active and wf config get/set. Use --domain <name> to restrict a command to a single solution.
Upgrading from 1.x: earlier versions rewrote
ACTIVE_DOMAINto the workspace's domain on every command ("auto domain resolution"). That side effect is gone;wf config getnow always shows the domain you last selected withwf domain use.
Example: two profiles, two solutions in one workspace:
wf domain add core --DB_NAME vNext_Core
wf domain add partner --DB_NAME vNext_Partner
cd ~/projects/my-workspace # vnext.config.json (core) + vnext.partner.config.json (partner)
wf update # core with the "core" profile, then partner with the "partner" profile- Existing single-domain configurations are automatically migrated to the new format.
- A
defaultdomain is created with your existing settings. - If you don't use multidomain features, everything works exactly as before.
- All
wf config get/setcommands continue to work (they operate on the active domain).
When upgrading from an older version, the CLI automatically migrates the config file:
Before (old flat format):
{
"API_BASE_URL": "http://localhost:4201",
"DB_NAME": "vNext_WorkflowDb"
}After (new domain-aware format):
{
"ACTIVE_DOMAIN": "default",
"DOMAINS": [
{
"DOMAIN_NAME": "default",
"AUTO_DISCOVER": true,
"API_BASE_URL": "http://localhost:4201",
"API_VERSION": "v1",
"DB_HOST": "localhost",
"DB_PORT": 5432,
"DB_NAME": "vNext_WorkflowDb",
"DB_USER": "postgres",
"DB_PASSWORD": "postgres",
"USE_DOCKER": false,
"DOCKER_POSTGRES_CONTAINER": "vnext-postgres",
"DEBUG_MODE": false
}
]
}Your existing values are preserved. Any missing keys are filled in from defaults (11 keys total).
No manual action is required. The migration happens automatically on first run.
| Command | Description |
|---|---|
wf domain active |
Show active domain name |
wf domain list |
List all domains with active indicator |
wf domain --list |
List all domains (shorthand) |
wf domain add <name> [options] |
Add a new domain |
wf domain use <name> |
Switch active domain |
wf domain remove <name> |
Remove a domain |
| Option | Description |
|---|---|
--API_BASE_URL <url> |
API base URL |
--API_VERSION <version> |
API version |
--DB_HOST <host> |
Database host |
--DB_PORT <port> |
Database port |
--DB_NAME <name> |
Database name |
--DB_USER <user> |
Database user |
--DB_PASSWORD <password> |
Database password |
--AUTO_DISCOVER <true/false> |
Auto discover components |
--USE_DOCKER <true/false> |
Use Docker for DB |
--DOCKER_POSTGRES_CONTAINER <name> |
Docker container name |
--DEBUG_MODE <true/false> |
Debug mode |
Unspecified options inherit from the default domain.
# Make sure you're in the correct directory
pwd
# Check if vnext.config.json exists
ls -la vnext.config.json
# Check current working directory
wf config get PROJECT_ROOT# Just cd into the project directory
cd /Users/NewUser/path/to/project
# Verify
wf checkNote: No need to set PROJECT_ROOT - just cd into your project folder.
The solution's domain has no matching profile. Create one:
wf domain add <domain> --API_BASE_URL http://localhost:4201 --DB_NAME <db>
wf domain listA component's domain field is missing or differs from the domain of the solution file whose componentsRoot contains it. Fix the component's domain (or move the file to the right solution folder) and re-run.
--domain names a domain that no solution file in the current directory declares. The message lists the available domains.
# Check API
curl http://localhost:4201/api/v1/health
# Check config
wf config get API_BASE_URL# Check Docker container
docker ps | grep postgres
# Start container
docker start vnext-postgres
# Check config
wf config get USE_DOCKER
wf config get DOCKER_POSTGRES_CONTAINER# Use alias (wf or vnext)
echo 'alias wf="node $(pwd)/bin/workflow.js"' >> ~/.bashrc
echo 'alias vnext="node $(pwd)/bin/workflow.js"' >> ~/.bashrc
source ~/.bashrcThe project uses automated versioning and publishing via GitHub Actions. Follow these steps to create and publish a new version:
-
Create a release branch following the pattern
release-vX.Y:git checkout -b release-v1.0 git push origin release-v1.0
-
Push to the release branch - The workflow will automatically:
- Calculate the next patch version (e.g.,
1.0.0,1.0.1,1.0.2) - Build and validate the package
- Publish to NPM and/or GitHub Packages
- Create a Git tag (e.g.,
v1.0.0) - Create a GitHub release
- Calculate the next patch version (e.g.,
- Go to GitHub Actions in your repository
- Select "Build and Publish to NPM" workflow
- Click "Run workflow"
- Configure options:
- Version Override: Optional. Leave empty for auto-calculation (e.g.,
1.0.6) - Force Publish: Set to
trueif you want to republish an existing version - Target Registry: Choose
npmjs,github, orboth
- Version Override: Optional. Leave empty for auto-calculation (e.g.,
- Click "Run workflow"
The workflow automatically calculates versions:
- From branch name: If branch is
release-v1.0, it will find the next available patch version (e.g.,1.0.0,1.0.1,1.0.2) - From package.json: If branch doesn't match the pattern, it increments the patch version from
package.json
Once published, the new version will be:
- β
Available on NPM:
npm install -g @burgan-tech/vnext-workflow-cli@1.0.0 - β
Tagged in Git:
v1.0.0 - β Released on GitHub with release notes
The workflow requires these secrets to be configured in GitHub repository settings:
- NPM_TOKEN (optional): For publishing to NPM. If not set, only GitHub Packages will be used.
- SONAR_TOKEN (optional): For code quality analysis
- SONAR_HOST_URL (optional): SonarQube server URL
The build and publish workflow performs these steps:
- β Checkout code with full Git history
- β Calculate version from branch or package.json
- β Validate syntax - Checks all JavaScript files
- β Run linting (if available)
- β Run tests (if available)
- β Build package (if build script exists)
- β Publish to registry (NPM and/or GitHub Packages)
- β
Create Git tag (e.g.,
v1.0.0) - β Create GitHub release with release notes
vnext-workflow-cli/
βββ bin/
β βββ workflow.js # CLI entry point
βββ src/
β βββ commands/ # Command implementations
β β βββ check.js
β β βββ config.js
β β βββ csx.js
β β βββ domain.js # Multidomain management
β β βββ reset.js
β β βββ sync.js
β β βββ update.js
β βββ lib/ # Library modules
β βββ api.js # API client (publish, publish-completed)
β βββ config.js # CLI configuration
β βββ csx.js # CSX processing
β βββ db.js # Database operations
β βββ discover.js # Component discovery
β βββ solutions.js # Solution-file discovery + per-domain runner
β βββ vnextConfig.js # Solution file (vnext*.config.json) parser
β βββ workflow.js # Workflow processing
βββ .github/
β βββ workflows/ # GitHub Actions workflows
β βββ build-and-publish.yml
β βββ check-sonar.yml
βββ package.json
βββ README.md
# Clone and install
git clone https://github.com/burgan-tech/vnext-workflow-cli.git
cd vnext-workflow-cli
npm install
npm link
# Test the CLI
wf --version
wf check
# Run development
npm run devMIT License - see LICENSE for details.
Schema components use the existing attributes.type string. Its values are not restricted to an enum;
legacy and custom types remain valid. Only the exact value master permits x-indexed metadata
(including false) and contributes index SQL. Missing, null, blank or other values never mean master.
The existing publication requirement for a non-empty schema type is unchanged. JSON Schema type
keywords within attributes.schema retain their existing meaning.
A latest reference resolving to a non-master schema does not fall back to an older master version.
No matching masters means no SQL batch. There is no separate component root type field.
{
"key": "order-master",
"domain": "sales",
"flow": "sys-schemas",
"version": "1.0.0",
"flowVersion": "1.0.0",
"tags": ["orders"],
"attributes": {
"type": "master",
"schema": {
"type": "object",
"properties": {
"amount": { "type": "number", "x-indexed": true, "x-filterOperators": ["gt"] }
}
}
}
}The schema validator reads SchemaDefinition.Type (attributes.type) during publication, including
schema seed items. No extra envelope metadata is required.