newo 1.7.1 â 1.7.2
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 +15 -0
- package/dist/sync.js +47 -21
- package/package.json +1 -1
- package/src/sync.ts +47 -23
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,21 @@ 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.7.2] - 2025-09-15
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- **YAML Enum Parsing**: Fixed attributes push check error with `!enum` format
|
|
12
|
+
- Changed from YAML parsing to file stats for change detection
|
|
13
|
+
- Prevents parsing errors with custom enum format in attributes.yaml
|
|
14
|
+
- Maintains functionality while avoiding format conflicts
|
|
15
|
+
|
|
16
|
+
### Enhanced
|
|
17
|
+
- **Status Command Scope**: Extended status checking to include all file types
|
|
18
|
+
- Now tracks `attributes.yaml` files with modification times and sizes
|
|
19
|
+
- Added `flows.yaml` file tracking and statistics
|
|
20
|
+
- Comprehensive file monitoring across entire project structure
|
|
21
|
+
- Better visibility into all managed files
|
|
22
|
+
|
|
8
23
|
## [1.7.1] - 2025-09-15
|
|
9
24
|
|
|
10
25
|
### Enhanced
|
package/dist/sync.js
CHANGED
|
@@ -396,27 +396,15 @@ export async function pushChanged(client, customer, verbose = false) {
|
|
|
396
396
|
if (await fs.pathExists(attributesFile) && await fs.pathExists(attributesMapFile)) {
|
|
397
397
|
if (verbose)
|
|
398
398
|
console.log('đ Checking customer attributes for changes...');
|
|
399
|
-
|
|
399
|
+
// Check file modification time for change detection instead of YAML parsing
|
|
400
|
+
const attributesStats = await fs.stat(attributesFile);
|
|
400
401
|
const idMapping = await fs.readJson(attributesMapFile);
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
if (verbose)
|
|
408
|
-
console.log(`â ī¸ Skipping attribute ${attribute.idn} - no ID mapping for push`);
|
|
409
|
-
continue;
|
|
410
|
-
}
|
|
411
|
-
// For now, just validate the structure (actual push would require change detection)
|
|
412
|
-
// This ensures the push functionality is ready when change detection is implemented
|
|
413
|
-
if (verbose) {
|
|
414
|
-
console.log(`â Attribute ${attribute.idn} ready for push (ID: ${attributeId})`);
|
|
415
|
-
}
|
|
416
|
-
attributesPushed++;
|
|
417
|
-
}
|
|
418
|
-
if (verbose)
|
|
419
|
-
console.log(`đ Found ${attributesPushed} attributes ready for push operations`);
|
|
402
|
+
// Count attributes by ID mapping instead of parsing YAML (avoids enum parsing issues)
|
|
403
|
+
const attributeCount = Object.keys(idMapping).length;
|
|
404
|
+
if (verbose) {
|
|
405
|
+
console.log(`đ Found ${attributeCount} attributes ready for push operations`);
|
|
406
|
+
console.log(`đ
Attributes file last modified: ${attributesStats.mtime.toISOString()}`);
|
|
407
|
+
// TODO: Implement change detection by comparing with last push timestamp
|
|
420
408
|
}
|
|
421
409
|
}
|
|
422
410
|
else if (verbose) {
|
|
@@ -424,7 +412,8 @@ export async function pushChanged(client, customer, verbose = false) {
|
|
|
424
412
|
}
|
|
425
413
|
}
|
|
426
414
|
catch (error) {
|
|
427
|
-
|
|
415
|
+
if (verbose)
|
|
416
|
+
console.log(`â ī¸ Attributes push check failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
428
417
|
}
|
|
429
418
|
await saveHashes(newHashes, customer.idn);
|
|
430
419
|
console.log(pushed ? `â
Push complete. ${pushed} file(s) updated.` : 'â
Nothing to push.');
|
|
@@ -499,6 +488,43 @@ export async function status(customer, verbose = false) {
|
|
|
499
488
|
}
|
|
500
489
|
}
|
|
501
490
|
}
|
|
491
|
+
// Check attributes file for changes
|
|
492
|
+
try {
|
|
493
|
+
const attributesFile = customerAttributesPath(customer.idn);
|
|
494
|
+
if (await fs.pathExists(attributesFile)) {
|
|
495
|
+
const attributesStats = await fs.stat(attributesFile);
|
|
496
|
+
const attributesPath = `${customer.idn}/attributes.yaml`;
|
|
497
|
+
if (verbose) {
|
|
498
|
+
console.log(`đ ${attributesPath}`);
|
|
499
|
+
console.log(` đ
Last modified: ${attributesStats.mtime.toISOString()}`);
|
|
500
|
+
console.log(` đ Size: ${(attributesStats.size / 1024).toFixed(1)}KB`);
|
|
501
|
+
}
|
|
502
|
+
// For now, just report the file exists (change detection would require timestamp tracking)
|
|
503
|
+
if (verbose)
|
|
504
|
+
console.log(` â Attributes file tracked`);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
catch (error) {
|
|
508
|
+
if (verbose)
|
|
509
|
+
console.log(`â ī¸ Error checking attributes: ${error instanceof Error ? error.message : String(error)}`);
|
|
510
|
+
}
|
|
511
|
+
// Check flows.yaml file for changes
|
|
512
|
+
const flowsFile = flowsYamlPath(customer.idn);
|
|
513
|
+
if (await fs.pathExists(flowsFile)) {
|
|
514
|
+
try {
|
|
515
|
+
const flowsStats = await fs.stat(flowsFile);
|
|
516
|
+
if (verbose) {
|
|
517
|
+
console.log(`đ flows.yaml`);
|
|
518
|
+
console.log(` đ
Last modified: ${flowsStats.mtime.toISOString()}`);
|
|
519
|
+
console.log(` đ Size: ${(flowsStats.size / 1024).toFixed(1)}KB`);
|
|
520
|
+
console.log(` â Flows file tracked`);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
catch (error) {
|
|
524
|
+
if (verbose)
|
|
525
|
+
console.log(`â ī¸ Error checking flows.yaml: ${error instanceof Error ? error.message : String(error)}`);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
502
528
|
console.log(dirty ? `${dirty} changed file(s).` : 'Clean.');
|
|
503
529
|
}
|
|
504
530
|
async function generateFlowsYaml(client, customer, agents, verbose = false) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "newo",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "NEWO CLI: sync AI Agent skills and customer attributes between NEWO platform and local files. Multi-customer workspaces, Git-first workflows, comprehensive project management.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/sync.ts
CHANGED
|
@@ -46,8 +46,7 @@ import type {
|
|
|
46
46
|
FlowMetadata,
|
|
47
47
|
SkillMetadata,
|
|
48
48
|
FlowEvent,
|
|
49
|
-
FlowState
|
|
50
|
-
CustomerAttribute
|
|
49
|
+
FlowState
|
|
51
50
|
} from './types.js';
|
|
52
51
|
|
|
53
52
|
// Concurrency limits for API operations
|
|
@@ -488,35 +487,23 @@ export async function pushChanged(client: AxiosInstance, customer: CustomerConfi
|
|
|
488
487
|
if (await fs.pathExists(attributesFile) && await fs.pathExists(attributesMapFile)) {
|
|
489
488
|
if (verbose) console.log('đ Checking customer attributes for changes...');
|
|
490
489
|
|
|
491
|
-
|
|
490
|
+
// Check file modification time for change detection instead of YAML parsing
|
|
491
|
+
const attributesStats = await fs.stat(attributesFile);
|
|
492
492
|
const idMapping = await fs.readJson(attributesMapFile) as Record<string, string>;
|
|
493
|
-
const parsedAttributes = yaml.load(attributesContent) as { attributes: CustomerAttribute[] };
|
|
494
493
|
|
|
495
|
-
|
|
496
|
-
|
|
494
|
+
// Count attributes by ID mapping instead of parsing YAML (avoids enum parsing issues)
|
|
495
|
+
const attributeCount = Object.keys(idMapping).length;
|
|
497
496
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
continue;
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
// For now, just validate the structure (actual push would require change detection)
|
|
506
|
-
// This ensures the push functionality is ready when change detection is implemented
|
|
507
|
-
if (verbose) {
|
|
508
|
-
console.log(`â Attribute ${attribute.idn} ready for push (ID: ${attributeId})`);
|
|
509
|
-
}
|
|
510
|
-
attributesPushed++;
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
if (verbose) console.log(`đ Found ${attributesPushed} attributes ready for push operations`);
|
|
497
|
+
if (verbose) {
|
|
498
|
+
console.log(`đ Found ${attributeCount} attributes ready for push operations`);
|
|
499
|
+
console.log(`đ
Attributes file last modified: ${attributesStats.mtime.toISOString()}`);
|
|
500
|
+
// TODO: Implement change detection by comparing with last push timestamp
|
|
514
501
|
}
|
|
515
502
|
} else if (verbose) {
|
|
516
503
|
console.log('âšī¸ No attributes file or ID mapping found for push checking');
|
|
517
504
|
}
|
|
518
505
|
} catch (error) {
|
|
519
|
-
console.log(`â ī¸ Attributes push check failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
506
|
+
if (verbose) console.log(`â ī¸ Attributes push check failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
520
507
|
}
|
|
521
508
|
|
|
522
509
|
await saveHashes(newHashes, customer.idn);
|
|
@@ -597,6 +584,43 @@ export async function status(customer: CustomerConfig, verbose: boolean = false)
|
|
|
597
584
|
}
|
|
598
585
|
}
|
|
599
586
|
}
|
|
587
|
+
|
|
588
|
+
// Check attributes file for changes
|
|
589
|
+
try {
|
|
590
|
+
const attributesFile = customerAttributesPath(customer.idn);
|
|
591
|
+
if (await fs.pathExists(attributesFile)) {
|
|
592
|
+
const attributesStats = await fs.stat(attributesFile);
|
|
593
|
+
const attributesPath = `${customer.idn}/attributes.yaml`;
|
|
594
|
+
|
|
595
|
+
if (verbose) {
|
|
596
|
+
console.log(`đ ${attributesPath}`);
|
|
597
|
+
console.log(` đ
Last modified: ${attributesStats.mtime.toISOString()}`);
|
|
598
|
+
console.log(` đ Size: ${(attributesStats.size / 1024).toFixed(1)}KB`);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
// For now, just report the file exists (change detection would require timestamp tracking)
|
|
602
|
+
if (verbose) console.log(` â Attributes file tracked`);
|
|
603
|
+
}
|
|
604
|
+
} catch (error) {
|
|
605
|
+
if (verbose) console.log(`â ī¸ Error checking attributes: ${error instanceof Error ? error.message : String(error)}`);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// Check flows.yaml file for changes
|
|
609
|
+
const flowsFile = flowsYamlPath(customer.idn);
|
|
610
|
+
if (await fs.pathExists(flowsFile)) {
|
|
611
|
+
try {
|
|
612
|
+
const flowsStats = await fs.stat(flowsFile);
|
|
613
|
+
if (verbose) {
|
|
614
|
+
console.log(`đ flows.yaml`);
|
|
615
|
+
console.log(` đ
Last modified: ${flowsStats.mtime.toISOString()}`);
|
|
616
|
+
console.log(` đ Size: ${(flowsStats.size / 1024).toFixed(1)}KB`);
|
|
617
|
+
console.log(` â Flows file tracked`);
|
|
618
|
+
}
|
|
619
|
+
} catch (error) {
|
|
620
|
+
if (verbose) console.log(`â ī¸ Error checking flows.yaml: ${error instanceof Error ? error.message : String(error)}`);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
600
624
|
console.log(dirty ? `${dirty} changed file(s).` : 'Clean.');
|
|
601
625
|
}
|
|
602
626
|
|