vantuz 3.4.1 → 3.5.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.
Files changed (70) hide show
  1. package/LICENSE +45 -45
  2. package/admin-keygen.js +51 -0
  3. package/cli.js +685 -585
  4. package/config.js +733 -733
  5. package/core/agent-loop.js +190 -190
  6. package/core/ai-provider.js +298 -261
  7. package/core/automation.js +523 -523
  8. package/core/brand-analyst.js +101 -0
  9. package/core/channels.js +167 -167
  10. package/core/dashboard.js +230 -230
  11. package/core/database.js +135 -36
  12. package/core/eia-monitor.js +3 -1
  13. package/core/engine.js +648 -636
  14. package/core/gateway.js +447 -447
  15. package/core/learning.js +214 -214
  16. package/core/license.js +113 -0
  17. package/core/marketplace-adapter.js +168 -168
  18. package/core/memory.js +190 -190
  19. package/core/migrations/001-initial-schema.sql +1 -1
  20. package/core/queue.js +120 -120
  21. package/core/self-healer.js +314 -314
  22. package/core/unified-product.js +214 -214
  23. package/core/vision-service.js +113 -113
  24. package/index.js +217 -174
  25. package/modules/crm/sentiment-crm.js +231 -231
  26. package/modules/healer/listing-healer.js +201 -201
  27. package/modules/oracle/predictor.js +214 -214
  28. package/modules/researcher/agent.js +169 -169
  29. package/modules/team/agents/base.js +92 -92
  30. package/modules/team/agents/dev.js +33 -33
  31. package/modules/team/agents/josh.js +40 -40
  32. package/modules/team/agents/marketing.js +33 -33
  33. package/modules/team/agents/milo.js +36 -36
  34. package/modules/team/index.js +78 -78
  35. package/modules/team/shared-memory.js +87 -87
  36. package/modules/war-room/competitor-tracker.js +250 -250
  37. package/modules/war-room/pricing-engine.js +308 -308
  38. package/nodes/warehouse.js +238 -238
  39. package/onboard.js +1 -1
  40. package/package.json +7 -6
  41. package/platforms/pttavm.js +14 -14
  42. package/plugins/vantuz/index.js +528 -528
  43. package/plugins/vantuz/memory/hippocampus.js +465 -464
  44. package/plugins/vantuz/package.json +20 -20
  45. package/plugins/vantuz/platforms/_template.js +118 -118
  46. package/plugins/vantuz/platforms/amazon.js +236 -236
  47. package/plugins/vantuz/platforms/ciceksepeti.js +166 -166
  48. package/plugins/vantuz/platforms/hepsiburada.js +180 -180
  49. package/plugins/vantuz/platforms/index.js +165 -165
  50. package/plugins/vantuz/platforms/n11.js +229 -229
  51. package/plugins/vantuz/platforms/pazarama.js +154 -154
  52. package/plugins/vantuz/platforms/pttavm.js +127 -127
  53. package/plugins/vantuz/platforms/trendyol.js +326 -326
  54. package/plugins/vantuz/services/alerts.js +253 -253
  55. package/plugins/vantuz/services/license.js +34 -34
  56. package/plugins/vantuz/services/scheduler.js +232 -232
  57. package/plugins/vantuz/tools/analytics.js +152 -152
  58. package/plugins/vantuz/tools/crossborder.js +187 -187
  59. package/plugins/vantuz/tools/nl-parser.js +211 -211
  60. package/plugins/vantuz/tools/product.js +110 -110
  61. package/plugins/vantuz/tools/quick-report.js +175 -175
  62. package/plugins/vantuz/tools/repricer.js +314 -314
  63. package/plugins/vantuz/tools/sentiment.js +115 -115
  64. package/plugins/vantuz/tools/vision.js +257 -257
  65. package/private.pem +28 -0
  66. package/public.pem +9 -0
  67. package/server/app.js +260 -260
  68. package/server/public/index.html +514 -514
  69. package/start.bat +33 -33
  70. package/vantuz.sqlite +0 -0
@@ -1,238 +1,238 @@
1
- // nodes/warehouse.js
2
- // Warehouse Node — Lightweight hardware peripheral for Vantuz Gateway
3
- // Connects to Gateway via WebSocket as a "node" role.
4
- // Provides: camera.snap, barcode.scan, voice.listen commands.
5
-
6
- import WebSocket from 'ws';
7
- import fs from 'fs';
8
- import path from 'path';
9
- import { log } from '../core/ai-provider.js';
10
-
11
- const DEFAULT_GATEWAY_URL = 'ws://localhost:18789';
12
-
13
- class WarehouseNode {
14
- constructor(options = {}) {
15
- this.id = options.nodeId || `warehouse-${Date.now().toString(36)}`;
16
- this.name = options.name || 'Depo Terminali';
17
- this.gatewayUrl = options.gatewayUrl || DEFAULT_GATEWAY_URL;
18
- this.token = options.token || process.env.OPENCLAW_GATEWAY_TOKEN || '';
19
- this.ws = null;
20
- this.connected = false;
21
-
22
- // Capabilities this node exposes
23
- this.capabilities = [
24
- 'camera.snap', // Take a photo
25
- 'camera.clip', // Record short video
26
- 'barcode.scan', // Scan barcode (simulated via image)
27
- 'location.get', // GPS / warehouse zone
28
- 'status.report' // Node health status
29
- ];
30
-
31
- log('INFO', `WarehouseNode "${this.name}" created`, { id: this.id });
32
- }
33
-
34
- /**
35
- * Connect to Gateway as a Node peripheral.
36
- */
37
- async connect() {
38
- return new Promise((resolve, reject) => {
39
- try {
40
- this.ws = new WebSocket(this.gatewayUrl);
41
-
42
- this.ws.on('open', () => {
43
- // Send handshake frame
44
- this.ws.send(JSON.stringify({
45
- type: 'connect',
46
- role: 'node',
47
- nodeId: this.id,
48
- name: this.name,
49
- token: this.token,
50
- capabilities: this.capabilities,
51
- meta: {
52
- platform: process.platform,
53
- version: '1.0.0',
54
- location: 'warehouse'
55
- }
56
- }));
57
-
58
- this.connected = true;
59
- log('INFO', `WarehouseNode connected to Gateway`, { url: this.gatewayUrl });
60
- resolve(true);
61
- });
62
-
63
- this.ws.on('message', (data) => {
64
- this._handleCommand(JSON.parse(data.toString()));
65
- });
66
-
67
- this.ws.on('close', () => {
68
- this.connected = false;
69
- log('WARN', 'WarehouseNode disconnected from Gateway');
70
- // Auto-reconnect after 5s
71
- setTimeout(() => this.connect().catch(() => { }), 5000);
72
- });
73
-
74
- this.ws.on('error', (err) => {
75
- log('ERROR', 'WarehouseNode WebSocket error', { error: err.message });
76
- reject(err);
77
- });
78
-
79
- } catch (e) {
80
- reject(e);
81
- }
82
- });
83
- }
84
-
85
- /**
86
- * Handle incoming commands from Gateway/Agent.
87
- */
88
- async _handleCommand(frame) {
89
- const { type, command, requestId, params = {} } = frame;
90
-
91
- if (type !== 'command') return;
92
-
93
- log('INFO', `Node command received: ${command}`, { requestId, params });
94
-
95
- let result;
96
-
97
- switch (command) {
98
- case 'camera.snap':
99
- result = await this._cameraSnap(params);
100
- break;
101
-
102
- case 'barcode.scan':
103
- result = await this._barcodeScan(params);
104
- break;
105
-
106
- case 'status.report':
107
- result = this._statusReport();
108
- break;
109
-
110
- default:
111
- result = { success: false, error: `Unknown command: ${command}` };
112
- }
113
-
114
- // Send response back to Gateway
115
- this._sendResponse(requestId, result);
116
- }
117
-
118
- /**
119
- * Capture an image from camera.
120
- * In production: uses device camera API.
121
- * Prototype: reads from a configured watch directory.
122
- */
123
- async _cameraSnap(params = {}) {
124
- const watchDir = params.watchDir || path.join(process.cwd(), 'warehouse', 'camera');
125
-
126
- // Prototype: look for the latest image in watch directory
127
- if (!fs.existsSync(watchDir)) {
128
- fs.mkdirSync(watchDir, { recursive: true });
129
- return {
130
- success: false,
131
- error: `Kamera klasörü oluşturuldu: ${watchDir}. Fotoğraf dosyasını buraya koyun.`
132
- };
133
- }
134
-
135
- const files = fs.readdirSync(watchDir)
136
- .filter(f => /\.(jpg|jpeg|png|webp)$/i.test(f))
137
- .map(f => ({
138
- name: f,
139
- path: path.join(watchDir, f),
140
- time: fs.statSync(path.join(watchDir, f)).mtimeMs
141
- }))
142
- .sort((a, b) => b.time - a.time);
143
-
144
- if (files.length === 0) {
145
- return {
146
- success: false,
147
- error: 'Kamera klasöründe fotoğraf bulunamadı.'
148
- };
149
- }
150
-
151
- const latest = files[0];
152
- const buffer = fs.readFileSync(latest.path);
153
- const base64 = buffer.toString('base64');
154
-
155
- log('INFO', `Camera snap: ${latest.name}`, { size: buffer.length });
156
-
157
- return {
158
- success: true,
159
- image: `data:image/jpeg;base64,${base64}`,
160
- filename: latest.name,
161
- capturedAt: new Date().toISOString()
162
- };
163
- }
164
-
165
- /**
166
- * Scan barcode from latest camera image.
167
- * In production: uses barcode scanning library.
168
- * Prototype: extracts from filename convention (e.g., "barcode_123456.jpg").
169
- */
170
- async _barcodeScan(params = {}) {
171
- const snap = await this._cameraSnap(params);
172
- if (!snap.success) return snap;
173
-
174
- // Prototype: extract barcode from filename
175
- const match = snap.filename.match(/barcode[_-]?(\d+)/i);
176
- if (match) {
177
- return {
178
- success: true,
179
- barcode: match[1],
180
- format: 'CODE128',
181
- source: 'filename',
182
- image: snap.image
183
- };
184
- }
185
-
186
- // In production, this would use a barcode scanning library
187
- return {
188
- success: true,
189
- barcode: null,
190
- note: 'Barkod tespit edilemedi. Üretim sürümünde barkod kütüphanesi kullanılacak.',
191
- image: snap.image
192
- };
193
- }
194
-
195
- /**
196
- * Report node status / health.
197
- */
198
- _statusReport() {
199
- return {
200
- success: true,
201
- nodeId: this.id,
202
- name: this.name,
203
- connected: this.connected,
204
- uptime: process.uptime(),
205
- memoryMB: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
206
- capabilities: this.capabilities,
207
- platform: process.platform
208
- };
209
- }
210
-
211
- /**
212
- * Send response frame back to Gateway.
213
- */
214
- _sendResponse(requestId, result) {
215
- if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
216
- log('WARN', 'Cannot send response, WebSocket not open');
217
- return;
218
- }
219
-
220
- this.ws.send(JSON.stringify({
221
- type: 'response',
222
- requestId,
223
- ...result
224
- }));
225
- }
226
-
227
- /**
228
- * Disconnect from Gateway.
229
- */
230
- disconnect() {
231
- if (this.ws) {
232
- this.ws.close();
233
- this.connected = false;
234
- }
235
- }
236
- }
237
-
238
- export default WarehouseNode;
1
+ // nodes/warehouse.js
2
+ // Warehouse Node — Lightweight hardware peripheral for Vantuz Gateway
3
+ // Connects to Gateway via WebSocket as a "node" role.
4
+ // Provides: camera.snap, barcode.scan, voice.listen commands.
5
+
6
+ import WebSocket from 'ws';
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+ import { log } from '../core/ai-provider.js';
10
+
11
+ const DEFAULT_GATEWAY_URL = 'ws://localhost:18789';
12
+
13
+ class WarehouseNode {
14
+ constructor(options = {}) {
15
+ this.id = options.nodeId || `warehouse-${Date.now().toString(36)}`;
16
+ this.name = options.name || 'Depo Terminali';
17
+ this.gatewayUrl = options.gatewayUrl || DEFAULT_GATEWAY_URL;
18
+ this.token = options.token || process.env.OPENCLAW_GATEWAY_TOKEN || '';
19
+ this.ws = null;
20
+ this.connected = false;
21
+
22
+ // Capabilities this node exposes
23
+ this.capabilities = [
24
+ 'camera.snap', // Take a photo
25
+ 'camera.clip', // Record short video
26
+ 'barcode.scan', // Scan barcode (simulated via image)
27
+ 'location.get', // GPS / warehouse zone
28
+ 'status.report' // Node health status
29
+ ];
30
+
31
+ log('INFO', `WarehouseNode "${this.name}" created`, { id: this.id });
32
+ }
33
+
34
+ /**
35
+ * Connect to Gateway as a Node peripheral.
36
+ */
37
+ async connect() {
38
+ return new Promise((resolve, reject) => {
39
+ try {
40
+ this.ws = new WebSocket(this.gatewayUrl);
41
+
42
+ this.ws.on('open', () => {
43
+ // Send handshake frame
44
+ this.ws.send(JSON.stringify({
45
+ type: 'connect',
46
+ role: 'node',
47
+ nodeId: this.id,
48
+ name: this.name,
49
+ token: this.token,
50
+ capabilities: this.capabilities,
51
+ meta: {
52
+ platform: process.platform,
53
+ version: '1.0.0',
54
+ location: 'warehouse'
55
+ }
56
+ }));
57
+
58
+ this.connected = true;
59
+ log('INFO', `WarehouseNode connected to Gateway`, { url: this.gatewayUrl });
60
+ resolve(true);
61
+ });
62
+
63
+ this.ws.on('message', (data) => {
64
+ this._handleCommand(JSON.parse(data.toString()));
65
+ });
66
+
67
+ this.ws.on('close', () => {
68
+ this.connected = false;
69
+ log('WARN', 'WarehouseNode disconnected from Gateway');
70
+ // Auto-reconnect after 5s
71
+ setTimeout(() => this.connect().catch(() => { }), 5000);
72
+ });
73
+
74
+ this.ws.on('error', (err) => {
75
+ log('ERROR', 'WarehouseNode WebSocket error', { error: err.message });
76
+ reject(err);
77
+ });
78
+
79
+ } catch (e) {
80
+ reject(e);
81
+ }
82
+ });
83
+ }
84
+
85
+ /**
86
+ * Handle incoming commands from Gateway/Agent.
87
+ */
88
+ async _handleCommand(frame) {
89
+ const { type, command, requestId, params = {} } = frame;
90
+
91
+ if (type !== 'command') return;
92
+
93
+ log('INFO', `Node command received: ${command}`, { requestId, params });
94
+
95
+ let result;
96
+
97
+ switch (command) {
98
+ case 'camera.snap':
99
+ result = await this._cameraSnap(params);
100
+ break;
101
+
102
+ case 'barcode.scan':
103
+ result = await this._barcodeScan(params);
104
+ break;
105
+
106
+ case 'status.report':
107
+ result = this._statusReport();
108
+ break;
109
+
110
+ default:
111
+ result = { success: false, error: `Unknown command: ${command}` };
112
+ }
113
+
114
+ // Send response back to Gateway
115
+ this._sendResponse(requestId, result);
116
+ }
117
+
118
+ /**
119
+ * Capture an image from camera.
120
+ * In production: uses device camera API.
121
+ * Prototype: reads from a configured watch directory.
122
+ */
123
+ async _cameraSnap(params = {}) {
124
+ const watchDir = params.watchDir || path.join(process.cwd(), 'warehouse', 'camera');
125
+
126
+ // Prototype: look for the latest image in watch directory
127
+ if (!fs.existsSync(watchDir)) {
128
+ fs.mkdirSync(watchDir, { recursive: true });
129
+ return {
130
+ success: false,
131
+ error: `Kamera klasörü oluşturuldu: ${watchDir}. Fotoğraf dosyasını buraya koyun.`
132
+ };
133
+ }
134
+
135
+ const files = fs.readdirSync(watchDir)
136
+ .filter(f => /\.(jpg|jpeg|png|webp)$/i.test(f))
137
+ .map(f => ({
138
+ name: f,
139
+ path: path.join(watchDir, f),
140
+ time: fs.statSync(path.join(watchDir, f)).mtimeMs
141
+ }))
142
+ .sort((a, b) => b.time - a.time);
143
+
144
+ if (files.length === 0) {
145
+ return {
146
+ success: false,
147
+ error: 'Kamera klasöründe fotoğraf bulunamadı.'
148
+ };
149
+ }
150
+
151
+ const latest = files[0];
152
+ const buffer = fs.readFileSync(latest.path);
153
+ const base64 = buffer.toString('base64');
154
+
155
+ log('INFO', `Camera snap: ${latest.name}`, { size: buffer.length });
156
+
157
+ return {
158
+ success: true,
159
+ image: `data:image/jpeg;base64,${base64}`,
160
+ filename: latest.name,
161
+ capturedAt: new Date().toISOString()
162
+ };
163
+ }
164
+
165
+ /**
166
+ * Scan barcode from latest camera image.
167
+ * In production: uses barcode scanning library.
168
+ * Prototype: extracts from filename convention (e.g., "barcode_123456.jpg").
169
+ */
170
+ async _barcodeScan(params = {}) {
171
+ const snap = await this._cameraSnap(params);
172
+ if (!snap.success) return snap;
173
+
174
+ // Prototype: extract barcode from filename
175
+ const match = snap.filename.match(/barcode[_-]?(\d+)/i);
176
+ if (match) {
177
+ return {
178
+ success: true,
179
+ barcode: match[1],
180
+ format: 'CODE128',
181
+ source: 'filename',
182
+ image: snap.image
183
+ };
184
+ }
185
+
186
+ // In production, this would use a barcode scanning library
187
+ return {
188
+ success: true,
189
+ barcode: null,
190
+ note: 'Barkod tespit edilemedi. Üretim sürümünde barkod kütüphanesi kullanılacak.',
191
+ image: snap.image
192
+ };
193
+ }
194
+
195
+ /**
196
+ * Report node status / health.
197
+ */
198
+ _statusReport() {
199
+ return {
200
+ success: true,
201
+ nodeId: this.id,
202
+ name: this.name,
203
+ connected: this.connected,
204
+ uptime: process.uptime(),
205
+ memoryMB: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
206
+ capabilities: this.capabilities,
207
+ platform: process.platform
208
+ };
209
+ }
210
+
211
+ /**
212
+ * Send response frame back to Gateway.
213
+ */
214
+ _sendResponse(requestId, result) {
215
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
216
+ log('WARN', 'Cannot send response, WebSocket not open');
217
+ return;
218
+ }
219
+
220
+ this.ws.send(JSON.stringify({
221
+ type: 'response',
222
+ requestId,
223
+ ...result
224
+ }));
225
+ }
226
+
227
+ /**
228
+ * Disconnect from Gateway.
229
+ */
230
+ disconnect() {
231
+ if (this.ws) {
232
+ this.ws.close();
233
+ this.connected = false;
234
+ }
235
+ }
236
+ }
237
+
238
+ export default WarehouseNode;
package/onboard.js CHANGED
@@ -8,4 +8,4 @@ try {
8
8
  } catch (e) {
9
9
  console.error('[HATA] Onboarding basarisiz:', e?.message || e);
10
10
  process.exitCode = 1;
11
- }
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vantuz",
3
- "version": "3.4.1",
3
+ "version": "3.5.0",
4
4
  "description": "Yapay Zeka Destekli Yeni Nesil E-Ticaret Yönetim Platformu (CLI)",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -8,7 +8,6 @@
8
8
  },
9
9
  "scripts": {
10
10
  "start": "node index.js",
11
- "postinstall": "npm rebuild sqlite3",
12
11
  "test": "echo \"Error: no test specified\" && exit 1"
13
12
  },
14
13
  "keywords": [
@@ -29,14 +28,16 @@
29
28
  "chalk": "^4.1.2",
30
29
  "conf": "^10.2.0",
31
30
  "console-clear": "^1.1.1",
31
+ "cron": "^4.4.0",
32
32
  "dotenv": "^16.0.0",
33
33
  "figlet": "^1.5.0",
34
34
  "inquirer": "^8.2.0",
35
35
  "ora": "^5.4.1",
36
36
  "pkg": "^5.8.1",
37
- "sequelize": "^6.37.7",
38
- "sqlite3": "^5.1.7",
39
- "table": "^6.8.0"
37
+ "playwright": "^1.58.2",
38
+ "better-sqlite3": "^11.8.1",
39
+ "table": "^6.8.0",
40
+ "xml2js": "^0.6.2"
40
41
  },
41
42
  "os": [
42
43
  "darwin",
@@ -46,4 +47,4 @@
46
47
  "engines": {
47
48
  "node": ">=16.0.0"
48
49
  }
49
- }
50
+ }
@@ -1,14 +1,14 @@
1
- export default {
2
- name: 'PttAVM',
3
- icon: '📮', // Postbox icon for PttAVM
4
- description: 'Türkiye\'nin Güvenilir E-ticaret Platformu',
5
- requiredFields: [
6
- { key: 'apiKey', label: 'API Key', env: 'PTTAVM_API_KEY' },
7
- { key: 'token', label: 'Token', env: 'PTTAVM_TOKEN' },
8
- { key: 'shopId', label: 'Shop ID', env: 'PTTAVM_SHOP_ID' }
9
- ],
10
- async getOrders(creds) {
11
- // Stub
12
- return [];
13
- }
14
- };
1
+ export default {
2
+ name: 'PttAVM',
3
+ icon: '📮', // Postbox icon for PttAVM
4
+ description: 'Türkiye\'nin Güvenilir E-ticaret Platformu',
5
+ requiredFields: [
6
+ { key: 'apiKey', label: 'API Key', env: 'PTTAVM_API_KEY' },
7
+ { key: 'token', label: 'Token', env: 'PTTAVM_TOKEN' },
8
+ { key: 'shopId', label: 'Shop ID', env: 'PTTAVM_SHOP_ID' }
9
+ ],
10
+ async getOrders(creds) {
11
+ // Stub
12
+ return [];
13
+ }
14
+ };