newo 3.6.0 → 3.6.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
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.6.2] - 2026-04-23
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **`attributes.yaml` YAML escaping**: The attribute serializer previously ran `.replace(/\\"/g, '"')` as a "prettify" post-processing step, which stripped legitimate YAML escape characters from double-quoted scalars. Values containing double quotes (e.g. `["+37410333310"]`) were written as invalid YAML like `value: "["+37410333310"]"` — rejected by `yaml.load` with `bad indentation of a mapping entry`. This made `newo push --format newo_v2` unable to parse customer/project attribute files at all, and long compiled values (e.g. AMI) broke on the first embedded quote. The serializer now uses the existing `patchYamlToPyyaml` post-processor (already used on the V2 path) to convert JSON-like double-quoted values to single-quoted form (`value: '["+37410333310"]'`) and handle long-line wrapping in pyyaml style. Fix applied in both `src/sync/attributes.ts` and `src/domain/strategies/sync/AttributeSyncStrategy.ts`. Added 11 round-trip regression tests.
|
|
15
|
+
|
|
16
|
+
## [3.6.1] - 2026-04-14
|
|
17
|
+
|
|
18
|
+
### Documentation
|
|
19
|
+
|
|
20
|
+
- Update README.md with V2 format, libraries, and `newo export` documentation for npm package page
|
|
21
|
+
|
|
10
22
|
## [3.6.0] - 2026-04-13
|
|
11
23
|
|
|
12
24
|
### Added
|
|
@@ -988,7 +1000,8 @@ Another Item: $Price [Modifiers: modifier3]
|
|
|
988
1000
|
- GitHub Actions CI/CD integration
|
|
989
1001
|
- Robust authentication with token refresh
|
|
990
1002
|
|
|
991
|
-
[Unreleased]: https://github.com/sabbah13/newo-cli/compare/v3.
|
|
1003
|
+
[Unreleased]: https://github.com/sabbah13/newo-cli/compare/v3.6.2...HEAD
|
|
1004
|
+
[3.6.2]: https://github.com/sabbah13/newo-cli/compare/v3.6.1...v3.6.2
|
|
992
1005
|
[3.3.0]: https://github.com/sabbah13/newo-cli/compare/v3.2.0...v3.3.0
|
|
993
1006
|
[3.2.0]: https://github.com/sabbah13/newo-cli/compare/v3.1.0...v3.2.0
|
|
994
1007
|
[3.1.0]: https://github.com/sabbah13/newo-cli/compare/v3.0.0...v3.1.0
|
package/README.md
CHANGED
|
@@ -8,22 +8,22 @@
|
|
|
8
8
|
**NEWO CLI** - Professional command-line tool for NEWO AI Agent development. Features **modular architecture**, **IDN-based file management**, and **comprehensive multi-customer support**.
|
|
9
9
|
|
|
10
10
|
Sync NEWO "Project → Agent → Flow → Skills" structure to local files with:
|
|
11
|
+
- 🆕 **Dual format support** (v3.6.0) - `cli_v1` (native) and `newo_v2` (platform compatible), auto-detected per customer
|
|
12
|
+
- 🆕 **Libraries** (v3.6.0) - Pull/push shared reusable skills across agents within a project
|
|
13
|
+
- 🆕 **Bulk export** (v3.6.0) - `newo export` downloads complete V2 ZIP from platform
|
|
11
14
|
- 🚀 **Account migration** - Fully automated account copying with 100% accuracy
|
|
12
15
|
- 🏗️ **Complete entity management** - Create, edit, and delete agents, flows, skills, events, and states
|
|
13
16
|
- 🔄 **Intelligent synchronization** - Pull projects, attributes, and conversations automatically
|
|
14
|
-
- 🎯 **IDN-based naming** - Skills named as `{skillIdn}.jinja/.guidance`
|
|
17
|
+
- 🎯 **IDN-based naming** - Skills named as `{skillIdn}.jinja/.guidance` or `{skillIdn}.nsl/.nslg`
|
|
15
18
|
- 📊 **Real-time progress** - Live progress tracking during large operations (1,000+ skills)
|
|
16
19
|
- 🏢 **Multi-customer workspaces** - Work with multiple NEWO accounts simultaneously
|
|
17
|
-
- 📁 **Hierarchical structure** - Complete project metadata and organized file structure
|
|
18
20
|
- 🔐 **Secure authentication** - API key-based auth with automatic token refresh
|
|
19
21
|
- ⚡ **Smart change detection** - SHA256-based efficient sync with hash consistency
|
|
20
|
-
-
|
|
21
|
-
- 🧠 **AI skill formats** - Support for `.guidance` (AI prompts) and `.jinja` (NSL templates)
|
|
22
|
+
- 🧠 **AI skill formats** - Support for `.guidance`/`.jinja` (V1) and `.nslg`/`.nsl` (V2)
|
|
22
23
|
- 📡 **Webhook automation** - Automatic webhook creation from YAML configuration
|
|
23
24
|
- 📊 **Knowledge base import** - Bulk import AKB articles from structured text files
|
|
24
25
|
- 💬 **Conversation history** - Extract and sync user conversations and personas
|
|
25
26
|
- 🧪 **Sandbox testing** - Interactive agent testing with conversation continuation
|
|
26
|
-
- ✅ **Migration verification** - Automated validation of migration completeness
|
|
27
27
|
- 🔧 **CI/CD ready** - GitHub Actions integration for automated deployments
|
|
28
28
|
|
|
29
29
|
---
|
|
@@ -143,15 +143,33 @@ NEWO_REFRESH_URL=custom_refresh_endpoint # Custom refresh endpoint
|
|
|
143
143
|
|
|
144
144
|
| Command | Description | Features |
|
|
145
145
|
|---------|-------------|----------|
|
|
146
|
-
| `newo pull` | Download projects + attributes +
|
|
147
|
-
| `newo push` | Upload local changes to NEWO | •
|
|
148
|
-
| `newo status` | Show modified files
|
|
149
|
-
| `newo
|
|
146
|
+
| `newo pull [--format <fmt>]` | Download projects + attributes + libraries | • Dual format: `cli_v1` / `newo_v2`<br>• Auto-detects format per customer<br>• Real-time progress tracking (1,000+ skills)<br>• IDN-based file naming<br>• `--force` for silent overwrite |
|
|
147
|
+
| `newo push [--format <fmt>]` | Upload local changes to NEWO | • Works with both formats<br>• Hash-based change detection<br>• Library skill updates<br>• Publishes flows automatically |
|
|
148
|
+
| `newo status [--format <fmt>]` | Show modified files | • Format-aware status<br>• Multiple file warnings<br>• Per-customer status |
|
|
149
|
+
| `newo export [--output <file>]` | Download V2 bulk ZIP from platform | • Complete organization export<br>• Projects, agents, flows, skills, attributes, AKB<br>• Compatible with platform UI import |
|
|
150
|
+
| `newo sandbox` | Test agents in sandbox chat mode | • Single-command mode for automation<br>• Multi-turn conversation support<br>• Debug info for agent development |
|
|
150
151
|
| `newo conversations` | Pull conversation history | • User personas and chat history<br>• YAML format output<br>• Pagination support |
|
|
151
152
|
| `newo list-customers` | List configured customers | • Shows default customer<br>• Multi-customer discovery |
|
|
152
153
|
| `newo import-akb` | Import knowledge base articles | • Structured text parsing<br>• Bulk article import<br>• Validation and error reporting |
|
|
153
154
|
| `newo meta` | Get project metadata (debug) | • Project structure analysis<br>• Metadata validation |
|
|
154
155
|
|
|
156
|
+
### V2 Format Support (NEW v3.6.0)
|
|
157
|
+
|
|
158
|
+
The CLI supports two formats that coexist in the same workspace:
|
|
159
|
+
|
|
160
|
+
- **`cli_v1`** (default) - Native CLI format with per-entity metadata files, `.guidance`/`.jinja` extensions
|
|
161
|
+
- **`newo_v2`** - Platform import/export format, `.nslg`/`.nsl` extensions, compatible with SuperAgent repository and NEWO platform export ZIPs
|
|
162
|
+
|
|
163
|
+
**Format is auto-detected per customer** from filesystem markers (`import_version.txt` = V2, `projects/` dir = V1). Override per-command with `--format newo_v2` or set persistent default with `NEWO_FORMAT=newo_v2` in `.env`.
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
newo pull --format newo_v2 # Pull in V2 format
|
|
167
|
+
newo export --output backup.zip # Bulk V2 ZIP download
|
|
168
|
+
newo push --format newo_v2 # Push from V2 format project
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Round-trip tested against real SuperAgent export: 1426/1426 files, 1331 scripts byte-identical, zero data loss on platform import.
|
|
172
|
+
|
|
155
173
|
### Account Migration Commands
|
|
156
174
|
|
|
157
175
|
**Enterprise-grade account migration with 100% automation:**
|
|
@@ -14,6 +14,7 @@ import yaml from 'js-yaml';
|
|
|
14
14
|
import path from 'path';
|
|
15
15
|
import { getCustomerAttributes, getProjectAttributes, updateCustomerAttribute, updateProjectAttribute, listProjects } from '../../../api.js';
|
|
16
16
|
import { writeFileSafe, customerAttributesPath, customerAttributesMapPath } from '../../../fsutil.js';
|
|
17
|
+
import { patchYamlToPyyaml } from '../../../format/yaml-patch.js';
|
|
17
18
|
import { sha256, saveHashes, loadHashes } from '../../../hash.js';
|
|
18
19
|
/**
|
|
19
20
|
* AttributeSyncStrategy - Handles attribute synchronization
|
|
@@ -171,18 +172,20 @@ export class AttributeSyncStrategy {
|
|
|
171
172
|
...attr,
|
|
172
173
|
value_type: `__ENUM_PLACEHOLDER_${attr.value_type}__`
|
|
173
174
|
}));
|
|
175
|
+
// Emit YAML without folding/wrapping; patchYamlToPyyaml handles long-line
|
|
176
|
+
// wrapping and converts JSON-like double-quoted values to single-quoted
|
|
177
|
+
// (so strings containing `"` stay valid YAML on reload).
|
|
174
178
|
let yamlContent = yaml.dump({ attributes: attributesWithPlaceholders }, {
|
|
175
179
|
indent: 2,
|
|
176
180
|
quotingType: '"',
|
|
177
181
|
forceQuotes: false,
|
|
178
|
-
lineWidth:
|
|
182
|
+
lineWidth: -1,
|
|
179
183
|
noRefs: true,
|
|
180
184
|
sortKeys: false,
|
|
181
|
-
flowLevel: -1
|
|
185
|
+
flowLevel: -1,
|
|
182
186
|
});
|
|
183
|
-
// Replace placeholders with enum syntax
|
|
184
187
|
yamlContent = yamlContent.replace(/__ENUM_PLACEHOLDER_(\w+)__/g, '!enum "AttributeValueTypes.$1"');
|
|
185
|
-
yamlContent = yamlContent
|
|
188
|
+
yamlContent = patchYamlToPyyaml(yamlContent);
|
|
186
189
|
return yamlContent;
|
|
187
190
|
}
|
|
188
191
|
/**
|
package/dist/sync/attributes.js
CHANGED
|
@@ -6,6 +6,7 @@ import { writeFileSafe, customerAttributesPath, customerAttributesMapPath, custo
|
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import fs from 'fs-extra';
|
|
8
8
|
import yaml from 'js-yaml';
|
|
9
|
+
import { patchYamlToPyyaml } from '../format/yaml-patch.js';
|
|
9
10
|
/**
|
|
10
11
|
* Save customer attributes to YAML format and return content for hashing
|
|
11
12
|
*/
|
|
@@ -55,23 +56,22 @@ export async function saveCustomerAttributes(client, customer, verbose = false)
|
|
|
55
56
|
const attributesYaml = {
|
|
56
57
|
attributes: cleanAttributes
|
|
57
58
|
};
|
|
58
|
-
//
|
|
59
|
+
// Emit YAML without folding/wrapping; patchYamlToPyyaml handles long-line
|
|
60
|
+
// wrapping and converts JSON-like double-quoted values to single-quoted
|
|
61
|
+
// (so strings containing `"` stay valid YAML on reload).
|
|
59
62
|
let yamlContent = yaml.dump(attributesYaml, {
|
|
60
63
|
indent: 2,
|
|
61
64
|
quotingType: '"',
|
|
62
65
|
forceQuotes: false,
|
|
63
|
-
lineWidth:
|
|
66
|
+
lineWidth: -1,
|
|
64
67
|
noRefs: true,
|
|
65
68
|
sortKeys: false,
|
|
66
|
-
flowLevel: -1,
|
|
67
|
-
styles: {
|
|
68
|
-
'!!str': 'folded' // Use folded style for better line wrapping of long strings
|
|
69
|
-
}
|
|
69
|
+
flowLevel: -1,
|
|
70
70
|
});
|
|
71
|
-
// Post-process to fix enum format
|
|
71
|
+
// Post-process to fix enum format
|
|
72
72
|
yamlContent = yamlContent.replace(/__ENUM_PLACEHOLDER_(\w+)__/g, '!enum "AttributeValueTypes.$1"');
|
|
73
|
-
//
|
|
74
|
-
yamlContent = yamlContent
|
|
73
|
+
// Convert JSON-like double-quoted values to single-quoted and wrap long lines
|
|
74
|
+
yamlContent = patchYamlToPyyaml(yamlContent);
|
|
75
75
|
// Save all files: attributes.yaml, ID mapping, and backup for diff tracking
|
|
76
76
|
await writeFileSafe(customerAttributesPath(customer.idn), yamlContent);
|
|
77
77
|
await writeFileSafe(customerAttributesMapPath(customer.idn), JSON.stringify(idMapping, null, 2));
|
|
@@ -139,19 +139,19 @@ export async function saveProjectAttributes(client, customer, projectId, project
|
|
|
139
139
|
const attributesYaml = {
|
|
140
140
|
attributes: cleanAttributes
|
|
141
141
|
};
|
|
142
|
-
//
|
|
142
|
+
// Emit YAML without folding/wrapping; patchYamlToPyyaml handles long-line
|
|
143
|
+
// wrapping and converts JSON-like double-quoted values to single-quoted.
|
|
143
144
|
let yamlContent = yaml.dump(attributesYaml, {
|
|
144
145
|
indent: 2,
|
|
145
146
|
quotingType: '"',
|
|
146
147
|
forceQuotes: false,
|
|
147
|
-
lineWidth:
|
|
148
|
+
lineWidth: -1,
|
|
148
149
|
noRefs: true,
|
|
149
150
|
sortKeys: false,
|
|
150
|
-
flowLevel: -1
|
|
151
|
+
flowLevel: -1,
|
|
151
152
|
});
|
|
152
|
-
// Post-process to fix enum format
|
|
153
153
|
yamlContent = yamlContent.replace(/__ENUM_PLACEHOLDER_(\w+)__/g, '!enum "AttributeValueTypes.$1"');
|
|
154
|
-
yamlContent = yamlContent
|
|
154
|
+
yamlContent = patchYamlToPyyaml(yamlContent);
|
|
155
155
|
// Save to project directory
|
|
156
156
|
const customerDir = path.join(process.cwd(), 'newo_customers', customer.idn);
|
|
157
157
|
const projectDir = path.join(customerDir, 'projects', projectIdn);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "newo",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.2",
|
|
4
4
|
"description": "NEWO CLI: Professional command-line tool with modular architecture for NEWO AI Agent development. Features account migration, integration management, webhook automation, AKB knowledge base, project attributes, sandbox testing, IDN-based file management, real-time progress tracking, intelligent sync operations, and comprehensive multi-customer support.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
customerAttributesPath,
|
|
39
39
|
customerAttributesMapPath
|
|
40
40
|
} from '../../../fsutil.js';
|
|
41
|
+
import { patchYamlToPyyaml } from '../../../format/yaml-patch.js';
|
|
41
42
|
import { sha256, saveHashes, loadHashes } from '../../../hash.js';
|
|
42
43
|
|
|
43
44
|
/**
|
|
@@ -251,19 +252,21 @@ export class AttributeSyncStrategy implements ISyncStrategy<CustomerAttributesRe
|
|
|
251
252
|
value_type: `__ENUM_PLACEHOLDER_${attr.value_type}__`
|
|
252
253
|
}));
|
|
253
254
|
|
|
255
|
+
// Emit YAML without folding/wrapping; patchYamlToPyyaml handles long-line
|
|
256
|
+
// wrapping and converts JSON-like double-quoted values to single-quoted
|
|
257
|
+
// (so strings containing `"` stay valid YAML on reload).
|
|
254
258
|
let yamlContent = yaml.dump({ attributes: attributesWithPlaceholders }, {
|
|
255
259
|
indent: 2,
|
|
256
260
|
quotingType: '"',
|
|
257
261
|
forceQuotes: false,
|
|
258
|
-
lineWidth:
|
|
262
|
+
lineWidth: -1,
|
|
259
263
|
noRefs: true,
|
|
260
264
|
sortKeys: false,
|
|
261
|
-
flowLevel: -1
|
|
265
|
+
flowLevel: -1,
|
|
262
266
|
});
|
|
263
267
|
|
|
264
|
-
// Replace placeholders with enum syntax
|
|
265
268
|
yamlContent = yamlContent.replace(/__ENUM_PLACEHOLDER_(\w+)__/g, '!enum "AttributeValueTypes.$1"');
|
|
266
|
-
yamlContent = yamlContent
|
|
269
|
+
yamlContent = patchYamlToPyyaml(yamlContent);
|
|
267
270
|
|
|
268
271
|
return yamlContent;
|
|
269
272
|
}
|
package/src/sync/attributes.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import path from 'path';
|
|
12
12
|
import fs from 'fs-extra';
|
|
13
13
|
import yaml from 'js-yaml';
|
|
14
|
+
import { patchYamlToPyyaml } from '../format/yaml-patch.js';
|
|
14
15
|
import type { AxiosInstance } from 'axios';
|
|
15
16
|
import type { CustomerConfig } from '../types.js';
|
|
16
17
|
|
|
@@ -72,25 +73,24 @@ export async function saveCustomerAttributes(
|
|
|
72
73
|
attributes: cleanAttributes
|
|
73
74
|
};
|
|
74
75
|
|
|
75
|
-
//
|
|
76
|
+
// Emit YAML without folding/wrapping; patchYamlToPyyaml handles long-line
|
|
77
|
+
// wrapping and converts JSON-like double-quoted values to single-quoted
|
|
78
|
+
// (so strings containing `"` stay valid YAML on reload).
|
|
76
79
|
let yamlContent = yaml.dump(attributesYaml, {
|
|
77
80
|
indent: 2,
|
|
78
81
|
quotingType: '"',
|
|
79
82
|
forceQuotes: false,
|
|
80
|
-
lineWidth:
|
|
83
|
+
lineWidth: -1,
|
|
81
84
|
noRefs: true,
|
|
82
85
|
sortKeys: false,
|
|
83
|
-
flowLevel: -1,
|
|
84
|
-
styles: {
|
|
85
|
-
'!!str': 'folded' // Use folded style for better line wrapping of long strings
|
|
86
|
-
}
|
|
86
|
+
flowLevel: -1,
|
|
87
87
|
});
|
|
88
88
|
|
|
89
|
-
// Post-process to fix enum format
|
|
89
|
+
// Post-process to fix enum format
|
|
90
90
|
yamlContent = yamlContent.replace(/__ENUM_PLACEHOLDER_(\w+)__/g, '!enum "AttributeValueTypes.$1"');
|
|
91
91
|
|
|
92
|
-
//
|
|
93
|
-
yamlContent = yamlContent
|
|
92
|
+
// Convert JSON-like double-quoted values to single-quoted and wrap long lines
|
|
93
|
+
yamlContent = patchYamlToPyyaml(yamlContent);
|
|
94
94
|
|
|
95
95
|
// Save all files: attributes.yaml, ID mapping, and backup for diff tracking
|
|
96
96
|
await writeFileSafe(customerAttributesPath(customer.idn), yamlContent);
|
|
@@ -172,20 +172,20 @@ export async function saveProjectAttributes(
|
|
|
172
172
|
attributes: cleanAttributes
|
|
173
173
|
};
|
|
174
174
|
|
|
175
|
-
//
|
|
175
|
+
// Emit YAML without folding/wrapping; patchYamlToPyyaml handles long-line
|
|
176
|
+
// wrapping and converts JSON-like double-quoted values to single-quoted.
|
|
176
177
|
let yamlContent = yaml.dump(attributesYaml, {
|
|
177
178
|
indent: 2,
|
|
178
179
|
quotingType: '"',
|
|
179
180
|
forceQuotes: false,
|
|
180
|
-
lineWidth:
|
|
181
|
+
lineWidth: -1,
|
|
181
182
|
noRefs: true,
|
|
182
183
|
sortKeys: false,
|
|
183
|
-
flowLevel: -1
|
|
184
|
+
flowLevel: -1,
|
|
184
185
|
});
|
|
185
186
|
|
|
186
|
-
// Post-process to fix enum format
|
|
187
187
|
yamlContent = yamlContent.replace(/__ENUM_PLACEHOLDER_(\w+)__/g, '!enum "AttributeValueTypes.$1"');
|
|
188
|
-
yamlContent = yamlContent
|
|
188
|
+
yamlContent = patchYamlToPyyaml(yamlContent);
|
|
189
189
|
|
|
190
190
|
// Save to project directory
|
|
191
191
|
const customerDir = path.join(process.cwd(), 'newo_customers', customer.idn);
|