newo 1.5.2 → 1.6.1
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/CHANGELOG.md +64 -0
- package/README.md +325 -4
- package/dist/cli.js +66 -22
- package/dist/customerAsync.d.ts +8 -0
- package/dist/customerAsync.js +28 -0
- package/dist/sync.js +1 -1
- package/package.json +2 -1
- package/src/cli.ts +66 -23
- package/src/customerAsync.ts +35 -3
- package/src/sync.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,70 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.6.1] - 2025-09-13
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- **YAML Enum Formatting**: Fixed enum formatting in `flows.yaml` generation to properly handle NEWO enum types
|
|
12
|
+
- Corrected enum value serialization from quoted strings to proper YAML enum format
|
|
13
|
+
- Fixed issue where enum values like `!enum "RunnerType.guidance"` were incorrectly quoted
|
|
14
|
+
- Ensures generated `flows.yaml` files are properly formatted for NEWO platform consumption
|
|
15
|
+
|
|
16
|
+
### Enhanced
|
|
17
|
+
- **ES Module Support**: Added `"type": "module"` to package.json for proper ES module handling
|
|
18
|
+
- Resolves Node.js warnings about module type detection
|
|
19
|
+
- Improves performance by eliminating module type guessing
|
|
20
|
+
- Ensures consistent ES module behavior across all environments
|
|
21
|
+
|
|
22
|
+
## [1.6.0] - 2025-09-13
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- **Multi-Customer Auto-Pull**: Revolutionary workflow improvement for multi-customer environments
|
|
26
|
+
- `newo pull` now automatically pulls from ALL customers when no default customer is set
|
|
27
|
+
- Eliminates the need to specify `--customer` flag or set `NEWO_DEFAULT_CUSTOMER` for bulk operations
|
|
28
|
+
- Maintains backward compatibility - individual customer selection still works with `--customer` flag
|
|
29
|
+
- Smart detection: single customer setup works as before, multi-customer setup auto-pulls all
|
|
30
|
+
- **Publishing Infrastructure**: Complete automated publishing system for professional releases
|
|
31
|
+
- `scripts/publish-github.sh`: Automated GitHub publishing with releases, tags, and version management
|
|
32
|
+
- `scripts/publish-npm.sh`: Automated NPM publishing with validation and safety checks
|
|
33
|
+
- Comprehensive Makefile with 40+ commands for development and publishing workflows
|
|
34
|
+
- Version bump helpers (patch/minor/major) with semantic versioning support
|
|
35
|
+
- **Enhanced Documentation**: Professional publishing and development documentation
|
|
36
|
+
- Complete "Publishing & Release Management" section with step-by-step workflows
|
|
37
|
+
- "Local Testing" section with comprehensive testing procedures
|
|
38
|
+
- Makefile command reference with organized development workflows
|
|
39
|
+
- Troubleshooting guides for common development and publishing issues
|
|
40
|
+
|
|
41
|
+
### Enhanced
|
|
42
|
+
- **Customer Configuration Logic**: New functions for flexible customer handling
|
|
43
|
+
- `tryGetDefaultCustomer()`: Non-throwing version that returns null for multi-customer scenarios
|
|
44
|
+
- `getAllCustomers()`: Returns array of all configured customers for batch operations
|
|
45
|
+
- Improved error handling and user feedback for customer selection scenarios
|
|
46
|
+
- **CLI User Experience**: Enhanced command behavior and help documentation
|
|
47
|
+
- Updated help text to reflect auto-pull behavior: "uses default or all for pull"
|
|
48
|
+
- Clear progress indicators for multi-customer operations
|
|
49
|
+
- Better error messages and troubleshooting guidance
|
|
50
|
+
- **Development Workflow**: Professional development and publishing infrastructure
|
|
51
|
+
- Makefile with color-coded output and comprehensive command organization
|
|
52
|
+
- Automated validation pipelines for publishing (build, test, lint, typecheck)
|
|
53
|
+
- Publishing scripts with safety checks and rollback procedures
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
- **Pull Command Behavior**: Breaking change in multi-customer environments (improvement)
|
|
57
|
+
- Previously: Required explicit customer selection or default customer configuration
|
|
58
|
+
- Now: Automatically pulls from all customers when no default is set
|
|
59
|
+
- Single customer setups: No change in behavior
|
|
60
|
+
- Multi-customer setups: Significantly improved user experience
|
|
61
|
+
- **Help Documentation**: Updated command descriptions and examples
|
|
62
|
+
- `newo pull` now shows "(all customers if no default)" in help text
|
|
63
|
+
- Enhanced multi-customer examples with auto-pull scenarios
|
|
64
|
+
- Updated usage patterns to reflect new workflow capabilities
|
|
65
|
+
|
|
66
|
+
### Developer Experience
|
|
67
|
+
- **Publishing Automation**: One-command publishing to both GitHub and NPM with full validation
|
|
68
|
+
- **Comprehensive Testing**: Enhanced local testing documentation with step-by-step procedures
|
|
69
|
+
- **Professional Infrastructure**: Industry-standard publishing pipeline with version management
|
|
70
|
+
- **Quality Gates**: Automated validation before publishing (TypeScript, linting, building, package validation)
|
|
71
|
+
|
|
8
72
|
## [1.5.2] - 2025-01-15
|
|
9
73
|
|
|
10
74
|
### Enhanced
|
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ Mirror NEWO "Project → Agent → Flow → Skills" structure to local files wit
|
|
|
25
25
|
|
|
26
26
|
**Option 1: Global Installation (Recommended)**
|
|
27
27
|
```bash
|
|
28
|
-
npm install -g newo
|
|
28
|
+
npm install -g newo@latest
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
**Option 2: Local Project Installation**
|
|
@@ -127,7 +127,7 @@ NEWO_REFRESH_URL=custom_refresh_endpoint # Custom refresh endpoint
|
|
|
127
127
|
|
|
128
128
|
| Command | Description | Examples |
|
|
129
129
|
|---------|-------------|----------|
|
|
130
|
-
| `newo pull` | Download projects from NEWO | `newo pull
|
|
130
|
+
| `newo pull` | Download projects from NEWO | `newo pull` (all customers if no default)<br>`newo pull --customer=ACME`<br>`newo pull --project=uuid` |
|
|
131
131
|
| `newo push` | Upload local changes to NEWO | `newo push`<br>`newo push --customer=BETA` |
|
|
132
132
|
| `newo status` | Show modified files | `newo status`<br>`newo status --verbose` |
|
|
133
133
|
| `newo list-customers` | List configured customers | `newo list-customers` |
|
|
@@ -146,8 +146,8 @@ newo pull --customer=NEWO_ABC123
|
|
|
146
146
|
# Push changes to specific customer
|
|
147
147
|
newo push --customer=NEWO_XYZ789
|
|
148
148
|
|
|
149
|
-
# Work with default customer (
|
|
150
|
-
newo pull # Uses default
|
|
149
|
+
# Work with default customer (or auto multi-customer)
|
|
150
|
+
newo pull # Uses default customer OR pulls from all customers if no default set
|
|
151
151
|
newo push # Pushes to appropriate customers based on file origin
|
|
152
152
|
```
|
|
153
153
|
|
|
@@ -493,6 +493,176 @@ npm run dev push # Build and run push
|
|
|
493
493
|
| `npm run test:unit` | Run unit tests only |
|
|
494
494
|
| `npm run test:coverage` | Generate coverage report |
|
|
495
495
|
|
|
496
|
+
### Makefile Commands
|
|
497
|
+
|
|
498
|
+
The project includes a comprehensive Makefile for streamlined development:
|
|
499
|
+
|
|
500
|
+
#### Quick Commands
|
|
501
|
+
```bash
|
|
502
|
+
make help # Show all available commands
|
|
503
|
+
make setup # Initial project setup
|
|
504
|
+
make build # Build TypeScript
|
|
505
|
+
make test # Run tests
|
|
506
|
+
make dev # Development mode
|
|
507
|
+
make publish # Publish to GitHub and NPM
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
#### Development Workflow
|
|
511
|
+
```bash
|
|
512
|
+
make fresh-start # Clean + install + build + test
|
|
513
|
+
make dev-pull # Test pull command in development
|
|
514
|
+
make dev-push # Test push command in development
|
|
515
|
+
make test-local # Comprehensive local testing
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
#### Publishing Workflow
|
|
519
|
+
```bash
|
|
520
|
+
make pre-publish # Complete validation before publishing
|
|
521
|
+
make publish-github # Publish to GitHub with release
|
|
522
|
+
make publish-npm # Publish to NPM
|
|
523
|
+
make publish # Publish to both platforms
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
#### Quality Assurance
|
|
527
|
+
```bash
|
|
528
|
+
make typecheck # TypeScript type checking
|
|
529
|
+
make lint # Code linting
|
|
530
|
+
make check-all # All quality checks
|
|
531
|
+
make deps-audit # Security audit
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### Local Testing
|
|
535
|
+
|
|
536
|
+
After making changes to the CLI code, proper testing is essential to ensure functionality works correctly.
|
|
537
|
+
|
|
538
|
+
#### Quick Testing Commands
|
|
539
|
+
|
|
540
|
+
```bash
|
|
541
|
+
# Build and test core functionality
|
|
542
|
+
npm run build # Compile TypeScript
|
|
543
|
+
node ./dist/cli.js --help # Test CLI loads correctly
|
|
544
|
+
node ./dist/cli.js list-customers # Test customer configuration
|
|
545
|
+
|
|
546
|
+
# Test single customer operations
|
|
547
|
+
node ./dist/cli.js pull --customer=CUSTOMER_IDN # Test specific customer pull
|
|
548
|
+
node ./dist/cli.js status --customer=CUSTOMER_IDN # Test specific customer status
|
|
549
|
+
|
|
550
|
+
# Test multi-customer operations (if multiple API keys configured)
|
|
551
|
+
node ./dist/cli.js pull # Test auto multi-customer pull
|
|
552
|
+
node ./dist/cli.js pull --verbose # Test with detailed logging
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
#### Complete Testing Workflow
|
|
556
|
+
|
|
557
|
+
1. **Environment Setup**
|
|
558
|
+
```bash
|
|
559
|
+
# Ensure clean environment
|
|
560
|
+
cp .env.example .env
|
|
561
|
+
# Edit .env with your API key(s)
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
2. **Build & Syntax Check**
|
|
565
|
+
```bash
|
|
566
|
+
npm run build # Must complete without TypeScript errors
|
|
567
|
+
npm run typecheck # Verify type safety
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
3. **Basic CLI Tests**
|
|
571
|
+
```bash
|
|
572
|
+
node ./dist/cli.js --help # Should show updated help text
|
|
573
|
+
node ./dist/cli.js list-customers # Should show configured customers
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
4. **Authentication Tests**
|
|
577
|
+
```bash
|
|
578
|
+
# Test API key exchange and token generation
|
|
579
|
+
node ./dist/cli.js meta --verbose # Forces authentication
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
5. **Pull Operation Tests**
|
|
583
|
+
```bash
|
|
584
|
+
# Single customer (if specific customer configured)
|
|
585
|
+
node ./dist/cli.js pull --customer=YOUR_CUSTOMER_IDN --verbose
|
|
586
|
+
|
|
587
|
+
# Multi-customer (if multiple API keys configured)
|
|
588
|
+
node ./dist/cli.js pull --verbose # Should pull from all customers
|
|
589
|
+
|
|
590
|
+
# Check file structure was created correctly
|
|
591
|
+
ls -la newo_customers/ # Should show customer folders
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
6. **Status & Push Tests**
|
|
595
|
+
```bash
|
|
596
|
+
node ./dist/cli.js status --verbose # Should show no changes initially
|
|
597
|
+
|
|
598
|
+
# Make a test change to a .guidance or .jinja file
|
|
599
|
+
echo "# Test comment" >> newo_customers/*/projects/*/*/*/*.guidance
|
|
600
|
+
|
|
601
|
+
node ./dist/cli.js status # Should detect the change
|
|
602
|
+
node ./dist/cli.js push --verbose # Should upload the change
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
#### Testing Multi-Customer Functionality
|
|
606
|
+
|
|
607
|
+
If you have multiple API keys configured, test the new auto-pull behavior:
|
|
608
|
+
|
|
609
|
+
```bash
|
|
610
|
+
# Test that pull works without specifying customer
|
|
611
|
+
node ./dist/cli.js pull # Should pull from ALL customers
|
|
612
|
+
|
|
613
|
+
# Test individual customer selection still works
|
|
614
|
+
node ./dist/cli.js pull --customer=CUSTOMER_A # Should pull from specific customer
|
|
615
|
+
node ./dist/cli.js push --customer=CUSTOMER_B # Should push to specific customer
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
#### Common Testing Issues & Solutions
|
|
619
|
+
|
|
620
|
+
**Issue: "Multiple customers configured but no default specified" error**
|
|
621
|
+
- **Cause**: You're using `npx newo` instead of the local build
|
|
622
|
+
- **Solution**: Use `node ./dist/cli.js` instead of `npx newo`
|
|
623
|
+
|
|
624
|
+
**Issue: Changes not reflected in CLI behavior**
|
|
625
|
+
- **Cause**: TypeScript not compiled or using cached version
|
|
626
|
+
- **Solution**: Run `npm run build` first, then test with `node ./dist/cli.js`
|
|
627
|
+
|
|
628
|
+
**Issue: Authentication errors during testing**
|
|
629
|
+
- **Cause**: Invalid API keys or network issues
|
|
630
|
+
- **Solution**: Verify API keys in `.env`, test with `--verbose` flag for details
|
|
631
|
+
|
|
632
|
+
**Issue: File permission errors**
|
|
633
|
+
- **Cause**: Insufficient permissions in project directory
|
|
634
|
+
- **Solution**: Ensure write permissions: `chmod 755 .` and check disk space
|
|
635
|
+
|
|
636
|
+
#### Performance Testing
|
|
637
|
+
|
|
638
|
+
For testing with large projects or multiple customers:
|
|
639
|
+
|
|
640
|
+
```bash
|
|
641
|
+
# Test with timeout to avoid hanging
|
|
642
|
+
timeout 30s node ./dist/cli.js pull --verbose # Should complete or show progress
|
|
643
|
+
|
|
644
|
+
# Test memory usage
|
|
645
|
+
node --max-old-space-size=512 ./dist/cli.js pull # Test with limited memory
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
#### Integration Testing
|
|
649
|
+
|
|
650
|
+
Test complete workflows that users would actually perform:
|
|
651
|
+
|
|
652
|
+
```bash
|
|
653
|
+
# Complete development workflow
|
|
654
|
+
node ./dist/cli.js pull # Download latest
|
|
655
|
+
# Edit some .guidance/.jinja files
|
|
656
|
+
node ./dist/cli.js status # Check changes
|
|
657
|
+
node ./dist/cli.js push # Upload changes
|
|
658
|
+
|
|
659
|
+
# Multi-customer workflow
|
|
660
|
+
node ./dist/cli.js list-customers # See available customers
|
|
661
|
+
node ./dist/cli.js pull --customer=CUSTOMER_A # Work with specific customer
|
|
662
|
+
# Make changes
|
|
663
|
+
node ./dist/cli.js push --customer=CUSTOMER_A # Push to specific customer
|
|
664
|
+
```
|
|
665
|
+
|
|
496
666
|
### Project Architecture
|
|
497
667
|
|
|
498
668
|
```
|
|
@@ -535,6 +705,157 @@ NEWO CLI includes comprehensive test coverage:
|
|
|
535
705
|
|
|
536
706
|
---
|
|
537
707
|
|
|
708
|
+
## Publishing & Release Management
|
|
709
|
+
|
|
710
|
+
The project includes automated scripts for publishing to GitHub and NPM with proper validation and release management.
|
|
711
|
+
|
|
712
|
+
### Prerequisites for Publishing
|
|
713
|
+
|
|
714
|
+
1. **GitHub Setup**
|
|
715
|
+
```bash
|
|
716
|
+
# Ensure GitHub remote is configured
|
|
717
|
+
git remote -v # Should show origin pointing to sabbah13/newo-cli
|
|
718
|
+
|
|
719
|
+
# Install GitHub CLI (optional, for automatic releases)
|
|
720
|
+
brew install gh # macOS
|
|
721
|
+
# or
|
|
722
|
+
sudo apt install gh # Ubuntu
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
2. **NPM Setup**
|
|
726
|
+
```bash
|
|
727
|
+
# Login to NPM
|
|
728
|
+
npm login
|
|
729
|
+
npm whoami # Verify you're logged in
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
### Publishing Workflow
|
|
733
|
+
|
|
734
|
+
#### Option 1: Full Automated Publishing (Recommended)
|
|
735
|
+
```bash
|
|
736
|
+
# Complete validation and publish to both platforms
|
|
737
|
+
make publish
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
This command will:
|
|
741
|
+
- Run all tests and quality checks
|
|
742
|
+
- Build the project
|
|
743
|
+
- Prompt for version bump (patch/minor/major)
|
|
744
|
+
- Publish to GitHub with release notes
|
|
745
|
+
- Publish to NPM with proper tags
|
|
746
|
+
- Verify publication success
|
|
747
|
+
|
|
748
|
+
#### Option 2: Step-by-Step Publishing
|
|
749
|
+
```bash
|
|
750
|
+
# 1. Validate everything is ready
|
|
751
|
+
make pre-publish
|
|
752
|
+
|
|
753
|
+
# 2. Publish to GitHub first
|
|
754
|
+
make publish-github
|
|
755
|
+
|
|
756
|
+
# 3. Publish to NPM
|
|
757
|
+
make publish-npm
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
#### Option 3: Manual Publishing
|
|
761
|
+
```bash
|
|
762
|
+
# Run individual scripts
|
|
763
|
+
./scripts/publish-github.sh
|
|
764
|
+
./scripts/publish-npm.sh
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
### Version Management
|
|
768
|
+
|
|
769
|
+
Use semantic versioning with the Makefile helpers:
|
|
770
|
+
|
|
771
|
+
```bash
|
|
772
|
+
make version-patch # 1.5.2 → 1.5.3 (bug fixes)
|
|
773
|
+
make version-minor # 1.5.2 → 1.6.0 (new features)
|
|
774
|
+
make version-major # 1.5.2 → 2.0.0 (breaking changes)
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
### Pre-Release Publishing
|
|
778
|
+
|
|
779
|
+
For beta/alpha releases:
|
|
780
|
+
```bash
|
|
781
|
+
# Set pre-release version manually
|
|
782
|
+
npm version 1.6.0-beta.1 --no-git-tag-version
|
|
783
|
+
|
|
784
|
+
# Publish with beta tag
|
|
785
|
+
make publish-npm # Automatically detects pre-release and uses beta tag
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
### Publishing Checklist
|
|
789
|
+
|
|
790
|
+
Before publishing, ensure:
|
|
791
|
+
- ✅ All tests pass (`make test`)
|
|
792
|
+
- ✅ TypeScript compiles without errors (`make build`)
|
|
793
|
+
- ✅ Local testing completed (`make test-local`)
|
|
794
|
+
- ✅ Documentation is up to date
|
|
795
|
+
- ✅ CHANGELOG.md is updated (if exists)
|
|
796
|
+
- ✅ Version number is appropriate
|
|
797
|
+
- ✅ No uncommitted changes (or committed)
|
|
798
|
+
|
|
799
|
+
### Automated Validation
|
|
800
|
+
|
|
801
|
+
The publish scripts include comprehensive validation:
|
|
802
|
+
- **TypeScript compilation** and type checking
|
|
803
|
+
- **Test suite execution** with coverage requirements
|
|
804
|
+
- **Package size analysis** and content verification
|
|
805
|
+
- **Authentication verification** for GitHub and NPM
|
|
806
|
+
- **Version conflict detection** to prevent duplicate publishes
|
|
807
|
+
- **Security audit** of dependencies
|
|
808
|
+
|
|
809
|
+
### GitHub Release Features
|
|
810
|
+
|
|
811
|
+
The GitHub publish script automatically:
|
|
812
|
+
- Creates semantic version tags (`v1.5.3`)
|
|
813
|
+
- Generates comprehensive release notes
|
|
814
|
+
- Marks releases as "latest" on GitHub
|
|
815
|
+
- Links to NPM package and documentation
|
|
816
|
+
- Includes installation instructions
|
|
817
|
+
|
|
818
|
+
### NPM Package Features
|
|
819
|
+
|
|
820
|
+
The NPM publish script ensures:
|
|
821
|
+
- Proper package.json validation
|
|
822
|
+
- Binary CLI availability verification
|
|
823
|
+
- File inclusion/exclusion validation
|
|
824
|
+
- Pre-release tag detection (`beta`, `alpha`, `rc`)
|
|
825
|
+
- Post-publish verification
|
|
826
|
+
|
|
827
|
+
### Rollback Procedures
|
|
828
|
+
|
|
829
|
+
If issues are discovered after publishing:
|
|
830
|
+
|
|
831
|
+
**NPM Rollback:**
|
|
832
|
+
```bash
|
|
833
|
+
# Deprecate problematic version
|
|
834
|
+
npm deprecate newo@1.5.3 "Version has known issues, use 1.5.2 instead"
|
|
835
|
+
|
|
836
|
+
# Publish fixed version immediately
|
|
837
|
+
make version-patch
|
|
838
|
+
make publish-npm
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
**GitHub Rollback:**
|
|
842
|
+
```bash
|
|
843
|
+
# Delete tag and release (if needed)
|
|
844
|
+
git tag -d v1.5.3
|
|
845
|
+
git push origin :refs/tags/v1.5.3
|
|
846
|
+
gh release delete v1.5.3
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
### Monitoring Post-Publication
|
|
850
|
+
|
|
851
|
+
After publishing, monitor:
|
|
852
|
+
- **NPM downloads**: https://npmjs.com/package/newo
|
|
853
|
+
- **GitHub releases**: https://github.com/sabbah13/newo-cli/releases
|
|
854
|
+
- **Issue reports**: https://github.com/sabbah13/newo-cli/issues
|
|
855
|
+
- **Badge updates**: README badges should reflect new version
|
|
856
|
+
|
|
857
|
+
---
|
|
858
|
+
|
|
538
859
|
## Contributing
|
|
539
860
|
|
|
540
861
|
We welcome contributions to NEWO CLI! Here's how to get involved:
|
package/dist/cli.js
CHANGED
|
@@ -5,7 +5,7 @@ import { makeClient, getProjectMeta, importAkbArticle } from './api.js';
|
|
|
5
5
|
import { pullAll, pushChanged, status } from './sync.js';
|
|
6
6
|
import { parseAkbFile, prepareArticlesForImport } from './akb.js';
|
|
7
7
|
import { initializeEnvironment, ENV, EnvValidationError } from './env.js';
|
|
8
|
-
import { parseCustomerConfigAsync, listCustomers, getCustomer, getDefaultCustomer, validateCustomerConfig } from './customerAsync.js';
|
|
8
|
+
import { parseCustomerConfigAsync, listCustomers, getCustomer, getDefaultCustomer, tryGetDefaultCustomer, getAllCustomers, validateCustomerConfig } from './customerAsync.js';
|
|
9
9
|
import { getValidAccessToken } from './auth.js';
|
|
10
10
|
import path from 'path';
|
|
11
11
|
// Enhanced error logging for CLI
|
|
@@ -126,7 +126,7 @@ async function main() {
|
|
|
126
126
|
const args = minimist(process.argv.slice(2));
|
|
127
127
|
const cmd = args._[0];
|
|
128
128
|
const verbose = Boolean(args.verbose || args.v);
|
|
129
|
-
// Parse customer configuration (async for API key array support)
|
|
129
|
+
// Parse customer configuration (async for API key array support)
|
|
130
130
|
let customerConfig;
|
|
131
131
|
try {
|
|
132
132
|
customerConfig = await parseCustomerConfigAsync(ENV, verbose);
|
|
@@ -140,7 +140,8 @@ async function main() {
|
|
|
140
140
|
process.exit(1);
|
|
141
141
|
}
|
|
142
142
|
// Handle customer selection
|
|
143
|
-
let selectedCustomer;
|
|
143
|
+
let selectedCustomer = null;
|
|
144
|
+
let allCustomers = [];
|
|
144
145
|
if (cmd === 'list-customers') {
|
|
145
146
|
const customers = listCustomers(customerConfig);
|
|
146
147
|
console.log('Available customers:');
|
|
@@ -160,13 +161,33 @@ async function main() {
|
|
|
160
161
|
selectedCustomer = customer;
|
|
161
162
|
}
|
|
162
163
|
else {
|
|
163
|
-
try
|
|
164
|
-
|
|
164
|
+
// For pull command, try to get default but fall back to all customers if multiple exist
|
|
165
|
+
if (cmd === 'pull') {
|
|
166
|
+
try {
|
|
167
|
+
selectedCustomer = tryGetDefaultCustomer(customerConfig);
|
|
168
|
+
if (!selectedCustomer) {
|
|
169
|
+
// Multiple customers exist with no default, pull from all
|
|
170
|
+
allCustomers = getAllCustomers(customerConfig);
|
|
171
|
+
if (verbose)
|
|
172
|
+
console.log(`📥 No default customer specified, pulling from all ${allCustomers.length} customers`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
177
|
+
console.error(message);
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|
|
165
180
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
181
|
+
else {
|
|
182
|
+
// For other commands, require explicit customer selection
|
|
183
|
+
try {
|
|
184
|
+
selectedCustomer = getDefaultCustomer(customerConfig);
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
188
|
+
console.error(message);
|
|
189
|
+
process.exit(1);
|
|
190
|
+
}
|
|
170
191
|
}
|
|
171
192
|
}
|
|
172
193
|
if (!cmd || ['help', '-h', '--help'].includes(cmd)) {
|
|
@@ -178,28 +199,29 @@ Usage:
|
|
|
178
199
|
newo list-customers # list available customers
|
|
179
200
|
newo meta [--customer <idn>] # get project metadata (debug)
|
|
180
201
|
newo import-akb <file> <persona_id> [--customer <idn>] # import AKB articles from file
|
|
181
|
-
|
|
202
|
+
|
|
182
203
|
Flags:
|
|
183
|
-
--customer <idn> # specify customer (if not set, uses default)
|
|
204
|
+
--customer <idn> # specify customer (if not set, uses default or all for pull)
|
|
184
205
|
--verbose, -v # enable detailed logging
|
|
185
|
-
|
|
206
|
+
|
|
186
207
|
Environment Variables:
|
|
187
208
|
NEWO_BASE_URL # NEWO API base URL (default: https://app.newo.ai)
|
|
188
209
|
NEWO_CUSTOMER_<IDN>_API_KEY # API key for customer <IDN>
|
|
189
210
|
NEWO_CUSTOMER_<IDN>_PROJECT_ID # Optional: specific project ID for customer
|
|
190
211
|
NEWO_DEFAULT_CUSTOMER # Optional: default customer to use
|
|
191
|
-
|
|
212
|
+
|
|
192
213
|
Multi-Customer Examples:
|
|
193
214
|
# Configure customers in .env:
|
|
194
215
|
NEWO_CUSTOMER_acme_API_KEY=your_acme_api_key
|
|
195
216
|
NEWO_CUSTOMER_globex_API_KEY=your_globex_api_key
|
|
196
217
|
NEWO_DEFAULT_CUSTOMER=acme
|
|
197
|
-
|
|
218
|
+
|
|
198
219
|
# Commands:
|
|
199
|
-
newo pull
|
|
220
|
+
newo pull # Pull from all customers (if no default set)
|
|
221
|
+
newo pull --customer acme # Pull projects for Acme only
|
|
200
222
|
newo push --customer globex # Push changes for Globex
|
|
201
223
|
newo status # Status for default customer
|
|
202
|
-
|
|
224
|
+
|
|
203
225
|
File Structure:
|
|
204
226
|
newo_customers/
|
|
205
227
|
├── acme/
|
|
@@ -211,15 +233,37 @@ File Structure:
|
|
|
211
233
|
`);
|
|
212
234
|
return;
|
|
213
235
|
}
|
|
236
|
+
if (cmd === 'pull') {
|
|
237
|
+
if (selectedCustomer) {
|
|
238
|
+
// Single customer pull
|
|
239
|
+
const accessToken = await getValidAccessToken(selectedCustomer);
|
|
240
|
+
const client = await makeClient(verbose, accessToken);
|
|
241
|
+
const projectId = selectedCustomer.projectId || null;
|
|
242
|
+
await pullAll(client, selectedCustomer, projectId, verbose);
|
|
243
|
+
}
|
|
244
|
+
else if (allCustomers.length > 0) {
|
|
245
|
+
// Multi-customer pull
|
|
246
|
+
console.log(`🔄 Pulling from ${allCustomers.length} customers...`);
|
|
247
|
+
for (const customer of allCustomers) {
|
|
248
|
+
console.log(`\n📥 Pulling from customer: ${customer.idn}`);
|
|
249
|
+
const accessToken = await getValidAccessToken(customer);
|
|
250
|
+
const client = await makeClient(verbose, accessToken);
|
|
251
|
+
const projectId = customer.projectId || null;
|
|
252
|
+
await pullAll(client, customer, projectId, verbose);
|
|
253
|
+
}
|
|
254
|
+
console.log(`\n✅ Pull completed for all ${allCustomers.length} customers`);
|
|
255
|
+
}
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
// For all other commands, require a single selected customer
|
|
259
|
+
if (!selectedCustomer) {
|
|
260
|
+
console.error('Customer selection required for this command');
|
|
261
|
+
process.exit(1);
|
|
262
|
+
}
|
|
214
263
|
// Get access token for the selected customer
|
|
215
264
|
const accessToken = await getValidAccessToken(selectedCustomer);
|
|
216
265
|
const client = await makeClient(verbose, accessToken);
|
|
217
|
-
if (cmd === '
|
|
218
|
-
// Use customer-specific project ID if set, otherwise pull all projects
|
|
219
|
-
const projectId = selectedCustomer.projectId || null;
|
|
220
|
-
await pullAll(client, selectedCustomer, projectId, verbose);
|
|
221
|
-
}
|
|
222
|
-
else if (cmd === 'push') {
|
|
266
|
+
if (cmd === 'push') {
|
|
223
267
|
await pushChanged(client, selectedCustomer, verbose);
|
|
224
268
|
}
|
|
225
269
|
else if (cmd === 'status') {
|
package/dist/customerAsync.d.ts
CHANGED
|
@@ -15,6 +15,14 @@ export declare function getCustomer(config: MultiCustomerConfig, customerIdn: st
|
|
|
15
15
|
* Get default customer or throw error if none
|
|
16
16
|
*/
|
|
17
17
|
export declare function getDefaultCustomer(config: MultiCustomerConfig): CustomerConfig;
|
|
18
|
+
/**
|
|
19
|
+
* Attempt to get default customer, return null if multiple customers exist without default
|
|
20
|
+
*/
|
|
21
|
+
export declare function tryGetDefaultCustomer(config: MultiCustomerConfig): CustomerConfig | null;
|
|
22
|
+
/**
|
|
23
|
+
* Get all customers as an array
|
|
24
|
+
*/
|
|
25
|
+
export declare function getAllCustomers(config: MultiCustomerConfig): CustomerConfig[];
|
|
18
26
|
/**
|
|
19
27
|
* Validate customer configuration
|
|
20
28
|
*/
|
package/dist/customerAsync.js
CHANGED
|
@@ -49,6 +49,34 @@ export function getDefaultCustomer(config) {
|
|
|
49
49
|
throw new Error(`Multiple customers configured but no default specified. Available: ${customerIdns.join(', ')}. ` +
|
|
50
50
|
`Set NEWO_DEFAULT_CUSTOMER or use --customer flag.`);
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Attempt to get default customer, return null if multiple customers exist without default
|
|
54
|
+
*/
|
|
55
|
+
export function tryGetDefaultCustomer(config) {
|
|
56
|
+
if (config.defaultCustomer) {
|
|
57
|
+
const customer = getCustomer(config, config.defaultCustomer);
|
|
58
|
+
if (customer)
|
|
59
|
+
return customer;
|
|
60
|
+
}
|
|
61
|
+
const customerIdns = listCustomers(config);
|
|
62
|
+
if (customerIdns.length === 1) {
|
|
63
|
+
const firstCustomerIdn = customerIdns[0];
|
|
64
|
+
if (firstCustomerIdn) {
|
|
65
|
+
return config.customers[firstCustomerIdn];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (customerIdns.length === 0) {
|
|
69
|
+
throw new Error('No customers configured. Please set NEWO_API_KEYS or NEWO_CUSTOMER_[IDN]_API_KEY in your .env file.');
|
|
70
|
+
}
|
|
71
|
+
// Return null if multiple customers exist without default (don't throw)
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get all customers as an array
|
|
76
|
+
*/
|
|
77
|
+
export function getAllCustomers(config) {
|
|
78
|
+
return listCustomers(config).map(idn => getCustomer(config, idn));
|
|
79
|
+
}
|
|
52
80
|
/**
|
|
53
81
|
* Validate customer configuration
|
|
54
82
|
*/
|
package/dist/sync.js
CHANGED
|
@@ -368,7 +368,7 @@ async function generateFlowsYaml(client, customer, agents, verbose = false) {
|
|
|
368
368
|
forceQuotes: false
|
|
369
369
|
});
|
|
370
370
|
// Post-process to fix enum formatting
|
|
371
|
-
yamlContent = yamlContent.replace(/"(!enum "[^"]+")"/g, '$
|
|
371
|
+
yamlContent = yamlContent.replace(/"(!enum \\"([^"]+)\\")"/g, '!enum "$2"');
|
|
372
372
|
const yamlPath = flowsYamlPath(customer.idn);
|
|
373
373
|
await writeFileSafe(yamlPath, yamlContent);
|
|
374
374
|
console.log(`✓ Generated flows.yaml`);
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "newo",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "NEWO CLI: sync AI Agent skills between NEWO platform and local files. Multi-customer workspaces, Git-first workflows, comprehensive project management.",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"bin": {
|
|
6
7
|
"newo": "dist/cli.js"
|
|
7
8
|
},
|
package/src/cli.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { makeClient, getProjectMeta, importAkbArticle } from './api.js';
|
|
|
5
5
|
import { pullAll, pushChanged, status } from './sync.js';
|
|
6
6
|
import { parseAkbFile, prepareArticlesForImport } from './akb.js';
|
|
7
7
|
import { initializeEnvironment, ENV, EnvValidationError } from './env.js';
|
|
8
|
-
import { parseCustomerConfigAsync, listCustomers, getCustomer, getDefaultCustomer, validateCustomerConfig } from './customerAsync.js';
|
|
8
|
+
import { parseCustomerConfigAsync, listCustomers, getCustomer, getDefaultCustomer, tryGetDefaultCustomer, getAllCustomers, validateCustomerConfig } from './customerAsync.js';
|
|
9
9
|
import { getValidAccessToken } from './auth.js';
|
|
10
10
|
import path from 'path';
|
|
11
11
|
import type { CliArgs, NewoApiError, CustomerConfig } from './types.js';
|
|
@@ -131,7 +131,7 @@ async function main(): Promise<void> {
|
|
|
131
131
|
const cmd = args._[0];
|
|
132
132
|
const verbose = Boolean(args.verbose || args.v);
|
|
133
133
|
|
|
134
|
-
// Parse customer configuration (async for API key array support)
|
|
134
|
+
// Parse customer configuration (async for API key array support)
|
|
135
135
|
let customerConfig;
|
|
136
136
|
try {
|
|
137
137
|
customerConfig = await parseCustomerConfigAsync(ENV as any, verbose);
|
|
@@ -145,8 +145,9 @@ async function main(): Promise<void> {
|
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
// Handle customer selection
|
|
148
|
-
let selectedCustomer: CustomerConfig;
|
|
149
|
-
|
|
148
|
+
let selectedCustomer: CustomerConfig | null = null;
|
|
149
|
+
let allCustomers: CustomerConfig[] = [];
|
|
150
|
+
|
|
150
151
|
if (cmd === 'list-customers') {
|
|
151
152
|
const customers = listCustomers(customerConfig);
|
|
152
153
|
console.log('Available customers:');
|
|
@@ -156,7 +157,7 @@ async function main(): Promise<void> {
|
|
|
156
157
|
}
|
|
157
158
|
return;
|
|
158
159
|
}
|
|
159
|
-
|
|
160
|
+
|
|
160
161
|
if (args.customer) {
|
|
161
162
|
const customer = getCustomer(customerConfig, args.customer as string);
|
|
162
163
|
if (!customer) {
|
|
@@ -166,12 +167,29 @@ async function main(): Promise<void> {
|
|
|
166
167
|
}
|
|
167
168
|
selectedCustomer = customer;
|
|
168
169
|
} else {
|
|
169
|
-
try
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
170
|
+
// For pull command, try to get default but fall back to all customers if multiple exist
|
|
171
|
+
if (cmd === 'pull') {
|
|
172
|
+
try {
|
|
173
|
+
selectedCustomer = tryGetDefaultCustomer(customerConfig);
|
|
174
|
+
if (!selectedCustomer) {
|
|
175
|
+
// Multiple customers exist with no default, pull from all
|
|
176
|
+
allCustomers = getAllCustomers(customerConfig);
|
|
177
|
+
if (verbose) console.log(`📥 No default customer specified, pulling from all ${allCustomers.length} customers`);
|
|
178
|
+
}
|
|
179
|
+
} catch (error: unknown) {
|
|
180
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
181
|
+
console.error(message);
|
|
182
|
+
process.exit(1);
|
|
183
|
+
}
|
|
184
|
+
} else {
|
|
185
|
+
// For other commands, require explicit customer selection
|
|
186
|
+
try {
|
|
187
|
+
selectedCustomer = getDefaultCustomer(customerConfig);
|
|
188
|
+
} catch (error: unknown) {
|
|
189
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
190
|
+
console.error(message);
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
175
193
|
}
|
|
176
194
|
}
|
|
177
195
|
|
|
@@ -184,28 +202,29 @@ Usage:
|
|
|
184
202
|
newo list-customers # list available customers
|
|
185
203
|
newo meta [--customer <idn>] # get project metadata (debug)
|
|
186
204
|
newo import-akb <file> <persona_id> [--customer <idn>] # import AKB articles from file
|
|
187
|
-
|
|
205
|
+
|
|
188
206
|
Flags:
|
|
189
|
-
--customer <idn> # specify customer (if not set, uses default)
|
|
207
|
+
--customer <idn> # specify customer (if not set, uses default or all for pull)
|
|
190
208
|
--verbose, -v # enable detailed logging
|
|
191
|
-
|
|
209
|
+
|
|
192
210
|
Environment Variables:
|
|
193
211
|
NEWO_BASE_URL # NEWO API base URL (default: https://app.newo.ai)
|
|
194
212
|
NEWO_CUSTOMER_<IDN>_API_KEY # API key for customer <IDN>
|
|
195
213
|
NEWO_CUSTOMER_<IDN>_PROJECT_ID # Optional: specific project ID for customer
|
|
196
214
|
NEWO_DEFAULT_CUSTOMER # Optional: default customer to use
|
|
197
|
-
|
|
215
|
+
|
|
198
216
|
Multi-Customer Examples:
|
|
199
217
|
# Configure customers in .env:
|
|
200
218
|
NEWO_CUSTOMER_acme_API_KEY=your_acme_api_key
|
|
201
219
|
NEWO_CUSTOMER_globex_API_KEY=your_globex_api_key
|
|
202
220
|
NEWO_DEFAULT_CUSTOMER=acme
|
|
203
|
-
|
|
221
|
+
|
|
204
222
|
# Commands:
|
|
205
|
-
newo pull
|
|
223
|
+
newo pull # Pull from all customers (if no default set)
|
|
224
|
+
newo pull --customer acme # Pull projects for Acme only
|
|
206
225
|
newo push --customer globex # Push changes for Globex
|
|
207
226
|
newo status # Status for default customer
|
|
208
|
-
|
|
227
|
+
|
|
209
228
|
File Structure:
|
|
210
229
|
newo_customers/
|
|
211
230
|
├── acme/
|
|
@@ -218,15 +237,39 @@ File Structure:
|
|
|
218
237
|
return;
|
|
219
238
|
}
|
|
220
239
|
|
|
240
|
+
if (cmd === 'pull') {
|
|
241
|
+
if (selectedCustomer) {
|
|
242
|
+
// Single customer pull
|
|
243
|
+
const accessToken = await getValidAccessToken(selectedCustomer);
|
|
244
|
+
const client = await makeClient(verbose, accessToken);
|
|
245
|
+
const projectId = selectedCustomer.projectId || null;
|
|
246
|
+
await pullAll(client, selectedCustomer, projectId, verbose);
|
|
247
|
+
} else if (allCustomers.length > 0) {
|
|
248
|
+
// Multi-customer pull
|
|
249
|
+
console.log(`🔄 Pulling from ${allCustomers.length} customers...`);
|
|
250
|
+
for (const customer of allCustomers) {
|
|
251
|
+
console.log(`\n📥 Pulling from customer: ${customer.idn}`);
|
|
252
|
+
const accessToken = await getValidAccessToken(customer);
|
|
253
|
+
const client = await makeClient(verbose, accessToken);
|
|
254
|
+
const projectId = customer.projectId || null;
|
|
255
|
+
await pullAll(client, customer, projectId, verbose);
|
|
256
|
+
}
|
|
257
|
+
console.log(`\n✅ Pull completed for all ${allCustomers.length} customers`);
|
|
258
|
+
}
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// For all other commands, require a single selected customer
|
|
263
|
+
if (!selectedCustomer) {
|
|
264
|
+
console.error('Customer selection required for this command');
|
|
265
|
+
process.exit(1);
|
|
266
|
+
}
|
|
267
|
+
|
|
221
268
|
// Get access token for the selected customer
|
|
222
269
|
const accessToken = await getValidAccessToken(selectedCustomer);
|
|
223
270
|
const client = await makeClient(verbose, accessToken);
|
|
224
271
|
|
|
225
|
-
if (cmd === '
|
|
226
|
-
// Use customer-specific project ID if set, otherwise pull all projects
|
|
227
|
-
const projectId = selectedCustomer.projectId || null;
|
|
228
|
-
await pullAll(client, selectedCustomer, projectId, verbose);
|
|
229
|
-
} else if (cmd === 'push') {
|
|
272
|
+
if (cmd === 'push') {
|
|
230
273
|
await pushChanged(client, selectedCustomer, verbose);
|
|
231
274
|
} else if (cmd === 'status') {
|
|
232
275
|
await status(selectedCustomer, verbose);
|
package/src/customerAsync.ts
CHANGED
|
@@ -40,7 +40,7 @@ export function getDefaultCustomer(config: MultiCustomerConfig): CustomerConfig
|
|
|
40
40
|
const customer = getCustomer(config, config.defaultCustomer);
|
|
41
41
|
if (customer) return customer;
|
|
42
42
|
}
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
const customerIdns = listCustomers(config);
|
|
45
45
|
if (customerIdns.length === 1) {
|
|
46
46
|
const firstCustomerIdn = customerIdns[0];
|
|
@@ -48,17 +48,49 @@ export function getDefaultCustomer(config: MultiCustomerConfig): CustomerConfig
|
|
|
48
48
|
return config.customers[firstCustomerIdn]!;
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
if (customerIdns.length === 0) {
|
|
53
53
|
throw new Error('No customers configured. Please set NEWO_API_KEYS or NEWO_CUSTOMER_[IDN]_API_KEY in your .env file.');
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
throw new Error(
|
|
57
57
|
`Multiple customers configured but no default specified. Available: ${customerIdns.join(', ')}. ` +
|
|
58
58
|
`Set NEWO_DEFAULT_CUSTOMER or use --customer flag.`
|
|
59
59
|
);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Attempt to get default customer, return null if multiple customers exist without default
|
|
64
|
+
*/
|
|
65
|
+
export function tryGetDefaultCustomer(config: MultiCustomerConfig): CustomerConfig | null {
|
|
66
|
+
if (config.defaultCustomer) {
|
|
67
|
+
const customer = getCustomer(config, config.defaultCustomer);
|
|
68
|
+
if (customer) return customer;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const customerIdns = listCustomers(config);
|
|
72
|
+
if (customerIdns.length === 1) {
|
|
73
|
+
const firstCustomerIdn = customerIdns[0];
|
|
74
|
+
if (firstCustomerIdn) {
|
|
75
|
+
return config.customers[firstCustomerIdn]!;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (customerIdns.length === 0) {
|
|
80
|
+
throw new Error('No customers configured. Please set NEWO_API_KEYS or NEWO_CUSTOMER_[IDN]_API_KEY in your .env file.');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Return null if multiple customers exist without default (don't throw)
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Get all customers as an array
|
|
89
|
+
*/
|
|
90
|
+
export function getAllCustomers(config: MultiCustomerConfig): CustomerConfig[] {
|
|
91
|
+
return listCustomers(config).map(idn => getCustomer(config, idn)!);
|
|
92
|
+
}
|
|
93
|
+
|
|
62
94
|
/**
|
|
63
95
|
* Validate customer configuration
|
|
64
96
|
*/
|
package/src/sync.ts
CHANGED
|
@@ -439,7 +439,7 @@ async function generateFlowsYaml(
|
|
|
439
439
|
});
|
|
440
440
|
|
|
441
441
|
// Post-process to fix enum formatting
|
|
442
|
-
yamlContent = yamlContent.replace(/"(!enum "[^"]+")"/g, '$
|
|
442
|
+
yamlContent = yamlContent.replace(/"(!enum \\"([^"]+)\\")"/g, '!enum "$2"');
|
|
443
443
|
|
|
444
444
|
const yamlPath = flowsYamlPath(customer.idn);
|
|
445
445
|
await writeFileSafe(yamlPath, yamlContent);
|