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.
@@ -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 - remove old files and write with correct IDN name
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 (!silentOverwrite) {
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 shouldOverwrite = await askForOverwrite(skill.idn, existingFile.fileName, `${skill.idn}.${getExtensionForRunner(skill.runner_type)}`);
206
- if (!shouldOverwrite) {
207
- shouldWrite = false;
208
- if (verbose)
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
- // Remove existing files before writing new one
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<boolean>;
42
+ export declare function askForOverwrite(skillIdn: string, existingFile: string, newFile: string): Promise<OverwriteChoice>;
42
43
  //# sourceMappingURL=skill-files.d.ts.map
@@ -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
- console.log('❌ Pull operation cancelled by user');
114
- process.exit(0);
113
+ return 'quit';
115
114
  }
116
115
  if (choice === 'a' || choice === 'all') {
117
- return true; // This should be handled by caller to set global overwrite mode
116
+ return 'all';
118
117
  }
119
- return choice === 'y' || choice === 'yes';
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.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": {
@@ -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 - remove old files and write with correct IDN name
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 (!silentOverwrite) {
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 shouldOverwrite = await askForOverwrite(
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 (!shouldOverwrite) {
276
- shouldWrite = false;
277
- if (verbose) console.log(` ⚠️ Skipped overwrite for ${skill.idn}`);
278
- } else {
279
- // Remove existing files before writing new one
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
@@ -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<boolean> {
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
- console.log('❌ Pull operation cancelled by user');
168
- process.exit(0);
169
+ return 'quit';
169
170
  }
170
171
 
171
172
  if (choice === 'a' || choice === 'all') {
172
- return true; // This should be handled by caller to set global overwrite mode
173
+ return 'all';
174
+ }
175
+
176
+ if (choice === 'y' || choice === 'yes') {
177
+ return 'yes';
173
178
  }
174
179
 
175
- return choice === 'y' || choice === 'yes';
180
+ return 'no';
176
181
  }