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.
- package/README.md +77 -294
- package/dist/api.d.ts +66 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +147 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +114 -32
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +58 -41
- package/dist/commands/index.d.ts +2 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +2 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +111 -19
- package/dist/commands/openclaw.d.ts +3 -0
- package/dist/commands/openclaw.d.ts.map +1 -0
- package/dist/commands/openclaw.js +1033 -0
- package/dist/commands/policies.d.ts.map +1 -1
- package/dist/commands/policies.js +137 -41
- package/dist/commands/threats.d.ts.map +1 -1
- package/dist/commands/threats.js +75 -29
- package/dist/commands/webhooks.d.ts.map +1 -1
- package/dist/commands/webhooks.js +24 -21
- package/dist/commands/workspaces.d.ts +5 -0
- package/dist/commands/workspaces.d.ts.map +1 -0
- package/dist/commands/workspaces.js +514 -0
- package/dist/config.d.ts +6 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +34 -23
- package/dist/index.js +178 -155
- package/dist/openclaw-api.d.ts +81 -0
- package/dist/openclaw-api.d.ts.map +1 -0
- package/dist/openclaw-api.js +262 -0
- package/package.json +6 -6
package/dist/api.js
CHANGED
|
@@ -47,6 +47,9 @@ class EmotosApiClient {
|
|
|
47
47
|
async signup(data) {
|
|
48
48
|
return this.request('POST', '/auth/signup', data, false);
|
|
49
49
|
}
|
|
50
|
+
async verify(token) {
|
|
51
|
+
return this.request('POST', '/auth/verify', { token }, false);
|
|
52
|
+
}
|
|
50
53
|
async logout() {
|
|
51
54
|
return this.request('POST', '/auth/logout');
|
|
52
55
|
}
|
|
@@ -63,6 +66,8 @@ class EmotosApiClient {
|
|
|
63
66
|
query.set('environment', params.environment);
|
|
64
67
|
if (params?.status)
|
|
65
68
|
query.set('status', params.status);
|
|
69
|
+
if (params?.name)
|
|
70
|
+
query.set('name', params.name);
|
|
66
71
|
if (params?.limit)
|
|
67
72
|
query.set('limit', String(params.limit));
|
|
68
73
|
if (params?.offset)
|
|
@@ -73,6 +78,44 @@ class EmotosApiClient {
|
|
|
73
78
|
async getAgent(agentId) {
|
|
74
79
|
return this.request('GET', `/agents/${agentId}`);
|
|
75
80
|
}
|
|
81
|
+
// ── Name-based resolvers ─────────────────────────────────────────────
|
|
82
|
+
// These let CLI commands accept either a UUID or a human-readable name.
|
|
83
|
+
async resolveAgent(nameOrId) {
|
|
84
|
+
if (isUuid(nameOrId))
|
|
85
|
+
return nameOrId;
|
|
86
|
+
const result = await this.listAgents({ name: nameOrId });
|
|
87
|
+
if (result.data?.items.length === 1)
|
|
88
|
+
return result.data.items[0].id;
|
|
89
|
+
if (result.data && result.data.items.length > 1)
|
|
90
|
+
throw new Error(`Multiple agents named "${nameOrId}". Use the ID instead.`);
|
|
91
|
+
throw new Error(`Agent "${nameOrId}" not found.`);
|
|
92
|
+
}
|
|
93
|
+
async resolveWorkspace(nameOrId) {
|
|
94
|
+
if (isUuid(nameOrId))
|
|
95
|
+
return nameOrId;
|
|
96
|
+
const result = await this.listWorkspaces({ name: nameOrId });
|
|
97
|
+
if (result.data?.items) {
|
|
98
|
+
const matches = result.data.items.filter((w) => w.name === nameOrId);
|
|
99
|
+
if (matches.length === 1)
|
|
100
|
+
return matches[0].id;
|
|
101
|
+
if (matches.length > 1)
|
|
102
|
+
throw new Error(`Multiple workspaces named "${nameOrId}". Use the ID instead.`);
|
|
103
|
+
}
|
|
104
|
+
throw new Error(`Workspace "${nameOrId}" not found.`);
|
|
105
|
+
}
|
|
106
|
+
async resolvePolicy(nameOrId) {
|
|
107
|
+
if (isUuid(nameOrId))
|
|
108
|
+
return nameOrId;
|
|
109
|
+
const result = await this.listPolicies();
|
|
110
|
+
if (result.data?.policies) {
|
|
111
|
+
const matches = result.data.policies.filter((p) => p.name === nameOrId);
|
|
112
|
+
if (matches.length === 1)
|
|
113
|
+
return matches[0].id;
|
|
114
|
+
if (matches.length > 1)
|
|
115
|
+
throw new Error(`Multiple policies named "${nameOrId}". Use the ID instead.`);
|
|
116
|
+
}
|
|
117
|
+
throw new Error(`Policy "${nameOrId}" not found.`);
|
|
118
|
+
}
|
|
76
119
|
async issueToken(agentId, ttlSeconds) {
|
|
77
120
|
return this.request('POST', `/agents/${agentId}/token`, { ttlSeconds });
|
|
78
121
|
}
|
|
@@ -167,5 +210,109 @@ class EmotosApiClient {
|
|
|
167
210
|
async getMetrics() {
|
|
168
211
|
return this.request('GET', '/metrics');
|
|
169
212
|
}
|
|
213
|
+
// Workspace endpoints
|
|
214
|
+
async createWorkspace(data) {
|
|
215
|
+
const result = await this.request('POST', '/workspaces', data);
|
|
216
|
+
// API wraps response in { workspace: {...} } — unwrap for consistency
|
|
217
|
+
if (result.data?.workspace) {
|
|
218
|
+
result.data = result.data.workspace;
|
|
219
|
+
}
|
|
220
|
+
return result;
|
|
221
|
+
}
|
|
222
|
+
async listWorkspaces(params) {
|
|
223
|
+
const query = new URLSearchParams();
|
|
224
|
+
if (params?.status)
|
|
225
|
+
query.set('status', params.status);
|
|
226
|
+
if (params?.name)
|
|
227
|
+
query.set('name', params.name);
|
|
228
|
+
const queryStr = query.toString();
|
|
229
|
+
const result = await this.request('GET', `/workspaces${queryStr ? `?${queryStr}` : ''}`);
|
|
230
|
+
// API returns { workspaces: [...] } — normalize to { items: [...] }
|
|
231
|
+
if (result.data && result.data.workspaces && !result.data.items) {
|
|
232
|
+
result.data.items = result.data.workspaces;
|
|
233
|
+
delete result.data.workspaces;
|
|
234
|
+
}
|
|
235
|
+
return result;
|
|
236
|
+
}
|
|
237
|
+
async getWorkspace(workspaceId) {
|
|
238
|
+
return this.request('GET', `/workspaces/${workspaceId}`);
|
|
239
|
+
}
|
|
240
|
+
async workspaceInvite(workspaceId, data) {
|
|
241
|
+
return this.request('POST', `/workspaces/${workspaceId}/invite`, data);
|
|
242
|
+
}
|
|
243
|
+
async workspaceJoin(workspaceId, data) {
|
|
244
|
+
return this.request('POST', `/workspaces/${workspaceId}/join`, data);
|
|
245
|
+
}
|
|
246
|
+
async workspaceLeave(workspaceId, data) {
|
|
247
|
+
return this.request('POST', `/workspaces/${workspaceId}/leave`, data);
|
|
248
|
+
}
|
|
249
|
+
async closeWorkspace(workspaceId) {
|
|
250
|
+
return this.request('DELETE', `/workspaces/${workspaceId}`);
|
|
251
|
+
}
|
|
252
|
+
async workspacePostMessage(workspaceId, data) {
|
|
253
|
+
const result = await this.request('POST', `/workspaces/${workspaceId}/messages`, data);
|
|
254
|
+
// API wraps response in { message: {...} } — unwrap for consistency
|
|
255
|
+
if (result.data?.message) {
|
|
256
|
+
result.data = result.data.message;
|
|
257
|
+
}
|
|
258
|
+
return result;
|
|
259
|
+
}
|
|
260
|
+
async workspaceMessages(workspaceId, params) {
|
|
261
|
+
const query = new URLSearchParams();
|
|
262
|
+
if (params?.after)
|
|
263
|
+
query.set('after', params.after);
|
|
264
|
+
if (params?.limit)
|
|
265
|
+
query.set('limit', String(params.limit));
|
|
266
|
+
const queryStr = query.toString();
|
|
267
|
+
const result = await this.request('GET', `/workspaces/${workspaceId}/messages${queryStr ? `?${queryStr}` : ''}`);
|
|
268
|
+
// API returns { messages: [...], cursor } — normalize to { items: [...], nextCursor }
|
|
269
|
+
if (result.data && result.data.messages && !result.data.items) {
|
|
270
|
+
result.data.items = result.data.messages;
|
|
271
|
+
delete result.data.messages;
|
|
272
|
+
}
|
|
273
|
+
if (result.data && result.data.cursor !== undefined && result.data.nextCursor === undefined) {
|
|
274
|
+
result.data.nextCursor = result.data.cursor;
|
|
275
|
+
delete result.data.cursor;
|
|
276
|
+
}
|
|
277
|
+
return result;
|
|
278
|
+
}
|
|
279
|
+
async workspacePresence(workspaceId) {
|
|
280
|
+
return this.request('GET', `/workspaces/${workspaceId}/presence`);
|
|
281
|
+
}
|
|
282
|
+
async workspaceStream(workspaceId) {
|
|
283
|
+
if (!isAuthenticated())
|
|
284
|
+
return null;
|
|
285
|
+
const url = `${getApiUrl()}/v1/workspaces/${workspaceId}/stream`;
|
|
286
|
+
try {
|
|
287
|
+
const response = await fetch(url, {
|
|
288
|
+
headers: { ...getAuthHeader(), Accept: 'text/event-stream' },
|
|
289
|
+
});
|
|
290
|
+
return response.body?.getReader() ?? null;
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
async generatePolicy(data) {
|
|
297
|
+
return this.request('POST', '/policies/generate', data);
|
|
298
|
+
}
|
|
299
|
+
// ── SSE streaming ────────────────────────────────────────────────────
|
|
300
|
+
async streamEvents(path) {
|
|
301
|
+
if (!isAuthenticated())
|
|
302
|
+
return null;
|
|
303
|
+
const url = `${getApiUrl()}/v1${path}`;
|
|
304
|
+
try {
|
|
305
|
+
const response = await fetch(url, {
|
|
306
|
+
headers: { ...getAuthHeader(), Accept: 'text/event-stream' },
|
|
307
|
+
});
|
|
308
|
+
return response.body?.getReader() ?? null;
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function isUuid(str) {
|
|
316
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(str);
|
|
170
317
|
}
|
|
171
318
|
export const api = new EmotosApiClient();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,mBAAmB,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,mBAAmB,IAAI,OAAO,CAiW7C"}
|
package/dist/commands/agents.js
CHANGED
|
@@ -129,9 +129,17 @@ export function createAgentsCommand() {
|
|
|
129
129
|
agents
|
|
130
130
|
.command('get <agentId>')
|
|
131
131
|
.alias('show')
|
|
132
|
-
.description('Get agent details')
|
|
132
|
+
.description('Get agent details (accepts name or ID)')
|
|
133
133
|
.option('--json', 'Output as JSON')
|
|
134
|
-
.action(async (
|
|
134
|
+
.action(async (agentIdOrName, options) => {
|
|
135
|
+
let agentId;
|
|
136
|
+
try {
|
|
137
|
+
agentId = await api.resolveAgent(agentIdOrName);
|
|
138
|
+
}
|
|
139
|
+
catch (e) {
|
|
140
|
+
output.error(e.message);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
135
143
|
const spinner = ora('Fetching agent...').start();
|
|
136
144
|
const result = await api.getAgent(agentId);
|
|
137
145
|
if (result.error) {
|
|
@@ -161,10 +169,18 @@ export function createAgentsCommand() {
|
|
|
161
169
|
agents
|
|
162
170
|
.command('token <agentId>')
|
|
163
171
|
.alias('issue-token')
|
|
164
|
-
.description('Issue a JWT token for an agent')
|
|
172
|
+
.description('Issue a JWT token for an agent (accepts name or ID)')
|
|
165
173
|
.option('-t, --ttl <seconds>', 'Token TTL in seconds', '3600')
|
|
166
174
|
.option('--json', 'Output as JSON')
|
|
167
|
-
.action(async (
|
|
175
|
+
.action(async (agentIdOrName, options) => {
|
|
176
|
+
let agentId;
|
|
177
|
+
try {
|
|
178
|
+
agentId = await api.resolveAgent(agentIdOrName);
|
|
179
|
+
}
|
|
180
|
+
catch (e) {
|
|
181
|
+
output.error(e.message);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
168
184
|
const spinner = ora('Issuing token...').start();
|
|
169
185
|
const result = await api.issueToken(agentId, Number.parseInt(options.ttl, 10));
|
|
170
186
|
if (result.error) {
|
|
@@ -190,9 +206,17 @@ export function createAgentsCommand() {
|
|
|
190
206
|
});
|
|
191
207
|
agents
|
|
192
208
|
.command('revoke <agentId>')
|
|
193
|
-
.description('Revoke an agent and all its tokens')
|
|
209
|
+
.description('Revoke an agent and all its tokens (accepts name or ID)')
|
|
194
210
|
.option('-f, --force', 'Skip confirmation')
|
|
195
|
-
.action(async (
|
|
211
|
+
.action(async (agentIdOrName, options) => {
|
|
212
|
+
let agentId;
|
|
213
|
+
try {
|
|
214
|
+
agentId = await api.resolveAgent(agentIdOrName);
|
|
215
|
+
}
|
|
216
|
+
catch (e) {
|
|
217
|
+
output.error(e.message);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
196
220
|
if (!options.force) {
|
|
197
221
|
const answers = await inquirer.prompt([
|
|
198
222
|
{
|
|
@@ -221,9 +245,17 @@ export function createAgentsCommand() {
|
|
|
221
245
|
});
|
|
222
246
|
agents
|
|
223
247
|
.command('rotate <agentId>')
|
|
224
|
-
.description('Rotate agent credentials')
|
|
248
|
+
.description('Rotate agent credentials (accepts name or ID)')
|
|
225
249
|
.option('--json', 'Output as JSON')
|
|
226
|
-
.action(async (
|
|
250
|
+
.action(async (agentIdOrName, options) => {
|
|
251
|
+
let agentId;
|
|
252
|
+
try {
|
|
253
|
+
agentId = await api.resolveAgent(agentIdOrName);
|
|
254
|
+
}
|
|
255
|
+
catch (e) {
|
|
256
|
+
output.error(e.message);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
227
259
|
const spinner = ora('Rotating credentials...').start();
|
|
228
260
|
const result = await api.rotateCredentials(agentId);
|
|
229
261
|
if (result.error) {
|
|
@@ -243,35 +275,85 @@ export function createAgentsCommand() {
|
|
|
243
275
|
});
|
|
244
276
|
agents
|
|
245
277
|
.command('monitor <agentId>')
|
|
246
|
-
.description('Monitor agent activity in real-time')
|
|
278
|
+
.description('Monitor agent activity in real-time (accepts name or ID)')
|
|
247
279
|
.option('-l, --limit <n>', 'Number of events to show', '10')
|
|
248
|
-
.action(async (
|
|
280
|
+
.action(async (agentIdOrName, options) => {
|
|
281
|
+
let agentId;
|
|
282
|
+
try {
|
|
283
|
+
agentId = await api.resolveAgent(agentIdOrName);
|
|
284
|
+
}
|
|
285
|
+
catch (e) {
|
|
286
|
+
output.error(e.message);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
249
289
|
output.heading(`Monitoring agent: ${agentId}`);
|
|
250
290
|
output.info('Press Ctrl+C to stop');
|
|
251
291
|
console.log();
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
});
|
|
257
|
-
if (result.data && result.data.items.length > 0) {
|
|
258
|
-
output.printAuditTable(result.data.items);
|
|
259
|
-
}
|
|
260
|
-
else {
|
|
261
|
-
output.dim('No recent events');
|
|
262
|
-
}
|
|
263
|
-
};
|
|
264
|
-
// Initial fetch
|
|
265
|
-
await fetchEvents();
|
|
266
|
-
// Poll every 5 seconds
|
|
267
|
-
const interval = setInterval(fetchEvents, 5000);
|
|
268
|
-
// Handle Ctrl+C
|
|
269
|
-
process.on('SIGINT', () => {
|
|
270
|
-
clearInterval(interval);
|
|
292
|
+
// Try SSE stream first, fall back to polling
|
|
293
|
+
const reader = await api.streamEvents(`/agents/${agentId}/stream`);
|
|
294
|
+
if (reader) {
|
|
295
|
+
output.info('Connected via real-time stream');
|
|
271
296
|
console.log();
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
297
|
+
const decoder = new TextDecoder();
|
|
298
|
+
let buffer = '';
|
|
299
|
+
const read = async () => {
|
|
300
|
+
try {
|
|
301
|
+
while (true) {
|
|
302
|
+
const { done, value } = await reader.read();
|
|
303
|
+
if (done)
|
|
304
|
+
break;
|
|
305
|
+
buffer += decoder.decode(value, { stream: true });
|
|
306
|
+
const lines = buffer.split('\n');
|
|
307
|
+
buffer = lines.pop() ?? '';
|
|
308
|
+
for (const line of lines) {
|
|
309
|
+
if (line.startsWith('data: ')) {
|
|
310
|
+
try {
|
|
311
|
+
const event = JSON.parse(line.slice(6));
|
|
312
|
+
const time = new Date().toISOString().slice(11, 19);
|
|
313
|
+
console.log(`${output.dim(time)} ${output.bold(event.eventType ?? 'event')} ${JSON.stringify(event).slice(0, 120)}`);
|
|
314
|
+
}
|
|
315
|
+
catch { /* ignore parse errors */ }
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
catch (err) {
|
|
321
|
+
if (err.name !== 'AbortError') {
|
|
322
|
+
output.warn('Stream disconnected, falling back to polling...');
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
read();
|
|
327
|
+
process.on('SIGINT', () => {
|
|
328
|
+
reader.cancel();
|
|
329
|
+
console.log();
|
|
330
|
+
output.info('Monitoring stopped');
|
|
331
|
+
process.exit(0);
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
// Fallback: polling every 5 seconds
|
|
336
|
+
const fetchEvents = async () => {
|
|
337
|
+
const result = await api.queryAuditEvents({
|
|
338
|
+
agentId,
|
|
339
|
+
limit: Number.parseInt(options.limit, 10),
|
|
340
|
+
});
|
|
341
|
+
if (result.data && result.data.items.length > 0) {
|
|
342
|
+
output.printAuditTable(result.data.items);
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
output.dim('No recent events');
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
await fetchEvents();
|
|
349
|
+
const interval = setInterval(fetchEvents, 5000);
|
|
350
|
+
process.on('SIGINT', () => {
|
|
351
|
+
clearInterval(interval);
|
|
352
|
+
console.log();
|
|
353
|
+
output.info('Monitoring stopped');
|
|
354
|
+
process.exit(0);
|
|
355
|
+
});
|
|
356
|
+
}
|
|
275
357
|
});
|
|
276
358
|
return agents;
|
|
277
359
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,iBAAiB,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,iBAAiB,IAAI,OAAO,CAuR3C"}
|
package/dist/commands/auth.js
CHANGED
|
@@ -14,6 +14,9 @@ export function createAuthCommand() {
|
|
|
14
14
|
.option('-p, --password <password>', 'Password')
|
|
15
15
|
.option('-k, --api-key <key>', 'Use API key instead of email/password')
|
|
16
16
|
.action(async (options) => {
|
|
17
|
+
console.log();
|
|
18
|
+
console.log(` Or log in via browser: ${output.link('https://emotos.ai/login')}`);
|
|
19
|
+
console.log();
|
|
17
20
|
if (options.apiKey) {
|
|
18
21
|
setConfig('apiKey', options.apiKey);
|
|
19
22
|
const spinner = ora('Verifying API key...').start();
|
|
@@ -63,14 +66,16 @@ export function createAuthCommand() {
|
|
|
63
66
|
return;
|
|
64
67
|
}
|
|
65
68
|
if (result.data) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
setConfig('
|
|
69
|
-
setConfig('
|
|
70
|
-
setConfig('
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
// API returns "token" or "sessionToken" depending on version
|
|
70
|
+
const sessionToken = result.data.sessionToken || result.data.token;
|
|
71
|
+
setConfig('sessionToken', sessionToken);
|
|
72
|
+
setConfig('orgId', result.data.org?.id);
|
|
73
|
+
setConfig('orgName', result.data.org?.name);
|
|
74
|
+
setConfig('userId', result.data.user?.id);
|
|
75
|
+
setConfig('userName', result.data.user?.name);
|
|
76
|
+
spinner.succeed(`Logged in as ${result.data.user?.name ?? result.data.org?.name ?? email}`);
|
|
77
|
+
output.info(`Organization: ${result.data.org?.name ?? 'N/A'}`);
|
|
78
|
+
output.info(`Role: ${result.data.user?.role ?? 'N/A'}`);
|
|
74
79
|
}
|
|
75
80
|
});
|
|
76
81
|
auth
|
|
@@ -79,13 +84,14 @@ export function createAuthCommand() {
|
|
|
79
84
|
.option('-e, --email <email>', 'Email address')
|
|
80
85
|
.option('-p, --password <password>', 'Password')
|
|
81
86
|
.option('-n, --name <name>', 'Your name')
|
|
82
|
-
.option('-r, --role <role>', 'Role (provider or consumer)', 'provider')
|
|
83
87
|
.option('-o, --org-name <name>', 'Organization name')
|
|
84
88
|
.action(async (options) => {
|
|
89
|
+
console.log();
|
|
90
|
+
console.log(` Or sign up via browser: ${output.link('https://emotos.ai/signup')}`);
|
|
91
|
+
console.log();
|
|
85
92
|
let email = options.email;
|
|
86
93
|
let password = options.password;
|
|
87
94
|
let name = options.name;
|
|
88
|
-
let role = options.role;
|
|
89
95
|
let orgName = options.orgName;
|
|
90
96
|
const prompts = [];
|
|
91
97
|
if (!email) {
|
|
@@ -113,17 +119,6 @@ export function createAuthCommand() {
|
|
|
113
119
|
validate: (input) => input.length > 0 || 'Name is required',
|
|
114
120
|
});
|
|
115
121
|
}
|
|
116
|
-
if (!role) {
|
|
117
|
-
prompts.push({
|
|
118
|
-
type: 'list',
|
|
119
|
-
name: 'role',
|
|
120
|
-
message: 'Select your role:',
|
|
121
|
-
choices: [
|
|
122
|
-
{ name: 'Agent Provider - I build and deploy AI agents', value: 'provider' },
|
|
123
|
-
{ name: 'Agent Consumer - I use AI agents and need to protect my systems', value: 'consumer' },
|
|
124
|
-
],
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
122
|
if (!orgName) {
|
|
128
123
|
prompts.push({
|
|
129
124
|
type: 'input',
|
|
@@ -136,9 +131,9 @@ export function createAuthCommand() {
|
|
|
136
131
|
email = email || answers.email;
|
|
137
132
|
password = password || answers.password;
|
|
138
133
|
name = name || answers.name;
|
|
139
|
-
role = role || answers.role;
|
|
140
134
|
orgName = orgName || answers.orgName;
|
|
141
135
|
}
|
|
136
|
+
const role = 'free';
|
|
142
137
|
const spinner = ora('Creating account...').start();
|
|
143
138
|
const result = await api.signup({ email, password, name, role, orgName: orgName || undefined });
|
|
144
139
|
if (result.error) {
|
|
@@ -147,20 +142,38 @@ export function createAuthCommand() {
|
|
|
147
142
|
return;
|
|
148
143
|
}
|
|
149
144
|
if (result.data) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
145
|
+
const data = result.data;
|
|
146
|
+
// API may return a verification-required response (no session yet)
|
|
147
|
+
if (data.requiresVerification) {
|
|
148
|
+
spinner.succeed('Account created — email verification required');
|
|
149
|
+
output.info(`Email: ${data.email}`);
|
|
150
|
+
if (data.orgApiKey) {
|
|
151
|
+
setConfig('apiKey', data.orgApiKey);
|
|
152
|
+
output.info(`Org API Key saved (use for auth until verified)`);
|
|
153
|
+
}
|
|
154
|
+
console.log();
|
|
155
|
+
output.info('Next steps:');
|
|
156
|
+
console.log(' 1. Verify your email (check inbox or API logs in dev mode)');
|
|
157
|
+
console.log(` 2. Then log in at: ${output.link('https://emotos.ai/login')}`);
|
|
158
|
+
console.log(' 3. Or run: agentspd auth login');
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
// Full session response (legacy / auto-verified flow)
|
|
162
|
+
const sessionToken = data.sessionToken || data.token;
|
|
163
|
+
setConfig('sessionToken', sessionToken);
|
|
164
|
+
setConfig('orgId', data.org?.id);
|
|
165
|
+
setConfig('orgName', data.org?.name);
|
|
166
|
+
setConfig('userId', data.user?.id);
|
|
167
|
+
setConfig('userName', data.user?.name);
|
|
155
168
|
spinner.succeed('Account created successfully!');
|
|
156
|
-
output.info(`Welcome, ${
|
|
157
|
-
output.info(`Organization: ${
|
|
158
|
-
output.info(`Role: ${result.data.user.role}`);
|
|
169
|
+
output.info(`Welcome, ${data.user?.name ?? email}!`);
|
|
170
|
+
output.info(`Organization: ${data.org?.name ?? orgName ?? 'N/A'}`);
|
|
159
171
|
console.log();
|
|
160
172
|
output.info('Next steps:');
|
|
161
|
-
console.log(
|
|
162
|
-
console.log('
|
|
163
|
-
console.log('
|
|
173
|
+
console.log(` Dashboard: ${output.link('https://emotos.ai')}`);
|
|
174
|
+
console.log(' 1. Run the quickstart: agentspd init');
|
|
175
|
+
console.log(' 2. Or manually: agentspd policies create && agentspd agents create');
|
|
176
|
+
console.log(' 3. Point your agent at: wss://emotos.ai/v1/mcp');
|
|
164
177
|
}
|
|
165
178
|
});
|
|
166
179
|
auth
|
|
@@ -178,6 +191,7 @@ export function createAuthCommand() {
|
|
|
178
191
|
});
|
|
179
192
|
auth
|
|
180
193
|
.command('whoami')
|
|
194
|
+
.alias('me')
|
|
181
195
|
.description('Show current user information')
|
|
182
196
|
.action(async () => {
|
|
183
197
|
if (!isAuthenticated()) {
|
|
@@ -194,14 +208,17 @@ export function createAuthCommand() {
|
|
|
194
208
|
spinner.stop();
|
|
195
209
|
if (result.data) {
|
|
196
210
|
output.heading('Current User');
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
['Email', result.data.user.email],
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
['Org
|
|
203
|
-
|
|
204
|
-
|
|
211
|
+
const pairs = [];
|
|
212
|
+
if (result.data.user) {
|
|
213
|
+
pairs.push(['Name', result.data.user.name], ['Email', result.data.user.email], ['Role', result.data.user.role]);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
pairs.push(['Auth', 'Org API Key']);
|
|
217
|
+
}
|
|
218
|
+
if (result.data.org) {
|
|
219
|
+
pairs.push(['Organization', result.data.org.name], ['Org ID', result.data.org.id], ['Tier', result.data.org.tier]);
|
|
220
|
+
}
|
|
221
|
+
output.printKeyValue(pairs);
|
|
205
222
|
}
|
|
206
223
|
});
|
|
207
224
|
auth
|
package/dist/commands/index.d.ts
CHANGED
|
@@ -6,4 +6,6 @@ export { createThreatsCommand } from './threats.js';
|
|
|
6
6
|
export { createWebhooksCommand } from './webhooks.js';
|
|
7
7
|
export { createConfigCommand } from './config-cmd.js';
|
|
8
8
|
export { createInitCommand } from './init.js';
|
|
9
|
+
export { createWorkspacesCommand, createPolicyGenerateCommand, createPolicyRefineCommand } from './workspaces.js';
|
|
10
|
+
export { createOpenClawCommand } from './openclaw.js';
|
|
9
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAClH,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/commands/index.js
CHANGED
|
@@ -6,3 +6,5 @@ export { createThreatsCommand } from './threats.js';
|
|
|
6
6
|
export { createWebhooksCommand } from './webhooks.js';
|
|
7
7
|
export { createConfigCommand } from './config-cmd.js';
|
|
8
8
|
export { createInitCommand } from './init.js';
|
|
9
|
+
export { createWorkspacesCommand, createPolicyGenerateCommand, createPolicyRefineCommand } from './workspaces.js';
|
|
10
|
+
export { createOpenClawCommand } from './openclaw.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmOpC,wBAAgB,iBAAiB,IAAI,OAAO,CA4K3C"}
|