newo 3.4.0 → 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.
Files changed (79) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/api.d.ts +3 -1
  3. package/dist/api.js +49 -1
  4. package/dist/application/migration/MigrationEngine.d.ts +141 -0
  5. package/dist/application/migration/MigrationEngine.js +322 -0
  6. package/dist/application/migration/index.d.ts +5 -0
  7. package/dist/application/migration/index.js +5 -0
  8. package/dist/application/sync/SyncEngine.d.ts +134 -0
  9. package/dist/application/sync/SyncEngine.js +335 -0
  10. package/dist/application/sync/index.d.ts +5 -0
  11. package/dist/application/sync/index.js +5 -0
  12. package/dist/cli/commands/create-attribute.js +1 -1
  13. package/dist/cli/commands/create-customer.d.ts +3 -0
  14. package/dist/cli/commands/create-customer.js +159 -0
  15. package/dist/cli/commands/diff.d.ts +6 -0
  16. package/dist/cli/commands/diff.js +288 -0
  17. package/dist/cli/commands/help.js +63 -3
  18. package/dist/cli/commands/logs.d.ts +18 -0
  19. package/dist/cli/commands/logs.js +283 -0
  20. package/dist/cli/commands/pull.js +114 -10
  21. package/dist/cli/commands/push.js +122 -12
  22. package/dist/cli/commands/update-attribute.d.ts +3 -0
  23. package/dist/cli/commands/update-attribute.js +78 -0
  24. package/dist/cli/commands/watch.d.ts +6 -0
  25. package/dist/cli/commands/watch.js +195 -0
  26. package/dist/cli-new/bootstrap.d.ts +74 -0
  27. package/dist/cli-new/bootstrap.js +154 -0
  28. package/dist/cli-new/di/Container.d.ts +64 -0
  29. package/dist/cli-new/di/Container.js +122 -0
  30. package/dist/cli-new/di/tokens.d.ts +77 -0
  31. package/dist/cli-new/di/tokens.js +76 -0
  32. package/dist/cli.js +20 -0
  33. package/dist/domain/resources/common/types.d.ts +71 -0
  34. package/dist/domain/resources/common/types.js +42 -0
  35. package/dist/domain/strategies/sync/AkbSyncStrategy.d.ts +63 -0
  36. package/dist/domain/strategies/sync/AkbSyncStrategy.js +274 -0
  37. package/dist/domain/strategies/sync/AttributeSyncStrategy.d.ts +87 -0
  38. package/dist/domain/strategies/sync/AttributeSyncStrategy.js +378 -0
  39. package/dist/domain/strategies/sync/ConversationSyncStrategy.d.ts +61 -0
  40. package/dist/domain/strategies/sync/ConversationSyncStrategy.js +232 -0
  41. package/dist/domain/strategies/sync/ISyncStrategy.d.ts +149 -0
  42. package/dist/domain/strategies/sync/ISyncStrategy.js +24 -0
  43. package/dist/domain/strategies/sync/IntegrationSyncStrategy.d.ts +68 -0
  44. package/dist/domain/strategies/sync/IntegrationSyncStrategy.js +413 -0
  45. package/dist/domain/strategies/sync/ProjectSyncStrategy.d.ts +111 -0
  46. package/dist/domain/strategies/sync/ProjectSyncStrategy.js +523 -0
  47. package/dist/domain/strategies/sync/index.d.ts +13 -0
  48. package/dist/domain/strategies/sync/index.js +19 -0
  49. package/dist/sync/migrate.js +99 -23
  50. package/dist/types.d.ts +124 -0
  51. package/package.json +3 -1
  52. package/src/api.ts +53 -2
  53. package/src/application/migration/MigrationEngine.ts +492 -0
  54. package/src/application/migration/index.ts +5 -0
  55. package/src/application/sync/SyncEngine.ts +467 -0
  56. package/src/application/sync/index.ts +5 -0
  57. package/src/cli/commands/create-attribute.ts +1 -1
  58. package/src/cli/commands/create-customer.ts +185 -0
  59. package/src/cli/commands/diff.ts +360 -0
  60. package/src/cli/commands/help.ts +63 -3
  61. package/src/cli/commands/logs.ts +329 -0
  62. package/src/cli/commands/pull.ts +128 -11
  63. package/src/cli/commands/push.ts +131 -13
  64. package/src/cli/commands/update-attribute.ts +82 -0
  65. package/src/cli/commands/watch.ts +227 -0
  66. package/src/cli-new/bootstrap.ts +252 -0
  67. package/src/cli-new/di/Container.ts +152 -0
  68. package/src/cli-new/di/tokens.ts +105 -0
  69. package/src/cli.ts +25 -0
  70. package/src/domain/resources/common/types.ts +106 -0
  71. package/src/domain/strategies/sync/AkbSyncStrategy.ts +358 -0
  72. package/src/domain/strategies/sync/AttributeSyncStrategy.ts +508 -0
  73. package/src/domain/strategies/sync/ConversationSyncStrategy.ts +299 -0
  74. package/src/domain/strategies/sync/ISyncStrategy.ts +182 -0
  75. package/src/domain/strategies/sync/IntegrationSyncStrategy.ts +522 -0
  76. package/src/domain/strategies/sync/ProjectSyncStrategy.ts +747 -0
  77. package/src/domain/strategies/sync/index.ts +46 -0
  78. package/src/sync/migrate.ts +103 -24
  79. package/src/types.ts +135 -0
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Dependency Injection Container
3
+ *
4
+ * A simple, TypeScript-native DI container that:
5
+ * - Supports singleton and factory registrations
6
+ * - Provides type-safe dependency resolution
7
+ * - Enables easy testing through dependency injection
8
+ */
9
+
10
+ /**
11
+ * Factory function type for creating service instances
12
+ */
13
+ type Factory<T> = (container: ServiceContainer) => T;
14
+
15
+ /**
16
+ * Registration types
17
+ */
18
+ interface Registration<T> {
19
+ factory: Factory<T>;
20
+ singleton: boolean;
21
+ instance?: T;
22
+ }
23
+
24
+ /**
25
+ * Service Container for Dependency Injection
26
+ */
27
+ export class ServiceContainer {
28
+ private registrations: Map<symbol, Registration<unknown>> = new Map();
29
+
30
+ /**
31
+ * Register a factory that creates a new instance each time
32
+ */
33
+ register<T>(token: symbol, factory: Factory<T>): void {
34
+ this.registrations.set(token, {
35
+ factory,
36
+ singleton: false
37
+ });
38
+ }
39
+
40
+ /**
41
+ * Register a singleton - only created once
42
+ */
43
+ registerSingleton<T>(token: symbol, instanceOrFactory: T | Factory<T>): void {
44
+ if (typeof instanceOrFactory === 'function') {
45
+ this.registrations.set(token, {
46
+ factory: instanceOrFactory as Factory<T>,
47
+ singleton: true
48
+ });
49
+ } else {
50
+ this.registrations.set(token, {
51
+ factory: () => instanceOrFactory,
52
+ singleton: true,
53
+ instance: instanceOrFactory
54
+ });
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Register a value directly
60
+ */
61
+ registerValue<T>(token: symbol, value: T): void {
62
+ this.registrations.set(token, {
63
+ factory: () => value,
64
+ singleton: true,
65
+ instance: value
66
+ });
67
+ }
68
+
69
+ /**
70
+ * Resolve a service by its token
71
+ */
72
+ get<T>(token: symbol): T {
73
+ const registration = this.registrations.get(token);
74
+
75
+ if (!registration) {
76
+ throw new Error(`No registration found for token: ${token.toString()}`);
77
+ }
78
+
79
+ if (registration.singleton) {
80
+ if (registration.instance === undefined) {
81
+ registration.instance = registration.factory(this);
82
+ }
83
+ return registration.instance as T;
84
+ }
85
+
86
+ return registration.factory(this) as T;
87
+ }
88
+
89
+ /**
90
+ * Check if a token is registered
91
+ */
92
+ has(token: symbol): boolean {
93
+ return this.registrations.has(token);
94
+ }
95
+
96
+ /**
97
+ * Get all registered tokens
98
+ */
99
+ getTokens(): symbol[] {
100
+ return Array.from(this.registrations.keys());
101
+ }
102
+
103
+ /**
104
+ * Clear all registrations (useful for testing)
105
+ */
106
+ clear(): void {
107
+ this.registrations.clear();
108
+ }
109
+
110
+ /**
111
+ * Create a child container that inherits parent registrations
112
+ */
113
+ createChild(): ServiceContainer {
114
+ const child = new ServiceContainer();
115
+
116
+ // Copy parent registrations
117
+ for (const [token, registration] of this.registrations) {
118
+ child.registrations.set(token, { ...registration });
119
+ }
120
+
121
+ return child;
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Global container instance
127
+ */
128
+ let globalContainer: ServiceContainer | null = null;
129
+
130
+ /**
131
+ * Get the global container instance
132
+ */
133
+ export function getContainer(): ServiceContainer {
134
+ if (!globalContainer) {
135
+ globalContainer = new ServiceContainer();
136
+ }
137
+ return globalContainer;
138
+ }
139
+
140
+ /**
141
+ * Set the global container instance (useful for testing)
142
+ */
143
+ export function setContainer(container: ServiceContainer): void {
144
+ globalContainer = container;
145
+ }
146
+
147
+ /**
148
+ * Reset the global container (useful for testing)
149
+ */
150
+ export function resetContainer(): void {
151
+ globalContainer = null;
152
+ }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Dependency Injection Tokens
3
+ *
4
+ * These symbols are used as unique identifiers for services in the DI container.
5
+ * Using symbols ensures no naming conflicts.
6
+ */
7
+
8
+ // Infrastructure Layer
9
+ export const TOKENS = {
10
+ // Logging
11
+ LOGGER: Symbol('Logger'),
12
+
13
+ // Auth
14
+ AUTH_SERVICE: Symbol('AuthService'),
15
+
16
+ // API Client
17
+ API_CLIENT: Symbol('ApiClient'),
18
+ API_CLIENT_FACTORY: Symbol('ApiClientFactory'),
19
+
20
+ // File System
21
+ FILE_SYSTEM: Symbol('FileSystem'),
22
+ HASH_MANAGER: Symbol('HashManager'),
23
+ METADATA_GENERATOR: Symbol('MetadataGenerator'),
24
+
25
+ // Repositories
26
+ PROJECT_REPOSITORY: Symbol('ProjectRepository'),
27
+ INTEGRATION_REPOSITORY: Symbol('IntegrationRepository'),
28
+ AKB_REPOSITORY: Symbol('AkbRepository'),
29
+ ATTRIBUTE_REPOSITORY: Symbol('AttributeRepository'),
30
+ CONVERSATION_REPOSITORY: Symbol('ConversationRepository'),
31
+
32
+ // Domain Layer - Sync Strategies
33
+ PROJECT_SYNC_STRATEGY: Symbol('ProjectSyncStrategy'),
34
+ INTEGRATION_SYNC_STRATEGY: Symbol('IntegrationSyncStrategy'),
35
+ AKB_SYNC_STRATEGY: Symbol('AkbSyncStrategy'),
36
+ ATTRIBUTE_SYNC_STRATEGY: Symbol('AttributeSyncStrategy'),
37
+ CONVERSATION_SYNC_STRATEGY: Symbol('ConversationSyncStrategy'),
38
+
39
+ // Domain Layer - Entity Strategies
40
+ PROJECT_ENTITY_STRATEGY: Symbol('ProjectEntityStrategy'),
41
+ AGENT_ENTITY_STRATEGY: Symbol('AgentEntityStrategy'),
42
+ FLOW_ENTITY_STRATEGY: Symbol('FlowEntityStrategy'),
43
+ SKILL_ENTITY_STRATEGY: Symbol('SkillEntityStrategy'),
44
+
45
+ // Application Layer - Engines
46
+ SYNC_ENGINE: Symbol('SyncEngine'),
47
+ MIGRATION_ENGINE: Symbol('MigrationEngine'),
48
+ ENTITY_MANAGER: Symbol('EntityManager'),
49
+
50
+ // Application Layer - Use Cases
51
+ PULL_USE_CASE: Symbol('PullUseCase'),
52
+ PUSH_USE_CASE: Symbol('PushUseCase'),
53
+ STATUS_USE_CASE: Symbol('StatusUseCase'),
54
+ MIGRATE_USE_CASE: Symbol('MigrateUseCase'),
55
+ CREATE_ENTITY_USE_CASE: Symbol('CreateEntityUseCase'),
56
+ DELETE_ENTITY_USE_CASE: Symbol('DeleteEntityUseCase'),
57
+
58
+ // CLI Layer
59
+ COMMAND_REGISTRY: Symbol('CommandRegistry'),
60
+ COMMAND_EXECUTOR: Symbol('CommandExecutor'),
61
+ ERROR_HANDLER: Symbol('ErrorHandler'),
62
+ CUSTOMER_SELECTOR: Symbol('CustomerSelector'),
63
+
64
+ // Configuration
65
+ CUSTOMER_CONFIG: Symbol('CustomerConfig'),
66
+ ENVIRONMENT: Symbol('Environment'),
67
+ } as const;
68
+
69
+ /**
70
+ * Type for the tokens object
71
+ */
72
+ export type TokenKey = keyof typeof TOKENS;
73
+ export type Token = (typeof TOKENS)[TokenKey];
74
+
75
+ /**
76
+ * Resource types for selective sync
77
+ * These match the resourceType property in each ISyncStrategy implementation
78
+ */
79
+ export const RESOURCE_TYPES = {
80
+ PROJECTS: 'projects',
81
+ ATTRIBUTES: 'attributes',
82
+ INTEGRATIONS: 'integrations',
83
+ AKB: 'akb',
84
+ CONVERSATIONS: 'conversations',
85
+ } as const;
86
+
87
+ /**
88
+ * All available resource types for sync operations
89
+ */
90
+ export const ALL_RESOURCE_TYPES = Object.values(RESOURCE_TYPES);
91
+
92
+ /**
93
+ * Pushable resource types (excludes read-only resources like conversations)
94
+ */
95
+ export const PUSHABLE_RESOURCE_TYPES = ['projects', 'attributes', 'integrations', 'akb'] as const;
96
+
97
+ /**
98
+ * Type for resource type values
99
+ */
100
+ export type ResourceType = (typeof RESOURCE_TYPES)[keyof typeof RESOURCE_TYPES];
101
+
102
+ /**
103
+ * Type for pushable resource types
104
+ */
105
+ export type PushableResourceType = (typeof PUSHABLE_RESOURCE_TYPES)[number];
package/src/cli.ts CHANGED
@@ -23,11 +23,13 @@ import { handleDeleteFlowCommand } from './cli/commands/delete-flow.js';
23
23
  import { handleCreateSkillCommand } from './cli/commands/create-skill.js';
24
24
  import { handleDeleteSkillCommand } from './cli/commands/delete-skill.js';
25
25
  import { handleCreateProjectCommand } from './cli/commands/create-project.js';
26
+ import { handleCreateCustomerCommand } from './cli/commands/create-customer.js';
26
27
  import { handleCreateEventCommand } from './cli/commands/create-event.js';
27
28
  import { handleCreateStateCommand } from './cli/commands/create-state.js';
28
29
  import { handleCreateParameterCommand } from './cli/commands/create-parameter.js';
29
30
  import { handleCreatePersonaCommand } from './cli/commands/create-persona.js';
30
31
  import { handleCreateAttributeCommand } from './cli/commands/create-attribute.js';
32
+ import { handleUpdateAttributeCommand } from './cli/commands/update-attribute.js';
31
33
  import { handleSandboxCommand } from './cli/commands/sandbox.js';
32
34
  import { handlePullIntegrationsCommand } from './cli/commands/pull-integrations.js';
33
35
  import { handlePushIntegrationsCommand } from './cli/commands/push-integrations.js';
@@ -41,6 +43,9 @@ import { handleCreateWebhooksCommand } from './cli/commands/create-webhooks.js';
41
43
  import { handleListRegistriesCommand } from './cli/commands/list-registries.js';
42
44
  import { handleListRegistryItemsCommand } from './cli/commands/list-registry-items.js';
43
45
  import { handleAddProjectCommand } from './cli/commands/add-project.js';
46
+ import { handleWatchCommand } from './cli/commands/watch.js';
47
+ import { handleDiffCommand } from './cli/commands/diff.js';
48
+ import { handleLogsCommand } from './cli/commands/logs.js';
44
49
  import type { CliArgs, NewoApiError } from './types.js';
45
50
 
46
51
  dotenv.config();
@@ -102,6 +107,10 @@ async function main(): Promise<void> {
102
107
  await handleStatusCommand(customerConfig, args, verbose);
103
108
  break;
104
109
 
110
+ case 'logs':
111
+ await handleLogsCommand(customerConfig, args, verbose);
112
+ break;
113
+
105
114
  case 'conversations':
106
115
  await handleConversationsCommand(customerConfig, args, verbose);
107
116
  break;
@@ -150,6 +159,10 @@ async function main(): Promise<void> {
150
159
  await handleCreateProjectCommand(customerConfig, args, verbose);
151
160
  break;
152
161
 
162
+ case 'create-customer':
163
+ await handleCreateCustomerCommand(customerConfig, args, verbose);
164
+ break;
165
+
153
166
  case 'create-event':
154
167
  await handleCreateEventCommand(customerConfig, args, verbose);
155
168
  break;
@@ -170,6 +183,10 @@ async function main(): Promise<void> {
170
183
  await handleCreateAttributeCommand(customerConfig, args, verbose);
171
184
  break;
172
185
 
186
+ case 'update-attribute':
187
+ await handleUpdateAttributeCommand(customerConfig, args, verbose);
188
+ break;
189
+
173
190
  case 'pull-integrations':
174
191
  await handlePullIntegrationsCommand(customerConfig, args, verbose);
175
192
  break;
@@ -219,6 +236,14 @@ async function main(): Promise<void> {
219
236
  await handleAddProjectCommand(customerConfig, args, verbose);
220
237
  break;
221
238
 
239
+ case 'watch':
240
+ await handleWatchCommand(customerConfig, args, verbose);
241
+ break;
242
+
243
+ case 'diff':
244
+ await handleDiffCommand(customerConfig, args, verbose);
245
+ break;
246
+
222
247
  default:
223
248
  console.error('Unknown command:', cmd);
224
249
  console.error('Run "newo --help" for usage information');
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Common types used across all domain resources
3
+ */
4
+
5
+ /**
6
+ * Customer configuration for API operations
7
+ */
8
+ export interface CustomerConfig {
9
+ idn: string;
10
+ apiKey: string;
11
+ projectId?: string | undefined;
12
+ }
13
+
14
+ /**
15
+ * Multi-customer configuration
16
+ */
17
+ export interface MultiCustomerConfig {
18
+ customers: Record<string, CustomerConfig>;
19
+ defaultCustomer?: string | undefined;
20
+ }
21
+
22
+ /**
23
+ * Base entity interface with common fields
24
+ */
25
+ export interface BaseEntity {
26
+ id: string;
27
+ idn: string;
28
+ created_at?: string;
29
+ updated_at?: string;
30
+ }
31
+
32
+ /**
33
+ * Entity with title and description
34
+ */
35
+ export interface DescriptiveEntity extends BaseEntity {
36
+ title: string;
37
+ description?: string;
38
+ }
39
+
40
+ /**
41
+ * Hash store for change detection
42
+ */
43
+ export interface HashStore {
44
+ [filePath: string]: string;
45
+ }
46
+
47
+ /**
48
+ * ID mapping for local to remote entity references
49
+ */
50
+ export interface IdMapping {
51
+ [localId: string]: string;
52
+ }
53
+
54
+ /**
55
+ * Logger interface for dependency injection
56
+ */
57
+ export interface ILogger {
58
+ info(message: string, ...args: unknown[]): void;
59
+ warn(message: string, ...args: unknown[]): void;
60
+ error(message: string, error?: unknown): void;
61
+ debug(message: string, ...args: unknown[]): void;
62
+ verbose(message: string, ...args: unknown[]): void;
63
+ progress(current: number, total: number, message: string): void;
64
+ }
65
+
66
+ /**
67
+ * Default console logger implementation
68
+ */
69
+ export class ConsoleLogger implements ILogger {
70
+ constructor(private verboseMode: boolean = false) {}
71
+
72
+ info(message: string, ..._args: unknown[]): void {
73
+ console.log(message);
74
+ }
75
+
76
+ warn(message: string, ..._args: unknown[]): void {
77
+ console.warn(`⚠️ ${message}`);
78
+ }
79
+
80
+ error(message: string, error?: unknown): void {
81
+ console.error(`❌ ${message}`);
82
+ if (error && this.verboseMode) {
83
+ console.error(error);
84
+ }
85
+ }
86
+
87
+ debug(message: string, ..._args: unknown[]): void {
88
+ if (this.verboseMode) {
89
+ console.log(`🔍 ${message}`);
90
+ }
91
+ }
92
+
93
+ verbose(message: string, ..._args: unknown[]): void {
94
+ if (this.verboseMode) {
95
+ console.log(message);
96
+ }
97
+ }
98
+
99
+ progress(current: number, total: number, message: string): void {
100
+ const pct = Math.round((current / total) * 100);
101
+ process.stdout.write(`\r${message}: ${current}/${total} (${pct}%)`);
102
+ if (current === total) {
103
+ console.log('');
104
+ }
105
+ }
106
+ }