agentspd 1.0.0 → 1.1.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.
@@ -0,0 +1,514 @@
1
+ import { Command } from 'commander';
2
+ import ora from 'ora';
3
+ import { api } from '../api.js';
4
+ import { getConfig } from '../config.js';
5
+ import * as output from '../output.js';
6
+ export function createWorkspacesCommand() {
7
+ const workspaces = new Command('workspace')
8
+ .alias('ws')
9
+ .description('Manage Emotos Workspaces workspaces for secure agent collaboration');
10
+ // ── workspace create ────────────────────────────────────────────────────
11
+ workspaces
12
+ .command('create')
13
+ .description('Create a new workspace')
14
+ .requiredOption('-n, --name <name>', 'Workspace name')
15
+ .option('-p, --purpose <purpose>', 'Workspace purpose')
16
+ .option('-m, --mode <mode>', 'Communication mode (live, mailbox, hybrid)', 'hybrid')
17
+ .option('--max-participants <n>', 'Max participants', '10')
18
+ .option('--ttl <duration>', 'Time to live (e.g. 24h, 7d)')
19
+ .option('--json', 'Output as JSON')
20
+ .action(async (options) => {
21
+ const spinner = ora('Creating workspace...').start();
22
+ const result = await api.createWorkspace({
23
+ name: options.name,
24
+ purpose: options.purpose,
25
+ mode: options.mode,
26
+ maxParticipants: Number(options.maxParticipants),
27
+ expiresAt: options.ttl ? parseTtl(options.ttl) : undefined,
28
+ });
29
+ if (result.error) {
30
+ spinner.fail('Failed to create workspace');
31
+ output.error(result.error.message);
32
+ return;
33
+ }
34
+ if (options.json) {
35
+ spinner.stop();
36
+ output.printJson(result.data);
37
+ }
38
+ else {
39
+ spinner.succeed('Workspace created!');
40
+ if (result.data) {
41
+ console.log();
42
+ output.printKeyValue([
43
+ ['Workspace ID', result.data.id],
44
+ ['Name', result.data.name],
45
+ ['Mode', result.data.mode],
46
+ ['Status', result.data.status],
47
+ ['Max Participants', String(result.data.maxParticipants)],
48
+ ['Created', output.formatDate(result.data.createdAt)],
49
+ ]);
50
+ console.log();
51
+ output.info('Next: Invite agents with:');
52
+ console.log(` ${output.highlight(`emotos workspace invite ${result.data.id} --agent-name "agent-name"`)}`);
53
+ }
54
+ }
55
+ });
56
+ // ── workspace list ──────────────────────────────────────────────────────
57
+ workspaces
58
+ .command('list')
59
+ .alias('ls')
60
+ .description('List workspaces')
61
+ .option('--status <status>', 'Filter by status')
62
+ .option('--json', 'Output as JSON')
63
+ .action(async (options) => {
64
+ const spinner = ora('Fetching workspaces...').start();
65
+ const result = await api.listWorkspaces({ status: options.status });
66
+ if (result.error) {
67
+ spinner.fail('Failed to fetch workspaces');
68
+ output.error(result.error.message);
69
+ return;
70
+ }
71
+ spinner.stop();
72
+ if (options.json) {
73
+ output.printJson(result.data);
74
+ }
75
+ else if (result.data) {
76
+ if (result.data.items.length === 0) {
77
+ output.info('No workspaces found');
78
+ output.info('Create one with: emotos workspace create --name "My Workspace"');
79
+ return;
80
+ }
81
+ output.heading('Workspaces');
82
+ for (const ws of result.data.items) {
83
+ console.log(` ${output.bold(ws.name)} ${output.dim(`(${ws.id.slice(0, 8)}...)`)}`);
84
+ console.log(` Mode: ${ws.mode} Status: ${ws.status} Created: ${output.formatDate(ws.createdAt)}`);
85
+ }
86
+ }
87
+ });
88
+ // ── workspace invite ────────────────────────────────────────────────────
89
+ workspaces
90
+ .command('invite <workspaceId>')
91
+ .description('Generate an invite token for a workspace (accepts name or ID)')
92
+ .requiredOption('--agent-name <name>', 'Name of the agent to invite')
93
+ .option('--email <address>', 'Send invite via email')
94
+ .option('--expires <duration>', 'Token expiry duration (e.g. 1h, 24h)', '1h')
95
+ .option('--max-uses <count>', 'Max number of joins allowed (0 = unlimited)', '0')
96
+ .option('--json', 'Output as JSON')
97
+ .action(async (workspaceIdOrName, options) => {
98
+ let workspaceId;
99
+ try {
100
+ workspaceId = await api.resolveWorkspace(workspaceIdOrName);
101
+ }
102
+ catch (e) {
103
+ output.error(e.message);
104
+ return;
105
+ }
106
+ const spinner = ora('Generating invite...').start();
107
+ const maxUses = parseInt(options.maxUses, 10) || 0;
108
+ const result = await api.workspaceInvite(workspaceId, {
109
+ agentName: options.agentName,
110
+ expires: options.expires,
111
+ maxUses,
112
+ });
113
+ if (result.error) {
114
+ spinner.fail('Failed to generate invite');
115
+ output.error(result.error.message);
116
+ return;
117
+ }
118
+ if (options.json) {
119
+ spinner.stop();
120
+ output.printJson(result.data);
121
+ }
122
+ else {
123
+ spinner.succeed('Invite token generated!');
124
+ if (result.data) {
125
+ const appUrl = getConfig().appUrl;
126
+ const joinUrl = `${appUrl}/workspaces/${workspaceId}/join?token=${encodeURIComponent(result.data.inviteToken)}`;
127
+ console.log();
128
+ output.printKeyValue([
129
+ ['Invite Token', result.data.inviteToken],
130
+ ['Join URL', joinUrl],
131
+ ['Max Uses', result.data.maxUses === 'unlimited' || result.data.maxUses === 0 ? 'Unlimited' : String(result.data.maxUses)],
132
+ ]);
133
+ console.log();
134
+ output.info('Share this link to invite agents to the workspace:');
135
+ console.log(` ${output.highlight(joinUrl)}`);
136
+ console.log();
137
+ output.info('Or join via CLI:');
138
+ console.log(` ${output.highlight(`emotos workspace join ${workspaceId} --invite-token <token>`)}`);
139
+ }
140
+ }
141
+ });
142
+ // ── workspace join ──────────────────────────────────────────────────────
143
+ workspaces
144
+ .command('join <workspaceId>')
145
+ .description('Join a workspace with an invite token (accepts name or ID)')
146
+ .requiredOption('--invite-token <token>', 'Invite token')
147
+ .requiredOption('--agent-id <id>', 'Your agent name or ID')
148
+ .option('--json', 'Output as JSON')
149
+ .action(async (workspaceIdOrName, options) => {
150
+ let workspaceId;
151
+ try {
152
+ workspaceId = await api.resolveWorkspace(workspaceIdOrName);
153
+ }
154
+ catch (e) {
155
+ output.error(e.message);
156
+ return;
157
+ }
158
+ let agentId;
159
+ try {
160
+ agentId = await api.resolveAgent(options.agentId);
161
+ }
162
+ catch (e) {
163
+ output.error(e.message);
164
+ return;
165
+ }
166
+ const spinner = ora('Joining workspace...').start();
167
+ const result = await api.workspaceJoin(workspaceId, {
168
+ agentId,
169
+ inviteToken: options.inviteToken,
170
+ });
171
+ if (result.error) {
172
+ spinner.fail('Failed to join workspace');
173
+ output.error(result.error.message);
174
+ return;
175
+ }
176
+ if (options.json) {
177
+ spinner.stop();
178
+ output.printJson(result.data);
179
+ }
180
+ else {
181
+ spinner.succeed('Joined workspace!');
182
+ if (result.data) {
183
+ output.printKeyValue([
184
+ ['Workspace', workspaceId],
185
+ ['Agent', result.data.agentId],
186
+ ['Org', result.data.orgId],
187
+ ['Joined', output.formatDate(result.data.joinedAt)],
188
+ ]);
189
+ }
190
+ }
191
+ });
192
+ // ── workspace post ──────────────────────────────────────────────────────
193
+ workspaces
194
+ .command('post <workspaceId>')
195
+ .description('Post a message to a workspace (accepts name or ID)')
196
+ .requiredOption('--agent-id <id>', 'Sender agent name or ID')
197
+ .requiredOption('-m, --message <text>', 'Message content')
198
+ .option('--type <type>', 'Message type (text, artifact)', 'text')
199
+ .option('--json', 'Output as JSON')
200
+ .action(async (workspaceIdOrName, options) => {
201
+ let workspaceId;
202
+ try {
203
+ workspaceId = await api.resolveWorkspace(workspaceIdOrName);
204
+ }
205
+ catch (e) {
206
+ output.error(e.message);
207
+ return;
208
+ }
209
+ let agentId;
210
+ try {
211
+ agentId = await api.resolveAgent(options.agentId);
212
+ }
213
+ catch (e) {
214
+ output.error(e.message);
215
+ return;
216
+ }
217
+ const spinner = ora('Posting message...').start();
218
+ const result = await api.workspacePostMessage(workspaceId, {
219
+ senderAgentId: agentId,
220
+ type: options.type,
221
+ content: options.message,
222
+ });
223
+ if (result.error) {
224
+ spinner.fail('Failed to post message');
225
+ output.error(result.error.message);
226
+ return;
227
+ }
228
+ if (options.json) {
229
+ spinner.stop();
230
+ output.printJson(result.data);
231
+ }
232
+ else {
233
+ spinner.succeed('Message posted!');
234
+ if (result.data) {
235
+ console.log(` ID: ${output.dim(result.data.id)}`);
236
+ console.log(` Type: ${result.data.type}`);
237
+ console.log(` Sent: ${output.formatDate(result.data.createdAt)}`);
238
+ }
239
+ }
240
+ });
241
+ // ── workspace messages ──────────────────────────────────────────────────
242
+ workspaces
243
+ .command('messages <workspaceId>')
244
+ .alias('msgs')
245
+ .description('List messages in a workspace (accepts name or ID)')
246
+ .option('--after <cursor>', 'Cursor for pagination')
247
+ .option('--limit <n>', 'Number of messages', '20')
248
+ .option('--json', 'Output as JSON')
249
+ .action(async (workspaceIdOrName, options) => {
250
+ let workspaceId;
251
+ try {
252
+ workspaceId = await api.resolveWorkspace(workspaceIdOrName);
253
+ }
254
+ catch (e) {
255
+ output.error(e.message);
256
+ return;
257
+ }
258
+ const spinner = ora('Fetching messages...').start();
259
+ const result = await api.workspaceMessages(workspaceId, {
260
+ after: options.after,
261
+ limit: Number(options.limit),
262
+ });
263
+ if (result.error) {
264
+ spinner.fail('Failed to fetch messages');
265
+ output.error(result.error.message);
266
+ return;
267
+ }
268
+ spinner.stop();
269
+ if (options.json) {
270
+ output.printJson(result.data);
271
+ }
272
+ else if (result.data) {
273
+ if (result.data.items.length === 0) {
274
+ output.info('No messages yet');
275
+ return;
276
+ }
277
+ // Resolve agent names for display
278
+ const agentIds = [...new Set(result.data.items.map((m) => m.senderAgentId))];
279
+ const agentNames = {};
280
+ for (const id of agentIds) {
281
+ try {
282
+ const agentResult = await api.getAgent(id);
283
+ if (agentResult.data)
284
+ agentNames[id] = agentResult.data.name;
285
+ }
286
+ catch {
287
+ // Fall back to truncated ID
288
+ }
289
+ }
290
+ output.heading('Messages');
291
+ for (const msg of result.data.items) {
292
+ const senderName = agentNames[msg.senderAgentId] ?? msg.senderAgentId.slice(0, 8) + '...';
293
+ const time = output.formatDate(msg.createdAt);
294
+ console.log(` ${output.dim(time)} ${output.bold(senderName)} [${msg.type}]`);
295
+ console.log(` ${msg.content.slice(0, 200)}${msg.content.length > 200 ? '...' : ''}`);
296
+ console.log();
297
+ }
298
+ if (result.data.nextCursor) {
299
+ output.info(`More messages available. Use --after ${result.data.nextCursor}`);
300
+ }
301
+ }
302
+ });
303
+ // ── workspace leave ─────────────────────────────────────────────────────
304
+ workspaces
305
+ .command('leave <workspaceId>')
306
+ .description('Leave a workspace (accepts name or ID)')
307
+ .requiredOption('--agent-id <id>', 'Your agent name or ID')
308
+ .action(async (workspaceIdOrName, options) => {
309
+ let workspaceId;
310
+ try {
311
+ workspaceId = await api.resolveWorkspace(workspaceIdOrName);
312
+ }
313
+ catch (e) {
314
+ output.error(e.message);
315
+ return;
316
+ }
317
+ let agentId;
318
+ try {
319
+ agentId = await api.resolveAgent(options.agentId);
320
+ }
321
+ catch (e) {
322
+ output.error(e.message);
323
+ return;
324
+ }
325
+ const spinner = ora('Leaving workspace...').start();
326
+ const result = await api.workspaceLeave(workspaceId, { agentId });
327
+ if (result.error) {
328
+ spinner.fail('Failed to leave workspace');
329
+ output.error(result.error.message);
330
+ return;
331
+ }
332
+ spinner.succeed('Left workspace');
333
+ });
334
+ // ── workspace close ─────────────────────────────────────────────────────
335
+ workspaces
336
+ .command('close <workspaceId>')
337
+ .description('Close a workspace (accepts name or ID)')
338
+ .option('--json', 'Output as JSON')
339
+ .action(async (workspaceIdOrName, options) => {
340
+ let workspaceId;
341
+ try {
342
+ workspaceId = await api.resolveWorkspace(workspaceIdOrName);
343
+ }
344
+ catch (e) {
345
+ output.error(e.message);
346
+ return;
347
+ }
348
+ const spinner = ora('Closing workspace...').start();
349
+ const result = await api.closeWorkspace(workspaceId);
350
+ if (result.error) {
351
+ spinner.fail('Failed to close workspace');
352
+ output.error(result.error.message);
353
+ return;
354
+ }
355
+ if (options.json) {
356
+ spinner.stop();
357
+ output.printJson({ id: workspaceId, status: 'closed' });
358
+ }
359
+ else {
360
+ spinner.succeed(`Workspace ${workspaceId} closed`);
361
+ }
362
+ });
363
+ // ── workspace watch ─────────────────────────────────────────────────────
364
+ workspaces
365
+ .command('watch <workspaceId>')
366
+ .description('Watch workspace activity (real-time observer stream, accepts name or ID)')
367
+ .option('--json', 'Output events as JSON')
368
+ .action(async (workspaceIdOrName, options) => {
369
+ let workspaceId;
370
+ try {
371
+ workspaceId = await api.resolveWorkspace(workspaceIdOrName);
372
+ }
373
+ catch (e) {
374
+ output.error(e.message);
375
+ return;
376
+ }
377
+ output.info(`Watching workspace ${workspaceId}...`);
378
+ output.info('Press Ctrl+C to stop\n');
379
+ try {
380
+ const eventSource = await api.workspaceStream(workspaceId);
381
+ if (!eventSource) {
382
+ output.error('Failed to connect to workspace stream');
383
+ return;
384
+ }
385
+ process.stdout.write('Connected to workspace stream\n\n');
386
+ // eventSource is already a ReadableStreamDefaultReader from api.workspaceStream()
387
+ const reader = eventSource;
388
+ const decoder = new TextDecoder();
389
+ let buffer = '';
390
+ while (true) {
391
+ const { done, value } = await reader.read();
392
+ if (done)
393
+ break;
394
+ buffer += decoder.decode(value, { stream: true });
395
+ const lines = buffer.split('\n');
396
+ buffer = lines.pop() ?? '';
397
+ for (const line of lines) {
398
+ if (line.startsWith('data: ')) {
399
+ const data = line.slice(6);
400
+ if (options.json) {
401
+ console.log(data);
402
+ }
403
+ else {
404
+ try {
405
+ const event = JSON.parse(data);
406
+ const time = new Date().toISOString().slice(11, 19);
407
+ console.log(`${output.dim(time)} ${output.bold(event.type ?? 'event')} ${JSON.stringify(event).slice(0, 100)}`);
408
+ }
409
+ catch {
410
+ console.log(data);
411
+ }
412
+ }
413
+ }
414
+ }
415
+ }
416
+ }
417
+ catch (err) {
418
+ if (err.name !== 'AbortError') {
419
+ output.error(`Stream error: ${err.message}`);
420
+ }
421
+ }
422
+ });
423
+ return workspaces;
424
+ }
425
+ // ── Policy generation commands (added to policies) ────────────────────────
426
+ export function createPolicyGenerateCommand() {
427
+ const generate = new Command('generate')
428
+ .description('Generate a policy from natural language using AI')
429
+ .requiredOption('--prompt <text>', 'Natural language description of the policy')
430
+ .option('--for-workspace <id>', 'Generate for a specific workspace')
431
+ .option('--json', 'Output as JSON')
432
+ .action(async (options) => {
433
+ const spinner = ora('Generating policy with AI...').start();
434
+ const result = await api.generatePolicy({
435
+ prompt: options.prompt,
436
+ workspaceId: options.forWorkspace,
437
+ mode: options.forWorkspace ? 'workspace' : 'single',
438
+ });
439
+ if (result.error) {
440
+ spinner.fail('Failed to generate policy');
441
+ output.error(result.error.message);
442
+ return;
443
+ }
444
+ if (options.json) {
445
+ spinner.stop();
446
+ output.printJson(result.data);
447
+ }
448
+ else {
449
+ spinner.succeed('Policy generated!');
450
+ if (result.data) {
451
+ console.log();
452
+ output.printKeyValue([
453
+ ['Generation ID', result.data.id],
454
+ ['Model', result.data.model],
455
+ ['Valid', result.data.validationResult?.valid ? 'Yes' : 'No'],
456
+ ]);
457
+ console.log();
458
+ output.heading('Generated Policy');
459
+ console.log(result.data.generatedPolicy);
460
+ }
461
+ }
462
+ });
463
+ return generate;
464
+ }
465
+ export function createPolicyRefineCommand() {
466
+ const refine = new Command('refine')
467
+ .description('Refine an existing policy with AI')
468
+ .argument('<policyId>', 'Policy ID to refine')
469
+ .requiredOption('--prompt <text>', 'Refinement instructions')
470
+ .option('--json', 'Output as JSON')
471
+ .action(async (policyId, options) => {
472
+ const spinner = ora('Refining policy with AI...').start();
473
+ const result = await api.generatePolicy({
474
+ prompt: options.prompt,
475
+ existingPolicyId: policyId,
476
+ mode: 'refine',
477
+ });
478
+ if (result.error) {
479
+ spinner.fail('Failed to refine policy');
480
+ output.error(result.error.message);
481
+ return;
482
+ }
483
+ if (options.json) {
484
+ spinner.stop();
485
+ output.printJson(result.data);
486
+ }
487
+ else {
488
+ spinner.succeed('Policy refined!');
489
+ if (result.data) {
490
+ console.log();
491
+ output.heading('Refined Policy');
492
+ console.log(result.data.generatedPolicy);
493
+ }
494
+ }
495
+ });
496
+ return refine;
497
+ }
498
+ // ── Helpers ─────────────────────────────────────────────────────────────────
499
+ function parseTtl(str) {
500
+ // Return ISO date string for the expiry
501
+ const match = str.match(/^(\d+)(ms|s|m|h|d)$/);
502
+ if (!match)
503
+ return new Date(Date.now() + 86_400_000).toISOString(); // default 24h
504
+ const value = Number(match[1]);
505
+ const unit = match[2];
506
+ const multipliers = {
507
+ ms: 1,
508
+ s: 1000,
509
+ m: 60_000,
510
+ h: 3_600_000,
511
+ d: 86_400_000,
512
+ };
513
+ return new Date(Date.now() + value * (multipliers[unit] ?? 1)).toISOString();
514
+ }
package/dist/config.d.ts CHANGED
@@ -1,14 +1,17 @@
1
- import Conf from 'conf';
1
+ import Conf from "conf";
2
2
  export interface EmotosConfig {
3
3
  apiUrl: string;
4
+ appUrl: string;
4
5
  apiKey?: string;
5
6
  sessionToken?: string;
6
7
  orgId?: string;
7
8
  orgName?: string;
8
9
  userId?: string;
9
10
  userName?: string;
10
- defaultEnvironment: 'development' | 'staging' | 'production';
11
- outputFormat: 'table' | 'json' | 'yaml';
11
+ defaultEnvironment: "development" | "staging" | "production";
12
+ outputFormat: "table" | "json" | "yaml";
13
+ openclawGatewayUrl?: string;
14
+ openclawToken?: string;
12
15
  }
13
16
  declare const config: Conf<EmotosConfig>;
14
17
  export declare function getConfig(): EmotosConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,aAAa,GAAG,SAAS,GAAG,YAAY,CAAC;IAC7D,YAAY,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;CACzC;AAoBD,QAAA,MAAM,MAAM,oBAIV,CAAC;AAEH,wBAAgB,SAAS,IAAI,YAAY,CAExC;AAED,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAE5F;AAED,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAgB,SAAS,IAAI,MAAM,GAAG,SAAS,CAE9C;AAED,wBAAgB,eAAe,IAAI,MAAM,GAAG,SAAS,CAEpD;AAED,wBAAgB,QAAQ,IAAI,MAAM,GAAG,SAAS,CAE7C;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWtD;AAED,OAAO,EAAE,MAAM,EAAE,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,aAAa,GAAG,SAAS,GAAG,YAAY,CAAC;IAC7D,YAAY,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACxC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AA2BD,QAAA,MAAM,MAAM,oBAIV,CAAC;AAEH,wBAAgB,SAAS,IAAI,YAAY,CAExC;AAED,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,YAAY,EACrD,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,GACpB,IAAI,CAMN;AAED,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAgB,SAAS,IAAI,MAAM,GAAG,SAAS,CAE9C;AAED,wBAAgB,eAAe,IAAI,MAAM,GAAG,SAAS,CAEpD;AAED,wBAAgB,QAAQ,IAAI,MAAM,GAAG,SAAS,CAE7C;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWtD;AAED,OAAO,EAAE,MAAM,EAAE,CAAC"}
package/dist/config.js CHANGED
@@ -1,22 +1,29 @@
1
- import Conf from 'conf';
1
+ import Conf from "conf";
2
2
  const defaults = {
3
- apiUrl: 'https://api.emotos.ai',
4
- defaultEnvironment: 'development',
5
- outputFormat: 'table',
3
+ apiUrl: process.env.EMOTOS_API_URL || "https://emotos.ai",
4
+ appUrl: process.env.EMOTOS_APP_URL || "https://emotos.ai",
5
+ defaultEnvironment: "development",
6
+ outputFormat: "table",
6
7
  };
7
8
  const schema = {
8
- apiUrl: { type: 'string' },
9
- apiKey: { type: 'string' },
10
- sessionToken: { type: 'string' },
11
- orgId: { type: 'string' },
12
- orgName: { type: 'string' },
13
- userId: { type: 'string' },
14
- userName: { type: 'string' },
15
- defaultEnvironment: { type: 'string', enum: ['development', 'staging', 'production'] },
16
- outputFormat: { type: 'string', enum: ['table', 'json', 'yaml'] },
9
+ apiUrl: { type: "string" },
10
+ appUrl: { type: "string" },
11
+ apiKey: { type: "string" },
12
+ sessionToken: { type: "string" },
13
+ orgId: { type: "string" },
14
+ orgName: { type: "string" },
15
+ userId: { type: "string" },
16
+ userName: { type: "string" },
17
+ defaultEnvironment: {
18
+ type: "string",
19
+ enum: ["development", "staging", "production"],
20
+ },
21
+ outputFormat: { type: "string", enum: ["table", "json", "yaml"] },
22
+ openclawGatewayUrl: { type: "string" },
23
+ openclawToken: { type: "string" },
17
24
  };
18
25
  const config = new Conf({
19
- projectName: 'emotos',
26
+ projectName: "emotos",
20
27
  defaults,
21
28
  schema,
22
29
  });
@@ -24,34 +31,38 @@ export function getConfig() {
24
31
  return config.store;
25
32
  }
26
33
  export function setConfig(key, value) {
34
+ if (value === undefined || value === null) {
35
+ config.delete(key);
36
+ return;
37
+ }
27
38
  config.set(key, value);
28
39
  }
29
40
  export function clearConfig() {
30
41
  config.clear();
31
42
  }
32
43
  export function getApiUrl() {
33
- return config.get('apiUrl');
44
+ return config.get("apiUrl");
34
45
  }
35
46
  export function getApiKey() {
36
- return config.get('apiKey');
47
+ return config.get("apiKey");
37
48
  }
38
49
  export function getSessionToken() {
39
- return config.get('sessionToken');
50
+ return config.get("sessionToken");
40
51
  }
41
52
  export function getOrgId() {
42
- return config.get('orgId');
53
+ return config.get("orgId");
43
54
  }
44
55
  export function isAuthenticated() {
45
- return !!(config.get('apiKey') || config.get('sessionToken'));
56
+ return !!(config.get("apiKey") || config.get("sessionToken"));
46
57
  }
47
58
  export function getAuthHeader() {
48
- const apiKey = config.get('apiKey');
49
- const sessionToken = config.get('sessionToken');
59
+ const apiKey = config.get("apiKey");
60
+ const sessionToken = config.get("sessionToken");
50
61
  if (apiKey) {
51
- return { 'Authorization': `Bearer ${apiKey}` };
62
+ return { Authorization: `Bearer ${apiKey}` };
52
63
  }
53
64
  if (sessionToken) {
54
- return { 'Authorization': `Bearer ${sessionToken}` };
65
+ return { Authorization: `Bearer ${sessionToken}` };
55
66
  }
56
67
  return {};
57
68
  }