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.3.0...HEAD
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` for better organization
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
- - 🛡️ **File validation** - Multiple file detection with clear warnings and safe handling
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 + metadata | • Real-time progress tracking (966+ skills)<br>• IDN-based file naming<br>• Automatic attributes.yaml generation<br>• `--force` for silent overwrite |
147
- | `newo push` | Upload local changes to NEWO | • Smart file validation<br>• Multiple file detection<br>• Hash-based change detection<br>• Safe error handling |
148
- | `newo status` | Show modified files with details | • Multiple file warnings<br>• Detailed change analysis<br>• Clean state validation<br>• Per-customer status |
149
- | `newo sandbox` | Test agents in sandbox chat mode | • Single-command mode for automation<br>• Multi-turn conversation support<br>• Debug info for agent development<br>• Conversation continuation |
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: 80,
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.replace(/\\"/g, '"');
188
+ yamlContent = patchYamlToPyyaml(yamlContent);
186
189
  return yamlContent;
187
190
  }
188
191
  /**
@@ -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
- // Configure YAML output to match reference format exactly
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: 80, // Wrap long lines to match reference format
66
+ lineWidth: -1,
64
67
  noRefs: true,
65
68
  sortKeys: false,
66
- flowLevel: -1, // Never use flow syntax
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 and improve JSON string formatting
71
+ // Post-process to fix enum format
72
72
  yamlContent = yamlContent.replace(/__ENUM_PLACEHOLDER_(\w+)__/g, '!enum "AttributeValueTypes.$1"');
73
- // Fix JSON string formatting to match reference (remove escape characters)
74
- yamlContent = yamlContent.replace(/\\"/g, '"');
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
- // Configure YAML output
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: 80,
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.replace(/\\"/g, '"');
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.0",
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: 80,
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.replace(/\\"/g, '"');
269
+ yamlContent = patchYamlToPyyaml(yamlContent);
267
270
 
268
271
  return yamlContent;
269
272
  }
@@ -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
- // Configure YAML output to match reference format exactly
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: 80, // Wrap long lines to match reference format
83
+ lineWidth: -1,
81
84
  noRefs: true,
82
85
  sortKeys: false,
83
- flowLevel: -1, // Never use flow syntax
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 and improve JSON string formatting
89
+ // Post-process to fix enum format
90
90
  yamlContent = yamlContent.replace(/__ENUM_PLACEHOLDER_(\w+)__/g, '!enum "AttributeValueTypes.$1"');
91
91
 
92
- // Fix JSON string formatting to match reference (remove escape characters)
93
- yamlContent = yamlContent.replace(/\\"/g, '"');
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
- // Configure YAML output
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: 80,
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.replace(/\\"/g, '"');
188
+ yamlContent = patchYamlToPyyaml(yamlContent);
189
189
 
190
190
  // Save to project directory
191
191
  const customerDir = path.join(process.cwd(), 'newo_customers', customer.idn);