newo 1.9.2 ā 2.0.0
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 +116 -0
- package/README.md +68 -20
- package/dist/cli/commands/conversations.d.ts +3 -0
- package/dist/cli/commands/conversations.js +38 -0
- package/dist/cli/commands/help.d.ts +5 -0
- package/dist/cli/commands/help.js +50 -0
- package/dist/cli/commands/import-akb.d.ts +3 -0
- package/dist/cli/commands/import-akb.js +62 -0
- package/dist/cli/commands/list-customers.d.ts +3 -0
- package/dist/cli/commands/list-customers.js +13 -0
- package/dist/cli/commands/meta.d.ts +3 -0
- package/dist/cli/commands/meta.js +19 -0
- package/dist/cli/commands/pull-attributes.d.ts +3 -0
- package/dist/cli/commands/pull-attributes.js +16 -0
- package/dist/cli/commands/pull.d.ts +3 -0
- package/dist/cli/commands/pull.js +34 -0
- package/dist/cli/commands/push.d.ts +3 -0
- package/dist/cli/commands/push.js +39 -0
- package/dist/cli/commands/status.d.ts +3 -0
- package/dist/cli/commands/status.js +22 -0
- package/dist/cli/customer-selection.d.ts +23 -0
- package/dist/cli/customer-selection.js +110 -0
- package/dist/cli/errors.d.ts +9 -0
- package/dist/cli/errors.js +111 -0
- package/dist/cli.js +66 -463
- package/dist/fsutil.js +1 -1
- package/dist/sync/attributes.d.ts +7 -0
- package/dist/sync/attributes.js +90 -0
- package/dist/sync/conversations.d.ts +7 -0
- package/dist/sync/conversations.js +218 -0
- package/dist/sync/metadata.d.ts +8 -0
- package/dist/sync/metadata.js +124 -0
- package/dist/sync/projects.d.ts +13 -0
- package/dist/sync/projects.js +283 -0
- package/dist/sync/push.d.ts +7 -0
- package/dist/sync/push.js +171 -0
- package/dist/sync/skill-files.d.ts +42 -0
- package/dist/sync/skill-files.js +121 -0
- package/dist/sync/status.d.ts +6 -0
- package/dist/sync/status.js +247 -0
- package/dist/sync.d.ts +10 -8
- package/dist/sync.js +12 -1226
- package/dist/types.d.ts +0 -1
- package/package.json +2 -2
- package/src/cli/commands/conversations.ts +47 -0
- package/src/cli/commands/help.ts +50 -0
- package/src/cli/commands/import-akb.ts +71 -0
- package/src/cli/commands/list-customers.ts +14 -0
- package/src/cli/commands/meta.ts +26 -0
- package/src/cli/commands/pull-attributes.ts +23 -0
- package/src/cli/commands/pull.ts +43 -0
- package/src/cli/commands/push.ts +47 -0
- package/src/cli/commands/status.ts +30 -0
- package/src/cli/customer-selection.ts +135 -0
- package/src/cli/errors.ts +111 -0
- package/src/cli.ts +77 -471
- package/src/fsutil.ts +1 -1
- package/src/sync/attributes.ts +110 -0
- package/src/sync/conversations.ts +257 -0
- package/src/sync/metadata.ts +153 -0
- package/src/sync/projects.ts +359 -0
- package/src/sync/push.ts +200 -0
- package/src/sync/skill-files.ts +176 -0
- package/src/sync/status.ts +277 -0
- package/src/sync.ts +14 -1418
- package/src/types.ts +0 -1
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customer selection and management utilities for CLI commands
|
|
3
|
+
*/
|
|
4
|
+
import { parseCustomerConfigAsync, listCustomers, getCustomer, getDefaultCustomer, tryGetDefaultCustomer, getAllCustomers, validateCustomerConfig } from '../customerAsync.js';
|
|
5
|
+
import { logCliError } from './errors.js';
|
|
6
|
+
/**
|
|
7
|
+
* Parse and validate customer configuration
|
|
8
|
+
*/
|
|
9
|
+
export async function parseAndValidateCustomerConfig(env, verbose) {
|
|
10
|
+
try {
|
|
11
|
+
const customerConfig = await parseCustomerConfigAsync(env, verbose);
|
|
12
|
+
validateCustomerConfig(customerConfig);
|
|
13
|
+
return customerConfig;
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
logCliError('error', 'Failed to parse customer configuration');
|
|
17
|
+
if (error instanceof Error) {
|
|
18
|
+
logCliError('error', error.message);
|
|
19
|
+
}
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Handle customer selection for commands that support single customer operations
|
|
25
|
+
*/
|
|
26
|
+
export function selectSingleCustomer(customerConfig, customerArg) {
|
|
27
|
+
let selectedCustomer = null;
|
|
28
|
+
let allCustomers = [];
|
|
29
|
+
if (customerArg) {
|
|
30
|
+
const customer = getCustomer(customerConfig, customerArg);
|
|
31
|
+
if (!customer) {
|
|
32
|
+
console.error(`Unknown customer: ${customerArg}`);
|
|
33
|
+
console.error(`Available customers: ${listCustomers(customerConfig).join(', ')}`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
selectedCustomer = customer;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// Try to get default, fall back to all customers
|
|
40
|
+
selectedCustomer = tryGetDefaultCustomer(customerConfig);
|
|
41
|
+
if (!selectedCustomer) {
|
|
42
|
+
allCustomers = getAllCustomers(customerConfig);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
selectedCustomer,
|
|
47
|
+
allCustomers,
|
|
48
|
+
isMultiCustomer: allCustomers.length > 0
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Handle customer selection for commands that require exactly one customer
|
|
53
|
+
*/
|
|
54
|
+
export function requireSingleCustomer(customerConfig, customerArg) {
|
|
55
|
+
if (customerArg) {
|
|
56
|
+
const customer = getCustomer(customerConfig, customerArg);
|
|
57
|
+
if (!customer) {
|
|
58
|
+
console.error(`Unknown customer: ${customerArg}`);
|
|
59
|
+
console.error(`Available customers: ${listCustomers(customerConfig).join(', ')}`);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
return customer;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
try {
|
|
66
|
+
return getDefaultCustomer(customerConfig);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
70
|
+
console.error(message);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Interactive customer selection for commands like push
|
|
77
|
+
*/
|
|
78
|
+
export async function interactiveCustomerSelection(allCustomers) {
|
|
79
|
+
console.log(`\nš¤ Multiple customers available for push:`);
|
|
80
|
+
allCustomers.forEach((customer, index) => {
|
|
81
|
+
console.log(` ${index + 1}. ${customer.idn}`);
|
|
82
|
+
});
|
|
83
|
+
console.log(` ${allCustomers.length + 1}. All customers`);
|
|
84
|
+
const readline = await import('readline');
|
|
85
|
+
const rl = readline.createInterface({
|
|
86
|
+
input: process.stdin,
|
|
87
|
+
output: process.stdout
|
|
88
|
+
});
|
|
89
|
+
const choice = await new Promise((resolve) => {
|
|
90
|
+
rl.question(`\nSelect customer to push (1-${allCustomers.length + 1}): `, resolve);
|
|
91
|
+
});
|
|
92
|
+
rl.close();
|
|
93
|
+
const choiceNum = parseInt(choice.trim());
|
|
94
|
+
if (choiceNum === allCustomers.length + 1) {
|
|
95
|
+
// User selected "All customers"
|
|
96
|
+
console.log(`š Pushing to all ${allCustomers.length} customers...`);
|
|
97
|
+
return allCustomers;
|
|
98
|
+
}
|
|
99
|
+
else if (choiceNum >= 1 && choiceNum <= allCustomers.length) {
|
|
100
|
+
// User selected specific customer
|
|
101
|
+
const selectedCustomer = allCustomers[choiceNum - 1];
|
|
102
|
+
if (selectedCustomer) {
|
|
103
|
+
console.log(`š Pushing to customer: ${selectedCustomer.idn}`);
|
|
104
|
+
return [selectedCustomer];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
console.error('Invalid choice. Exiting.');
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=customer-selection.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced error logging for CLI
|
|
3
|
+
*/
|
|
4
|
+
export declare function logCliError(level: 'error' | 'warn' | 'info', message: string, meta?: Record<string, unknown>): void;
|
|
5
|
+
/**
|
|
6
|
+
* Enhanced error handling with user-friendly messages
|
|
7
|
+
*/
|
|
8
|
+
export declare function handleCliError(error: unknown, operation?: string): never;
|
|
9
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced error handling utilities for NEWO CLI
|
|
3
|
+
*/
|
|
4
|
+
import { EnvValidationError } from '../env.js';
|
|
5
|
+
/**
|
|
6
|
+
* Enhanced error logging for CLI
|
|
7
|
+
*/
|
|
8
|
+
export function logCliError(level, message, meta) {
|
|
9
|
+
const timestamp = new Date().toISOString();
|
|
10
|
+
const logEntry = {
|
|
11
|
+
timestamp,
|
|
12
|
+
level,
|
|
13
|
+
module: 'cli',
|
|
14
|
+
message,
|
|
15
|
+
...meta
|
|
16
|
+
};
|
|
17
|
+
// Only log JSON format in verbose mode, otherwise use clean user messages
|
|
18
|
+
const verbose = process.argv.includes('--verbose') || process.argv.includes('-v');
|
|
19
|
+
if (verbose) {
|
|
20
|
+
if (level === 'error') {
|
|
21
|
+
console.error(JSON.stringify(logEntry));
|
|
22
|
+
}
|
|
23
|
+
else if (level === 'warn') {
|
|
24
|
+
console.warn(JSON.stringify(logEntry));
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
console.log(JSON.stringify(logEntry));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// Clean user-facing messages
|
|
32
|
+
if (level === 'error') {
|
|
33
|
+
console.error(`ā ${message}`);
|
|
34
|
+
}
|
|
35
|
+
else if (level === 'warn') {
|
|
36
|
+
console.warn(`ā ļø ${message}`);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
console.log(`ā¹ļø ${message}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Enhanced error handling with user-friendly messages
|
|
45
|
+
*/
|
|
46
|
+
export function handleCliError(error, operation = 'operation') {
|
|
47
|
+
const verbose = process.argv.includes('--verbose') || process.argv.includes('-v');
|
|
48
|
+
if (error instanceof Error) {
|
|
49
|
+
// Authentication errors
|
|
50
|
+
if (error.message.includes('API key') || error.message.includes('Authentication failed')) {
|
|
51
|
+
logCliError('error', 'Authentication failed. Please check your API key configuration.');
|
|
52
|
+
if (!verbose) {
|
|
53
|
+
console.error('\nš” Troubleshooting tips:');
|
|
54
|
+
console.error(' ⢠Verify your API key is correct in .env file');
|
|
55
|
+
console.error(' ⢠For multi-customer setup, check NEWO_CUSTOMER_<IDN>_API_KEY');
|
|
56
|
+
console.error(' ⢠Run with --verbose for detailed error information');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Network errors
|
|
60
|
+
else if (error.message.includes('Network timeout') || error.message.includes('ENOTFOUND') || error.message.includes('ECONNREFUSED')) {
|
|
61
|
+
logCliError('error', 'Network connection failed. Please check your internet connection.');
|
|
62
|
+
if (!verbose) {
|
|
63
|
+
console.error('\nš” Troubleshooting tips:');
|
|
64
|
+
console.error(' ⢠Check your internet connection');
|
|
65
|
+
console.error(' ⢠Verify NEWO_BASE_URL is correct');
|
|
66
|
+
console.error(' ⢠Try again in a few moments');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Environment configuration errors
|
|
70
|
+
else if (error instanceof EnvValidationError || error.message.includes('not set')) {
|
|
71
|
+
logCliError('error', 'Configuration error. Please check your environment setup.');
|
|
72
|
+
if (!verbose) {
|
|
73
|
+
console.error('\nš” Setup help:');
|
|
74
|
+
console.error(' ⢠Copy .env.example to .env and configure your settings');
|
|
75
|
+
console.error(' ⢠Run "newo --help" to see configuration examples');
|
|
76
|
+
console.error(' ⢠Check the README for detailed setup instructions');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// File system errors
|
|
80
|
+
else if (error.message.includes('ENOENT') || error.message.includes('EACCES')) {
|
|
81
|
+
logCliError('error', 'File system error. Please check file permissions and paths.');
|
|
82
|
+
}
|
|
83
|
+
// Rate limiting
|
|
84
|
+
else if (error.message.includes('Rate limit exceeded')) {
|
|
85
|
+
logCliError('error', 'Rate limit exceeded. Please wait before trying again.');
|
|
86
|
+
}
|
|
87
|
+
// General API errors
|
|
88
|
+
else if (error.message.includes('response') || error.message.includes('status')) {
|
|
89
|
+
logCliError('error', `API error during ${operation}. Please try again or contact support.`);
|
|
90
|
+
}
|
|
91
|
+
// Unknown errors
|
|
92
|
+
else {
|
|
93
|
+
logCliError('error', `Unexpected error during ${operation}: ${error.message}`);
|
|
94
|
+
if (!verbose) {
|
|
95
|
+
console.error('\nš” For more details, run the command with --verbose flag');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (verbose) {
|
|
99
|
+
logCliError('error', 'Full error details', {
|
|
100
|
+
operation,
|
|
101
|
+
errorType: error.constructor.name,
|
|
102
|
+
stack: error.stack?.split('\n').slice(0, 5).join('\n') // First 5 lines of stack
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
logCliError('error', `Unknown error during ${operation}: ${String(error)}`);
|
|
108
|
+
}
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=errors.js.map
|