newo 3.4.1 → 3.4.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 +10 -0
- package/dist/cli/commands/create-attribute.js +1 -1
- package/dist/cli/commands/update-attribute.d.ts +3 -0
- package/dist/cli/commands/update-attribute.js +78 -0
- package/dist/cli.js +4 -0
- package/package.json +1 -1
- package/src/cli/commands/create-attribute.ts +1 -1
- package/src/cli/commands/update-attribute.ts +82 -0
- package/src/cli.ts +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.4.2] - 2026-04-12
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`newo update-attribute` command**: Update existing customer attributes by IDN. Supports `--value`, `--title`, `--description`, `--group`, `--hidden`, `--value-type`, and `--possible-values` flags. Only explicitly provided fields are overridden; unspecified fields retain their current values.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **`create-attribute --value 0`**: Fixed a bug where numeric zero values passed via `--value 0` were incorrectly rejected as "value required". The minimist argument parser returns numeric `0` which was treated as falsy by the `||` operator. Now uses explicit `undefined` check.
|
|
19
|
+
|
|
10
20
|
## [3.4.1] - 2026-04-12
|
|
11
21
|
|
|
12
22
|
### Fixed
|
|
@@ -9,7 +9,7 @@ export async function handleCreateAttributeCommand(customerConfig, args, verbose
|
|
|
9
9
|
const selectedCustomer = requireSingleCustomer(customerConfig, args.customer);
|
|
10
10
|
// Parse arguments
|
|
11
11
|
const idn = args._[1];
|
|
12
|
-
const value = args.value
|
|
12
|
+
const value = args.value !== undefined ? String(args.value) : '';
|
|
13
13
|
const title = args.title || idn;
|
|
14
14
|
const description = args.description || '';
|
|
15
15
|
const group = args.group || 'General';
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Update Customer Attribute Command Handler
|
|
3
|
+
*/
|
|
4
|
+
import { makeClient, getCustomerAttributes, updateCustomerAttribute } from '../../api.js';
|
|
5
|
+
import { getValidAccessToken } from '../../auth.js';
|
|
6
|
+
import { requireSingleCustomer } from '../customer-selection.js';
|
|
7
|
+
export async function handleUpdateAttributeCommand(customerConfig, args, verbose = false) {
|
|
8
|
+
try {
|
|
9
|
+
const selectedCustomer = requireSingleCustomer(customerConfig, args.customer);
|
|
10
|
+
// Parse arguments
|
|
11
|
+
const idn = args._[1];
|
|
12
|
+
if (!idn) {
|
|
13
|
+
console.error('Error: Attribute IDN is required');
|
|
14
|
+
console.error('Usage: newo update-attribute <idn> [--value <value>] [--title <title>] [--description <desc>] [--group <group>] [--hidden] [--value-type <type>] [--possible-values <val1,val2>]');
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
// Get access token and create client
|
|
18
|
+
const accessToken = await getValidAccessToken(selectedCustomer);
|
|
19
|
+
const client = await makeClient(verbose, accessToken);
|
|
20
|
+
// Fetch existing attributes to find the one to update
|
|
21
|
+
const response = await getCustomerAttributes(client, true);
|
|
22
|
+
const existing = response.attributes.find((a) => a.idn === idn);
|
|
23
|
+
if (!existing) {
|
|
24
|
+
console.error(`❌ Attribute '${idn}' not found. Use 'newo create-attribute' to create it.`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
if (!existing.id) {
|
|
28
|
+
console.error(`❌ Attribute '${idn}' has no ID. Cannot update.`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
// Build updated attribute - only override fields that were explicitly provided
|
|
32
|
+
const updated = {
|
|
33
|
+
id: existing.id,
|
|
34
|
+
idn: existing.idn,
|
|
35
|
+
value: args.value !== undefined ? String(args.value) : existing.value,
|
|
36
|
+
title: args.title || existing.title,
|
|
37
|
+
description: args.description || existing.description,
|
|
38
|
+
group: args.group || existing.group,
|
|
39
|
+
is_hidden: args.hidden !== undefined ? Boolean(args.hidden) : existing.is_hidden,
|
|
40
|
+
possible_values: args['possible-values']
|
|
41
|
+
? args['possible-values'].split(',').map(v => v.trim())
|
|
42
|
+
: existing.possible_values,
|
|
43
|
+
value_type: args['value-type'] || existing.value_type
|
|
44
|
+
};
|
|
45
|
+
if (verbose) {
|
|
46
|
+
console.log(`📝 Updating customer attribute: ${idn} (ID: ${existing.id})`);
|
|
47
|
+
if (args.value !== undefined)
|
|
48
|
+
console.log(` Value: ${existing.value} -> ${updated.value}`);
|
|
49
|
+
if (args.title)
|
|
50
|
+
console.log(` Title: ${existing.title} -> ${updated.title}`);
|
|
51
|
+
if (args.description)
|
|
52
|
+
console.log(` Description: updated`);
|
|
53
|
+
if (args.group)
|
|
54
|
+
console.log(` Group: ${existing.group} -> ${updated.group}`);
|
|
55
|
+
if (args['value-type'])
|
|
56
|
+
console.log(` Type: ${existing.value_type} -> ${updated.value_type}`);
|
|
57
|
+
if (args.hidden !== undefined)
|
|
58
|
+
console.log(` Hidden: ${existing.is_hidden} -> ${updated.is_hidden}`);
|
|
59
|
+
}
|
|
60
|
+
await updateCustomerAttribute(client, updated);
|
|
61
|
+
console.log(`✅ Customer attribute updated: ${idn}`);
|
|
62
|
+
if (args.value !== undefined)
|
|
63
|
+
console.log(` Value: ${updated.value}`);
|
|
64
|
+
if (args['value-type'])
|
|
65
|
+
console.log(` Type: ${updated.value_type}`);
|
|
66
|
+
if (args.title)
|
|
67
|
+
console.log(` Title: ${updated.title}`);
|
|
68
|
+
if (args.description)
|
|
69
|
+
console.log(` Description: updated`);
|
|
70
|
+
if (args.group)
|
|
71
|
+
console.log(` Group: ${updated.group}`);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error('❌ Failed to update customer attribute:', error instanceof Error ? error.message : String(error));
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=update-attribute.js.map
|
package/dist/cli.js
CHANGED
|
@@ -29,6 +29,7 @@ import { handleCreateStateCommand } from './cli/commands/create-state.js';
|
|
|
29
29
|
import { handleCreateParameterCommand } from './cli/commands/create-parameter.js';
|
|
30
30
|
import { handleCreatePersonaCommand } from './cli/commands/create-persona.js';
|
|
31
31
|
import { handleCreateAttributeCommand } from './cli/commands/create-attribute.js';
|
|
32
|
+
import { handleUpdateAttributeCommand } from './cli/commands/update-attribute.js';
|
|
32
33
|
import { handleSandboxCommand } from './cli/commands/sandbox.js';
|
|
33
34
|
import { handlePullIntegrationsCommand } from './cli/commands/pull-integrations.js';
|
|
34
35
|
import { handlePushIntegrationsCommand } from './cli/commands/push-integrations.js';
|
|
@@ -153,6 +154,9 @@ async function main() {
|
|
|
153
154
|
case 'create-attribute':
|
|
154
155
|
await handleCreateAttributeCommand(customerConfig, args, verbose);
|
|
155
156
|
break;
|
|
157
|
+
case 'update-attribute':
|
|
158
|
+
await handleUpdateAttributeCommand(customerConfig, args, verbose);
|
|
159
|
+
break;
|
|
156
160
|
case 'pull-integrations':
|
|
157
161
|
await handlePullIntegrationsCommand(customerConfig, args, verbose);
|
|
158
162
|
break;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "newo",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.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": {
|
|
@@ -16,7 +16,7 @@ export async function handleCreateAttributeCommand(
|
|
|
16
16
|
|
|
17
17
|
// Parse arguments
|
|
18
18
|
const idn = args._[1] as string;
|
|
19
|
-
const value = args.value
|
|
19
|
+
const value = args.value !== undefined ? String(args.value) : '';
|
|
20
20
|
const title = args.title as string || idn;
|
|
21
21
|
const description = args.description as string || '';
|
|
22
22
|
const group = args.group as string || 'General';
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Update Customer Attribute Command Handler
|
|
3
|
+
*/
|
|
4
|
+
import { makeClient, getCustomerAttributes, updateCustomerAttribute } from '../../api.js';
|
|
5
|
+
import { getValidAccessToken } from '../../auth.js';
|
|
6
|
+
import { requireSingleCustomer } from '../customer-selection.js';
|
|
7
|
+
import type { MultiCustomerConfig, CliArgs, CustomerAttribute } from '../../types.js';
|
|
8
|
+
|
|
9
|
+
export async function handleUpdateAttributeCommand(
|
|
10
|
+
customerConfig: MultiCustomerConfig,
|
|
11
|
+
args: CliArgs,
|
|
12
|
+
verbose: boolean = false
|
|
13
|
+
): Promise<void> {
|
|
14
|
+
try {
|
|
15
|
+
const selectedCustomer = requireSingleCustomer(customerConfig, args.customer as string | undefined);
|
|
16
|
+
|
|
17
|
+
// Parse arguments
|
|
18
|
+
const idn = args._[1] as string;
|
|
19
|
+
|
|
20
|
+
if (!idn) {
|
|
21
|
+
console.error('Error: Attribute IDN is required');
|
|
22
|
+
console.error('Usage: newo update-attribute <idn> [--value <value>] [--title <title>] [--description <desc>] [--group <group>] [--hidden] [--value-type <type>] [--possible-values <val1,val2>]');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Get access token and create client
|
|
27
|
+
const accessToken = await getValidAccessToken(selectedCustomer);
|
|
28
|
+
const client = await makeClient(verbose, accessToken);
|
|
29
|
+
|
|
30
|
+
// Fetch existing attributes to find the one to update
|
|
31
|
+
const response = await getCustomerAttributes(client, true);
|
|
32
|
+
const existing = response.attributes.find((a: CustomerAttribute) => a.idn === idn);
|
|
33
|
+
|
|
34
|
+
if (!existing) {
|
|
35
|
+
console.error(`❌ Attribute '${idn}' not found. Use 'newo create-attribute' to create it.`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!existing.id) {
|
|
40
|
+
console.error(`❌ Attribute '${idn}' has no ID. Cannot update.`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Build updated attribute - only override fields that were explicitly provided
|
|
45
|
+
const updated: CustomerAttribute = {
|
|
46
|
+
id: existing.id,
|
|
47
|
+
idn: existing.idn,
|
|
48
|
+
value: args.value !== undefined ? String(args.value) : existing.value,
|
|
49
|
+
title: (args.title as string) || existing.title,
|
|
50
|
+
description: (args.description as string) || existing.description,
|
|
51
|
+
group: (args.group as string) || existing.group,
|
|
52
|
+
is_hidden: args.hidden !== undefined ? Boolean(args.hidden) : existing.is_hidden,
|
|
53
|
+
possible_values: args['possible-values']
|
|
54
|
+
? (args['possible-values'] as string).split(',').map(v => v.trim())
|
|
55
|
+
: existing.possible_values,
|
|
56
|
+
value_type: (args['value-type'] as string) || existing.value_type
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
if (verbose) {
|
|
60
|
+
console.log(`📝 Updating customer attribute: ${idn} (ID: ${existing.id})`);
|
|
61
|
+
if (args.value !== undefined) console.log(` Value: ${existing.value} -> ${updated.value}`);
|
|
62
|
+
if (args.title) console.log(` Title: ${existing.title} -> ${updated.title}`);
|
|
63
|
+
if (args.description) console.log(` Description: updated`);
|
|
64
|
+
if (args.group) console.log(` Group: ${existing.group} -> ${updated.group}`);
|
|
65
|
+
if (args['value-type']) console.log(` Type: ${existing.value_type} -> ${updated.value_type}`);
|
|
66
|
+
if (args.hidden !== undefined) console.log(` Hidden: ${existing.is_hidden} -> ${updated.is_hidden}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
await updateCustomerAttribute(client, updated);
|
|
70
|
+
|
|
71
|
+
console.log(`✅ Customer attribute updated: ${idn}`);
|
|
72
|
+
if (args.value !== undefined) console.log(` Value: ${updated.value}`);
|
|
73
|
+
if (args['value-type']) console.log(` Type: ${updated.value_type}`);
|
|
74
|
+
if (args.title) console.log(` Title: ${updated.title}`);
|
|
75
|
+
if (args.description) console.log(` Description: updated`);
|
|
76
|
+
if (args.group) console.log(` Group: ${updated.group}`);
|
|
77
|
+
|
|
78
|
+
} catch (error: unknown) {
|
|
79
|
+
console.error('❌ Failed to update customer attribute:', error instanceof Error ? error.message : String(error));
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -29,6 +29,7 @@ import { handleCreateStateCommand } from './cli/commands/create-state.js';
|
|
|
29
29
|
import { handleCreateParameterCommand } from './cli/commands/create-parameter.js';
|
|
30
30
|
import { handleCreatePersonaCommand } from './cli/commands/create-persona.js';
|
|
31
31
|
import { handleCreateAttributeCommand } from './cli/commands/create-attribute.js';
|
|
32
|
+
import { handleUpdateAttributeCommand } from './cli/commands/update-attribute.js';
|
|
32
33
|
import { handleSandboxCommand } from './cli/commands/sandbox.js';
|
|
33
34
|
import { handlePullIntegrationsCommand } from './cli/commands/pull-integrations.js';
|
|
34
35
|
import { handlePushIntegrationsCommand } from './cli/commands/push-integrations.js';
|
|
@@ -182,6 +183,10 @@ async function main(): Promise<void> {
|
|
|
182
183
|
await handleCreateAttributeCommand(customerConfig, args, verbose);
|
|
183
184
|
break;
|
|
184
185
|
|
|
186
|
+
case 'update-attribute':
|
|
187
|
+
await handleUpdateAttributeCommand(customerConfig, args, verbose);
|
|
188
|
+
break;
|
|
189
|
+
|
|
185
190
|
case 'pull-integrations':
|
|
186
191
|
await handlePullIntegrationsCommand(customerConfig, args, verbose);
|
|
187
192
|
break;
|