newo 2.0.0 → 2.0.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/dist/sync/projects.js +27 -12
- package/dist/sync/skill-files.d.ts +2 -1
- package/dist/sync/skill-files.js +6 -4
- package/package.json +1 -1
- package/src/sync/projects.ts +24 -11
- package/src/sync/skill-files.ts +10 -5
package/dist/sync/projects.js
CHANGED
|
@@ -48,9 +48,10 @@ export async function pullSingleProject(client, customer, projectId, verbose = f
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
const newHashes = {};
|
|
51
|
-
// Progress tracking
|
|
51
|
+
// Progress tracking and overwrite control
|
|
52
52
|
let totalSkills = 0;
|
|
53
53
|
let processedSkills = 0;
|
|
54
|
+
let globalOverwriteAll = silentOverwrite;
|
|
54
55
|
// Count total skills for progress tracking
|
|
55
56
|
for (const project of projects) {
|
|
56
57
|
const agents = await listAgents(client, project.id);
|
|
@@ -182,7 +183,7 @@ export async function pullSingleProject(client, customer, projectId, verbose = f
|
|
|
182
183
|
// Check if any existing file has the same content
|
|
183
184
|
hasContentMatch = existingFiles.some(file => !isContentDifferent(file.content, scriptContent));
|
|
184
185
|
if (hasContentMatch) {
|
|
185
|
-
// Content is the same -
|
|
186
|
+
// Content is the same - handle file naming
|
|
186
187
|
const matchingFile = existingFiles.find(file => !isContentDifferent(file.content, scriptContent));
|
|
187
188
|
const correctName = `${skill.idn}.${getExtensionForRunner(skill.runner_type)}`;
|
|
188
189
|
if (matchingFile && matchingFile.fileName !== correctName) {
|
|
@@ -192,30 +193,44 @@ export async function pullSingleProject(client, customer, projectId, verbose = f
|
|
|
192
193
|
console.log(` 🔄 Renamed ${matchingFile.fileName} → ${correctName}`);
|
|
193
194
|
}
|
|
194
195
|
else if (matchingFile && matchingFile.fileName === correctName) {
|
|
195
|
-
// Already has correct name and content
|
|
196
|
+
// Already has correct name and content - skip completely
|
|
196
197
|
shouldWrite = false;
|
|
197
198
|
newHashes[matchingFile.filePath] = sha256(scriptContent);
|
|
198
199
|
if (verbose)
|
|
199
200
|
console.log(` ✓ Content unchanged for ${skill.idn}, keeping existing file`);
|
|
200
201
|
}
|
|
201
202
|
}
|
|
202
|
-
else if (!
|
|
203
|
-
// Content is different, ask for overwrite
|
|
203
|
+
else if (!globalOverwriteAll) {
|
|
204
|
+
// Content is different, ask for overwrite unless global override is set
|
|
204
205
|
const existingFile = existingFiles[0];
|
|
205
|
-
const
|
|
206
|
-
if (
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
console.log(` ⚠️ Skipped overwrite for ${skill.idn}`);
|
|
206
|
+
const overwriteChoice = await askForOverwrite(skill.idn, existingFile.fileName, `${skill.idn}.${getExtensionForRunner(skill.runner_type)}`);
|
|
207
|
+
if (overwriteChoice === 'quit') {
|
|
208
|
+
console.log('❌ Pull operation cancelled by user');
|
|
209
|
+
process.exit(0);
|
|
210
210
|
}
|
|
211
|
-
else {
|
|
212
|
-
|
|
211
|
+
else if (overwriteChoice === 'all') {
|
|
212
|
+
globalOverwriteAll = true;
|
|
213
|
+
// Continue with overwrite
|
|
213
214
|
for (const file of existingFiles) {
|
|
214
215
|
await fs.remove(file.filePath);
|
|
215
216
|
if (verbose)
|
|
216
217
|
console.log(` 🗑️ Removed ${file.fileName}`);
|
|
217
218
|
}
|
|
218
219
|
}
|
|
220
|
+
else if (overwriteChoice === 'yes') {
|
|
221
|
+
// Single overwrite
|
|
222
|
+
for (const file of existingFiles) {
|
|
223
|
+
await fs.remove(file.filePath);
|
|
224
|
+
if (verbose)
|
|
225
|
+
console.log(` 🗑️ Removed ${file.fileName}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
// User said no
|
|
230
|
+
shouldWrite = false;
|
|
231
|
+
if (verbose)
|
|
232
|
+
console.log(` ⚠️ Skipped overwrite for ${skill.idn}`);
|
|
233
|
+
}
|
|
219
234
|
}
|
|
220
235
|
else {
|
|
221
236
|
// Silent overwrite mode - remove existing files
|
|
@@ -35,8 +35,9 @@ export declare function getSingleSkillFile(customerIdn: string, projectIdn: stri
|
|
|
35
35
|
* Check if skill script content is different from target content
|
|
36
36
|
*/
|
|
37
37
|
export declare function isContentDifferent(existingContent: string, newContent: string): boolean;
|
|
38
|
+
export type OverwriteChoice = 'yes' | 'no' | 'all' | 'quit';
|
|
38
39
|
/**
|
|
39
40
|
* Interactive overwrite confirmation
|
|
40
41
|
*/
|
|
41
|
-
export declare function askForOverwrite(skillIdn: string, existingFile: string, newFile: string): Promise<
|
|
42
|
+
export declare function askForOverwrite(skillIdn: string, existingFile: string, newFile: string): Promise<OverwriteChoice>;
|
|
42
43
|
//# sourceMappingURL=skill-files.d.ts.map
|
package/dist/sync/skill-files.js
CHANGED
|
@@ -110,12 +110,14 @@ export async function askForOverwrite(skillIdn, existingFile, newFile) {
|
|
|
110
110
|
rl.close();
|
|
111
111
|
const choice = answer.toLowerCase().trim();
|
|
112
112
|
if (choice === 'q' || choice === 'quit') {
|
|
113
|
-
|
|
114
|
-
process.exit(0);
|
|
113
|
+
return 'quit';
|
|
115
114
|
}
|
|
116
115
|
if (choice === 'a' || choice === 'all') {
|
|
117
|
-
return
|
|
116
|
+
return 'all';
|
|
118
117
|
}
|
|
119
|
-
|
|
118
|
+
if (choice === 'y' || choice === 'yes') {
|
|
119
|
+
return 'yes';
|
|
120
|
+
}
|
|
121
|
+
return 'no';
|
|
120
122
|
}
|
|
121
123
|
//# sourceMappingURL=skill-files.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "newo",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "NEWO CLI: Professional command-line tool with modular architecture for NEWO AI Agent development. Features IDN-based file management, real-time progress tracking, intelligent sync operations, and comprehensive multi-customer support.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/sync/projects.ts
CHANGED
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
askForOverwrite,
|
|
28
28
|
getExtensionForRunner
|
|
29
29
|
} from './skill-files.js';
|
|
30
|
+
import type { OverwriteChoice } from './skill-files.js';
|
|
30
31
|
import fs from 'fs-extra';
|
|
31
32
|
import { sha256, saveHashes } from '../hash.js';
|
|
32
33
|
import yaml from 'js-yaml';
|
|
@@ -96,9 +97,10 @@ export async function pullSingleProject(
|
|
|
96
97
|
|
|
97
98
|
const newHashes: HashStore = {};
|
|
98
99
|
|
|
99
|
-
// Progress tracking
|
|
100
|
+
// Progress tracking and overwrite control
|
|
100
101
|
let totalSkills = 0;
|
|
101
102
|
let processedSkills = 0;
|
|
103
|
+
let globalOverwriteAll = silentOverwrite;
|
|
102
104
|
|
|
103
105
|
// Count total skills for progress tracking
|
|
104
106
|
for (const project of projects) {
|
|
@@ -249,7 +251,7 @@ export async function pullSingleProject(
|
|
|
249
251
|
hasContentMatch = existingFiles.some(file => !isContentDifferent(file.content, scriptContent));
|
|
250
252
|
|
|
251
253
|
if (hasContentMatch) {
|
|
252
|
-
// Content is the same -
|
|
254
|
+
// Content is the same - handle file naming
|
|
253
255
|
const matchingFile = existingFiles.find(file => !isContentDifferent(file.content, scriptContent));
|
|
254
256
|
const correctName = `${skill.idn}.${getExtensionForRunner(skill.runner_type)}`;
|
|
255
257
|
|
|
@@ -258,29 +260,40 @@ export async function pullSingleProject(
|
|
|
258
260
|
await fs.remove(matchingFile.filePath);
|
|
259
261
|
if (verbose) console.log(` 🔄 Renamed ${matchingFile.fileName} → ${correctName}`);
|
|
260
262
|
} else if (matchingFile && matchingFile.fileName === correctName) {
|
|
261
|
-
// Already has correct name and content
|
|
263
|
+
// Already has correct name and content - skip completely
|
|
262
264
|
shouldWrite = false;
|
|
263
265
|
newHashes[matchingFile.filePath] = sha256(scriptContent);
|
|
264
266
|
if (verbose) console.log(` ✓ Content unchanged for ${skill.idn}, keeping existing file`);
|
|
265
267
|
}
|
|
266
|
-
} else if (!
|
|
267
|
-
// Content is different, ask for overwrite
|
|
268
|
+
} else if (!globalOverwriteAll) {
|
|
269
|
+
// Content is different, ask for overwrite unless global override is set
|
|
268
270
|
const existingFile = existingFiles[0]!;
|
|
269
|
-
const
|
|
271
|
+
const overwriteChoice: OverwriteChoice = await askForOverwrite(
|
|
270
272
|
skill.idn,
|
|
271
273
|
existingFile.fileName,
|
|
272
274
|
`${skill.idn}.${getExtensionForRunner(skill.runner_type)}`
|
|
273
275
|
);
|
|
274
276
|
|
|
275
|
-
if (
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
} else {
|
|
279
|
-
|
|
277
|
+
if (overwriteChoice === 'quit') {
|
|
278
|
+
console.log('❌ Pull operation cancelled by user');
|
|
279
|
+
process.exit(0);
|
|
280
|
+
} else if (overwriteChoice === 'all') {
|
|
281
|
+
globalOverwriteAll = true;
|
|
282
|
+
// Continue with overwrite
|
|
283
|
+
for (const file of existingFiles) {
|
|
284
|
+
await fs.remove(file.filePath);
|
|
285
|
+
if (verbose) console.log(` 🗑️ Removed ${file.fileName}`);
|
|
286
|
+
}
|
|
287
|
+
} else if (overwriteChoice === 'yes') {
|
|
288
|
+
// Single overwrite
|
|
280
289
|
for (const file of existingFiles) {
|
|
281
290
|
await fs.remove(file.filePath);
|
|
282
291
|
if (verbose) console.log(` 🗑️ Removed ${file.fileName}`);
|
|
283
292
|
}
|
|
293
|
+
} else {
|
|
294
|
+
// User said no
|
|
295
|
+
shouldWrite = false;
|
|
296
|
+
if (verbose) console.log(` ⚠️ Skipped overwrite for ${skill.idn}`);
|
|
284
297
|
}
|
|
285
298
|
} else {
|
|
286
299
|
// Silent overwrite mode - remove existing files
|
package/src/sync/skill-files.ts
CHANGED
|
@@ -142,10 +142,12 @@ export function isContentDifferent(existingContent: string, newContent: string):
|
|
|
142
142
|
return sha256(existingContent.trim()) !== sha256(newContent.trim());
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
export type OverwriteChoice = 'yes' | 'no' | 'all' | 'quit';
|
|
146
|
+
|
|
145
147
|
/**
|
|
146
148
|
* Interactive overwrite confirmation
|
|
147
149
|
*/
|
|
148
|
-
export async function askForOverwrite(skillIdn: string, existingFile: string, newFile: string): Promise<
|
|
150
|
+
export async function askForOverwrite(skillIdn: string, existingFile: string, newFile: string): Promise<OverwriteChoice> {
|
|
149
151
|
const readline = await import('readline');
|
|
150
152
|
const rl = readline.createInterface({
|
|
151
153
|
input: process.stdin,
|
|
@@ -164,13 +166,16 @@ export async function askForOverwrite(skillIdn: string, existingFile: string, ne
|
|
|
164
166
|
const choice = answer.toLowerCase().trim();
|
|
165
167
|
|
|
166
168
|
if (choice === 'q' || choice === 'quit') {
|
|
167
|
-
|
|
168
|
-
process.exit(0);
|
|
169
|
+
return 'quit';
|
|
169
170
|
}
|
|
170
171
|
|
|
171
172
|
if (choice === 'a' || choice === 'all') {
|
|
172
|
-
return
|
|
173
|
+
return 'all';
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (choice === 'y' || choice === 'yes') {
|
|
177
|
+
return 'yes';
|
|
173
178
|
}
|
|
174
179
|
|
|
175
|
-
return
|
|
180
|
+
return 'no';
|
|
176
181
|
}
|