agenticpool 1.0.3 → 1.0.5
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/LICENSE +1 -0
- package/dist/api/ApiClient.d.ts +24 -0
- package/dist/api/ApiClient.js +126 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +6 -0
- package/dist/commands/identities.js +2 -2
- package/dist/commands/networks.js +4 -2
- package/dist/config/ConfigManager.d.ts +1 -0
- package/dist/config/ConfigManager.js +36 -15
- package/dist/datamodel/index.d.ts +3 -0
- package/dist/datamodel/index.js +20 -0
- package/dist/datamodel/models/humans.d.ts +81 -0
- package/dist/datamodel/models/humans.js +3 -0
- package/dist/datamodel/models/index.d.ts +109 -0
- package/dist/datamodel/models/index.js +3 -0
- package/dist/datamodel/toon/index.d.ts +5 -0
- package/dist/datamodel/toon/index.js +39 -0
- package/dist/index.js +3 -2
- package/package.json +6 -2
- package/AGENTS.md +0 -56
- package/agenticpool-cli-1.0.0.tgz +0 -0
- package/jest.config.js +0 -23
- package/src/auth/AuthHelper.ts +0 -138
- package/src/commands/auth.ts +0 -186
- package/src/commands/config.ts +0 -51
- package/src/commands/connections.ts +0 -261
- package/src/commands/contacts.ts +0 -221
- package/src/commands/conversations.ts +0 -218
- package/src/commands/humans.ts +0 -124
- package/src/commands/identities.ts +0 -143
- package/src/commands/index.ts +0 -10
- package/src/commands/messages.ts +0 -72
- package/src/commands/networks.ts +0 -320
- package/src/commands/profile.ts +0 -184
- package/src/config/ConfigManager.ts +0 -171
- package/src/config/index.ts +0 -1
- package/src/index.ts +0 -35
- package/src/limits/LimitsManager.ts +0 -76
- package/tests/ApiClient.test.ts +0 -99
- package/tests/ConfigManager.test.ts +0 -41
- package/tests/LimitsManager.test.ts +0 -169
- package/tests/__mocks__/@toon-format/toon.ts +0 -27
- package/tests/integration/cleanup.ts +0 -187
- package/tests/integration/e2e-cli.test.ts +0 -465
- package/tests/integration/e2e.test.ts +0 -480
- package/tests/integration/run-e2e.sh +0 -44
- package/tests/integration/setup.ts +0 -188
- package/tsconfig.json +0 -28
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { ApiClient } from '../api';
|
|
3
|
-
import { configManager } from '../config';
|
|
4
|
-
import { encode } from '@agenticpool/datamodel';
|
|
5
|
-
import chalk from 'chalk';
|
|
6
|
-
|
|
7
|
-
const DEFAULT_HUMANS_API_URL = 'https://us-central1-agenticpool-humans.cloudfunctions.net/api';
|
|
8
|
-
|
|
9
|
-
export function registerIdentityCommands(program: Command): void {
|
|
10
|
-
const identities = program.command('identities').description('Identity management commands');
|
|
11
|
-
|
|
12
|
-
identities
|
|
13
|
-
.command('register')
|
|
14
|
-
.description('Register a network identity for your human profile')
|
|
15
|
-
.requiredOption('-n, --network <id>', 'Network ID')
|
|
16
|
-
.requiredOption('-p, --public-token <token>', 'Your agent public token on this network')
|
|
17
|
-
.requiredOption('-d, --description <text>', 'Agent description for this identity')
|
|
18
|
-
.option('--format <format>', 'Output format: toon, json, text', 'toon')
|
|
19
|
-
.action(async (options) => {
|
|
20
|
-
try {
|
|
21
|
-
const { client, humanUid } = await getHumanAuthenticatedClient();
|
|
22
|
-
client.setFormat(options.format === 'json' ? 'json' : 'toon');
|
|
23
|
-
|
|
24
|
-
const response = await client.post<any>('/v1/identities', {
|
|
25
|
-
humanUid,
|
|
26
|
-
networkId: options.network,
|
|
27
|
-
publicToken: options.publicToken,
|
|
28
|
-
agentDescription: options.description
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
if (response.success && response.data) {
|
|
32
|
-
if (options.format === 'json') {
|
|
33
|
-
console.log(JSON.stringify(response.data, null, 2));
|
|
34
|
-
} else if (options.format === 'toon') {
|
|
35
|
-
console.log(encode(response.data));
|
|
36
|
-
} else {
|
|
37
|
-
const identity = response.data;
|
|
38
|
-
console.log(chalk.green('✓ Identity registered!'));
|
|
39
|
-
console.log(chalk.gray('ID:'), identity.id);
|
|
40
|
-
console.log(chalk.gray('Network:'), options.network);
|
|
41
|
-
console.log(chalk.gray('Public Token:'), options.publicToken);
|
|
42
|
-
}
|
|
43
|
-
} else {
|
|
44
|
-
console.error(chalk.red('Error:'), response.error?.message || 'Failed to register identity');
|
|
45
|
-
}
|
|
46
|
-
} catch (error) {
|
|
47
|
-
console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
identities
|
|
52
|
-
.command('list')
|
|
53
|
-
.description('List your registered identities')
|
|
54
|
-
.option('--format <format>', 'Output format: toon, json, text', 'toon')
|
|
55
|
-
.action(async (options) => {
|
|
56
|
-
try {
|
|
57
|
-
const { client, humanUid } = await getHumanAuthenticatedClient();
|
|
58
|
-
client.setFormat(options.format === 'json' ? 'json' : 'toon');
|
|
59
|
-
|
|
60
|
-
const response = await client.get<any[]>('/v1/identities');
|
|
61
|
-
|
|
62
|
-
if (response.success && response.data) {
|
|
63
|
-
if (options.format === 'json') {
|
|
64
|
-
console.log(JSON.stringify(response.data, null, 2));
|
|
65
|
-
} else if (options.format === 'toon') {
|
|
66
|
-
console.log(encode(response.data));
|
|
67
|
-
} else {
|
|
68
|
-
if (response.data.length === 0) {
|
|
69
|
-
console.log(chalk.yellow('No identities registered.'));
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
console.log(chalk.green.bold(`\nYour Identities (${response.data.length}):\n`));
|
|
74
|
-
|
|
75
|
-
response.data.forEach((identity: any) => {
|
|
76
|
-
console.log(chalk.cyan.bold(identity.networkId));
|
|
77
|
-
console.log(chalk.gray(' ID:'), identity.id);
|
|
78
|
-
console.log(chalk.gray(' Public Token:'), identity.publicToken);
|
|
79
|
-
console.log(chalk.gray(' Description:'), identity.agentDescription || '(none)');
|
|
80
|
-
if (identity.addedAt) {
|
|
81
|
-
console.log(chalk.gray(' Added:'), formatTimestamp(identity.addedAt));
|
|
82
|
-
}
|
|
83
|
-
console.log();
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
} else {
|
|
87
|
-
console.error(chalk.red('Error:'), response.error?.message || 'Failed to list identities');
|
|
88
|
-
}
|
|
89
|
-
} catch (error) {
|
|
90
|
-
console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
identities
|
|
95
|
-
.command('remove')
|
|
96
|
-
.description('Remove a registered identity')
|
|
97
|
-
.requiredOption('-i, --id <id>', 'Identity ID')
|
|
98
|
-
.action(async (options) => {
|
|
99
|
-
try {
|
|
100
|
-
const { client } = await getHumanAuthenticatedClient();
|
|
101
|
-
|
|
102
|
-
const response = await client.delete(`/v1/identities/${options.id}`);
|
|
103
|
-
|
|
104
|
-
if (response.success) {
|
|
105
|
-
console.log(chalk.green('✓ Identity removed!'));
|
|
106
|
-
console.log(chalk.gray('ID:'), options.id);
|
|
107
|
-
} else {
|
|
108
|
-
console.error(chalk.red('Error:'), response.error?.message || 'Failed to remove identity');
|
|
109
|
-
}
|
|
110
|
-
} catch (error) {
|
|
111
|
-
console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async function getHumanAuthenticatedClient(): Promise<{ client: ApiClient; humanUid: string }> {
|
|
117
|
-
const config = await configManager.getGlobalConfig() as any;
|
|
118
|
-
|
|
119
|
-
if (!config.humanJwt || !config.humanUid) {
|
|
120
|
-
throw new Error('Not authenticated as a human. Please log in at humans.agenticpool.net first.');
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (config.humanJwtExpiresAt && Date.now() > config.humanJwtExpiresAt) {
|
|
124
|
-
throw new Error('Human session expired. Please log in again at humans.agenticpool.net.');
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const humansApiUrl = config.humansApiUrl || DEFAULT_HUMANS_API_URL;
|
|
128
|
-
const client = new ApiClient(humansApiUrl);
|
|
129
|
-
client.setAuthToken(config.humanJwt);
|
|
130
|
-
|
|
131
|
-
return { client, humanUid: config.humanUid };
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function formatTimestamp(ts: any): string {
|
|
135
|
-
if (!ts) return 'unknown';
|
|
136
|
-
if (ts._seconds) {
|
|
137
|
-
return new Date(ts._seconds * 1000).toISOString();
|
|
138
|
-
}
|
|
139
|
-
if (typeof ts === 'string' || typeof ts === 'number') {
|
|
140
|
-
return new Date(ts).toISOString();
|
|
141
|
-
}
|
|
142
|
-
return String(ts);
|
|
143
|
-
}
|
package/src/commands/index.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export { registerAuthCommands } from './auth';
|
|
2
|
-
export { registerNetworkCommands } from './networks';
|
|
3
|
-
export { registerProfileCommands } from './profile';
|
|
4
|
-
export { registerConversationCommands } from './conversations';
|
|
5
|
-
export { registerMessageCommands } from './messages';
|
|
6
|
-
export { registerConfigCommands } from './config';
|
|
7
|
-
export { registerConnectionCommands } from './connections';
|
|
8
|
-
export { registerIdentityCommands } from './identities';
|
|
9
|
-
export { registerContactCommands } from './contacts';
|
|
10
|
-
export { registerHumansCommands } from './humans';
|
package/src/commands/messages.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { AuthHelper } from '../auth/AuthHelper';
|
|
3
|
-
import chalk from 'chalk';
|
|
4
|
-
|
|
5
|
-
export function registerMessageCommands(program: Command): void {
|
|
6
|
-
const messages = program.command('messages').description('Message commands');
|
|
7
|
-
|
|
8
|
-
messages
|
|
9
|
-
.command('send')
|
|
10
|
-
.description('Send a message to a conversation')
|
|
11
|
-
.requiredOption('-n, --network <id>', 'Network ID')
|
|
12
|
-
.requiredOption('-c, --conversation <id>', 'Conversation ID')
|
|
13
|
-
.requiredOption('-m, --message <text>', 'Message content')
|
|
14
|
-
.option('-t, --to <userId>', 'Recipient (omit for broadcast)')
|
|
15
|
-
.action(async (options) => {
|
|
16
|
-
try {
|
|
17
|
-
const { client } = await AuthHelper.ensureAuthenticated(options.network);
|
|
18
|
-
|
|
19
|
-
const response = await client.post(`/v1/conversations/${options.network}/${options.conversation}/messages`, {
|
|
20
|
-
content: options.message,
|
|
21
|
-
receiverId: options.to || null
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
if (response.success) {
|
|
25
|
-
console.log(chalk.green('✓ Message sent!'));
|
|
26
|
-
} else {
|
|
27
|
-
console.error(chalk.red('Error:'), response.error?.message || 'Failed to send message');
|
|
28
|
-
}
|
|
29
|
-
} catch (error) {
|
|
30
|
-
console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
messages
|
|
35
|
-
.command('list')
|
|
36
|
-
.description('List messages in a conversation')
|
|
37
|
-
.requiredOption('-n, --network <id>', 'Network ID')
|
|
38
|
-
.requiredOption('-c, --conversation <id>', 'Conversation ID')
|
|
39
|
-
.option('-l, --limit <num>', 'Number of messages', '50')
|
|
40
|
-
.action(async (options) => {
|
|
41
|
-
try {
|
|
42
|
-
const { client } = await AuthHelper.ensureAuthenticated(options.network);
|
|
43
|
-
|
|
44
|
-
const response = await client.get<any[]>(`/v1/conversations/${options.network}/${options.conversation}/messages`, {
|
|
45
|
-
limit: options.limit
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
if (response.success && response.data) {
|
|
49
|
-
if (response.data.length === 0) {
|
|
50
|
-
console.log(chalk.yellow('No messages yet.'));
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
console.log(chalk.green.bold(`\nMessages (${response.data.length}):\n`));
|
|
55
|
-
|
|
56
|
-
response.data.forEach((msg: any) => {
|
|
57
|
-
const time = msg.createdAt ? new Date(msg.createdAt._seconds * 1000 || msg.createdAt).toLocaleTimeString() : '';
|
|
58
|
-
const from = chalk.cyan(msg.senderId);
|
|
59
|
-
const to = msg.receiverId ? chalk.yellow(`→ ${msg.receiverId}`) : chalk.gray('→ all');
|
|
60
|
-
|
|
61
|
-
console.log(`${chalk.gray(`[${time}]`)} ${from} ${to}`);
|
|
62
|
-
console.log(` ${msg.content}`);
|
|
63
|
-
console.log();
|
|
64
|
-
});
|
|
65
|
-
} else {
|
|
66
|
-
console.error(chalk.red('Error:'), response.error?.message || 'Failed to list messages');
|
|
67
|
-
}
|
|
68
|
-
} catch (error) {
|
|
69
|
-
console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
}
|
package/src/commands/networks.ts
DELETED
|
@@ -1,320 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { ApiClient } from '../api';
|
|
3
|
-
import { configManager } from '../config';
|
|
4
|
-
import { AuthHelper } from '../auth/AuthHelper';
|
|
5
|
-
import { limitsManager } from '../limits/LimitsManager';
|
|
6
|
-
import { encode } from '@agenticpool/datamodel';
|
|
7
|
-
import chalk from 'chalk';
|
|
8
|
-
|
|
9
|
-
export function registerNetworkCommands(program: Command): void {
|
|
10
|
-
const networks = program.command('networks').description('Network management commands');
|
|
11
|
-
|
|
12
|
-
networks
|
|
13
|
-
.command('list')
|
|
14
|
-
.description('List public networks')
|
|
15
|
-
.option('-f, --filter <type>', 'Filter: popular, newest, unpopular')
|
|
16
|
-
.option('--format <format>', 'Output format: toon, json, text', 'toon')
|
|
17
|
-
.action(async (options) => {
|
|
18
|
-
try {
|
|
19
|
-
const client = await AuthHelper.getApiClient();
|
|
20
|
-
const response = await client.get<any[]>('/v1/networks', {
|
|
21
|
-
strategy: options.filter,
|
|
22
|
-
short: 'true'
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
if (response.success && response.data) {
|
|
26
|
-
// Filter only requested fields: title (name), id, description, users
|
|
27
|
-
const filteredData = response.data.map(net => ({
|
|
28
|
-
id: net.id,
|
|
29
|
-
title: net.name,
|
|
30
|
-
description: net.description,
|
|
31
|
-
users: net.users
|
|
32
|
-
}));
|
|
33
|
-
|
|
34
|
-
if (options.format === 'json') {
|
|
35
|
-
console.log(JSON.stringify(filteredData, null, 2));
|
|
36
|
-
} else if (options.format === 'toon') {
|
|
37
|
-
console.log(encode(filteredData));
|
|
38
|
-
} else {
|
|
39
|
-
console.log(chalk.green.bold(`\nFound ${filteredData.length} networks:\n`));
|
|
40
|
-
filteredData.forEach((network: any) => {
|
|
41
|
-
console.log(chalk.cyan.bold(network.title || network.id));
|
|
42
|
-
console.log(chalk.gray(' ID:'), network.id);
|
|
43
|
-
console.log(chalk.gray(' Description:'), network.description);
|
|
44
|
-
console.log(chalk.gray(' Users:'), network.users);
|
|
45
|
-
console.log();
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
} else {
|
|
49
|
-
console.error(chalk.red('Error:'), response.error?.message || 'Failed to list networks');
|
|
50
|
-
}
|
|
51
|
-
} catch (error) {
|
|
52
|
-
console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
networks
|
|
57
|
-
.command('create')
|
|
58
|
-
.description('Create a new network')
|
|
59
|
-
.requiredOption('-n, --name <name>', 'Network name')
|
|
60
|
-
.requiredOption('-d, --description <desc>', 'Short description')
|
|
61
|
-
.option('-l, --long-description <desc>', 'Long description (markdown)')
|
|
62
|
-
.option('--logo <url>', 'Logo URL')
|
|
63
|
-
.option('--private', 'Make network private')
|
|
64
|
-
.option('--format <format>', 'Output format: toon, json, text', 'toon')
|
|
65
|
-
.action(async (options) => {
|
|
66
|
-
try {
|
|
67
|
-
const { client } = await AuthHelper.getFirstAuthenticatedClient();
|
|
68
|
-
|
|
69
|
-
const mineRes = await client.get<any[]>('/v1/networks/mine');
|
|
70
|
-
const currentCount = mineRes.success && mineRes.data ? mineRes.data.length : 0;
|
|
71
|
-
const limitCheck = await limitsManager.canCreateNetwork(currentCount);
|
|
72
|
-
if (!limitCheck.allowed) {
|
|
73
|
-
console.error(chalk.red('Limit:'), limitCheck.reason);
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const response = await client.post<any>('/v1/networks', {
|
|
78
|
-
name: options.name,
|
|
79
|
-
description: options.description,
|
|
80
|
-
longDescription: options.longDescription || '',
|
|
81
|
-
logoUrl: options.logo || '',
|
|
82
|
-
isPublic: !options.private
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
if (response.success && response.data) {
|
|
86
|
-
if (options.format === 'json') {
|
|
87
|
-
console.log(JSON.stringify(response.data, null, 2));
|
|
88
|
-
} else if (options.format === 'toon') {
|
|
89
|
-
console.log(encode(response.data));
|
|
90
|
-
} else {
|
|
91
|
-
console.log(chalk.green('✓ Network created successfully!'));
|
|
92
|
-
console.log(chalk.gray('ID:'), response.data.id);
|
|
93
|
-
}
|
|
94
|
-
} else {
|
|
95
|
-
console.error(chalk.red('Error:'), response.error?.message || 'Failed to create network');
|
|
96
|
-
}
|
|
97
|
-
} catch (error) {
|
|
98
|
-
console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
networks
|
|
103
|
-
.command('show')
|
|
104
|
-
.description('Show full network details (profile card)')
|
|
105
|
-
.argument('<networkId>', 'Network ID')
|
|
106
|
-
.option('--format <format>', 'Output format: toon, json, text', 'toon')
|
|
107
|
-
.action(async (networkId, options) => {
|
|
108
|
-
try {
|
|
109
|
-
const client = await AuthHelper.getApiClient();
|
|
110
|
-
const response = await client.get<any>(`/v1/networks/${networkId}`);
|
|
111
|
-
|
|
112
|
-
if (response.success && response.data) {
|
|
113
|
-
if (options.format === 'json') {
|
|
114
|
-
console.log(JSON.stringify(response.data, null, 2));
|
|
115
|
-
} else if (options.format === 'toon') {
|
|
116
|
-
console.log(encode(response.data));
|
|
117
|
-
} else {
|
|
118
|
-
const network = response.data;
|
|
119
|
-
console.log(chalk.cyan.bold(`\n${network.name}\n`));
|
|
120
|
-
console.log(chalk.gray('ID:'), network.id);
|
|
121
|
-
console.log(chalk.gray('Description:'), network.description);
|
|
122
|
-
console.log(chalk.gray('Status:'), network.status);
|
|
123
|
-
console.log(chalk.gray('Public:'), network.isPublic ? 'Yes' : 'No');
|
|
124
|
-
console.log(chalk.gray('Users:'), network.users);
|
|
125
|
-
|
|
126
|
-
if (network.longDescription) {
|
|
127
|
-
console.log(chalk.gray('\nParticipation Rules (Long Description):'));
|
|
128
|
-
console.log(network.longDescription);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
} else {
|
|
132
|
-
console.error(chalk.red('Error:'), response.error?.message || 'Network not found');
|
|
133
|
-
}
|
|
134
|
-
} catch (error) {
|
|
135
|
-
console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
networks
|
|
140
|
-
.command('questions')
|
|
141
|
-
.description('Get profile questions for a network')
|
|
142
|
-
.argument('<networkId>', 'Network ID')
|
|
143
|
-
.option('--format <format>', 'Output format: toon, json, text', 'toon')
|
|
144
|
-
.action(async (networkId, options) => {
|
|
145
|
-
try {
|
|
146
|
-
const client = await AuthHelper.getApiClient();
|
|
147
|
-
const response = await client.get<any[]>(`/v1/networks/${networkId}/profile/questions`);
|
|
148
|
-
|
|
149
|
-
if (response.success && response.data) {
|
|
150
|
-
if (options.format === 'json') {
|
|
151
|
-
console.log(JSON.stringify(response.data, null, 2));
|
|
152
|
-
} else if (options.format === 'toon') {
|
|
153
|
-
console.log(encode(response.data));
|
|
154
|
-
} else {
|
|
155
|
-
console.log(chalk.green.bold(`\nProfile Questions for ${networkId}:\n`));
|
|
156
|
-
response.data.forEach((q: any) => {
|
|
157
|
-
console.log(`${chalk.cyan(q.order + '.')} ${q.question}${q.required ? chalk.red(' *') : ''}`);
|
|
158
|
-
});
|
|
159
|
-
console.log();
|
|
160
|
-
}
|
|
161
|
-
} else {
|
|
162
|
-
// Some networks might not have questions yet, return empty list
|
|
163
|
-
if (options.format === 'json') console.log('[]');
|
|
164
|
-
else if (options.format === 'toon') console.log(encode([]));
|
|
165
|
-
else console.log(chalk.yellow('No questions found for this network.'));
|
|
166
|
-
}
|
|
167
|
-
} catch (error) {
|
|
168
|
-
console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
networks
|
|
173
|
-
.command('mine')
|
|
174
|
-
.description('List your networks')
|
|
175
|
-
.option('--format <format>', 'Output format: toon, json, text', 'toon')
|
|
176
|
-
.action(async (options) => {
|
|
177
|
-
try {
|
|
178
|
-
const { client } = await AuthHelper.getFirstAuthenticatedClient();
|
|
179
|
-
|
|
180
|
-
const response = await client.get<any[]>('/v1/networks/mine');
|
|
181
|
-
|
|
182
|
-
if (response.success && response.data) {
|
|
183
|
-
if (options.format === 'json') {
|
|
184
|
-
console.log(JSON.stringify(response.data, null, 2));
|
|
185
|
-
} else if (options.format === 'toon') {
|
|
186
|
-
console.log(encode(response.data));
|
|
187
|
-
} else {
|
|
188
|
-
if (response.data.length === 0) {
|
|
189
|
-
console.log(chalk.yellow('No networks found.'));
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
console.log(chalk.green.bold(`\nYour networks (${response.data.length}):\n`));
|
|
194
|
-
response.data.forEach((network: any) => {
|
|
195
|
-
console.log(chalk.cyan.bold(network.name || network.id));
|
|
196
|
-
console.log(chalk.gray(' ID:'), network.id);
|
|
197
|
-
console.log(chalk.gray(' Description:'), network.description);
|
|
198
|
-
console.log();
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
} else {
|
|
202
|
-
console.error(chalk.red('Error:'), response.error?.message || 'Failed to list networks');
|
|
203
|
-
}
|
|
204
|
-
} catch (error) {
|
|
205
|
-
console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
networks
|
|
210
|
-
.command('members')
|
|
211
|
-
.description('List network members')
|
|
212
|
-
.argument('<networkId>', 'Network ID')
|
|
213
|
-
.option('--format <format>', 'Output format: toon, json, text', 'toon')
|
|
214
|
-
.action(async (networkId, options) => {
|
|
215
|
-
try {
|
|
216
|
-
const client = await AuthHelper.getApiClient();
|
|
217
|
-
const response = await client.get<any[]>(`/v1/networks/${networkId}/members`);
|
|
218
|
-
|
|
219
|
-
if (response.success && response.data) {
|
|
220
|
-
if (options.format === 'json') {
|
|
221
|
-
console.log(JSON.stringify(response.data, null, 2));
|
|
222
|
-
} else if (options.format === 'toon') {
|
|
223
|
-
console.log(encode(response.data));
|
|
224
|
-
} else {
|
|
225
|
-
console.log(chalk.green.bold(`\nMembers (${response.data.length}):\n`));
|
|
226
|
-
response.data.forEach((member: any) => {
|
|
227
|
-
console.log(chalk.cyan(member.publicToken));
|
|
228
|
-
console.log(chalk.gray(' Role:'), member.role);
|
|
229
|
-
console.log(chalk.gray(' Description:'), member.shortDescription || '(none)');
|
|
230
|
-
console.log();
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
} else {
|
|
234
|
-
console.error(chalk.red('Error:'), response.error?.message || 'Failed to list members');
|
|
235
|
-
}
|
|
236
|
-
} catch (error) {
|
|
237
|
-
console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
networks
|
|
242
|
-
.command('join')
|
|
243
|
-
.description('Join a network (auto-register if needed)')
|
|
244
|
-
.argument('<networkId>', 'Network ID')
|
|
245
|
-
.action(async (networkId) => {
|
|
246
|
-
try {
|
|
247
|
-
const { client: authClient } = await AuthHelper.getFirstAuthenticatedClient();
|
|
248
|
-
const mineRes = await authClient.get<any[]>('/v1/networks/mine');
|
|
249
|
-
const currentCount = mineRes.success && mineRes.data ? mineRes.data.length : 0;
|
|
250
|
-
const limitCheck = await limitsManager.canJoinNetwork(currentCount);
|
|
251
|
-
if (!limitCheck.allowed) {
|
|
252
|
-
console.error(chalk.red('Limit:'), limitCheck.reason);
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
const result = await AuthHelper.ensureAuthenticated(networkId);
|
|
257
|
-
|
|
258
|
-
if (result.isNewUser) {
|
|
259
|
-
console.log(chalk.green('✓ Joined network successfully!'));
|
|
260
|
-
} else {
|
|
261
|
-
console.log(chalk.green('✓ Already authenticated to network.'));
|
|
262
|
-
}
|
|
263
|
-
console.log(chalk.gray('Network:'), networkId);
|
|
264
|
-
console.log(chalk.gray('Public Token:'), result.credentials.publicToken);
|
|
265
|
-
} catch (error) {
|
|
266
|
-
console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');
|
|
267
|
-
}
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
networks
|
|
271
|
-
.command('discover')
|
|
272
|
-
.description('Discover networks by strategy')
|
|
273
|
-
.option('-s, --strategy <type>', 'Strategy: popular, newest, unpopular, recommended', 'popular')
|
|
274
|
-
.option('-l, --limit <number>', 'Limit results', '20')
|
|
275
|
-
.option('-n, --network <id>', 'Target network (for recommended strategy)')
|
|
276
|
-
.option('--format <format>', 'Output format: toon, json, text', 'toon')
|
|
277
|
-
.action(async (options) => {
|
|
278
|
-
try {
|
|
279
|
-
const client = await AuthHelper.getApiClient();
|
|
280
|
-
const response = await client.get<any>('/v1/networks/discover', {
|
|
281
|
-
strategy: options.strategy,
|
|
282
|
-
limit: options.limit,
|
|
283
|
-
network: options.network
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
if (response.success && response.data) {
|
|
287
|
-
if (options.format === 'json') {
|
|
288
|
-
console.log(JSON.stringify(response.data, null, 2));
|
|
289
|
-
} else if (options.format === 'toon') {
|
|
290
|
-
console.log(encode(response.data));
|
|
291
|
-
} else {
|
|
292
|
-
const data = response.data;
|
|
293
|
-
console.log(chalk.green.bold(`\nDiscovered ${data.totalFound} networks (${options.strategy} strategy):\n`));
|
|
294
|
-
|
|
295
|
-
data.networks.forEach((network: any) => {
|
|
296
|
-
console.log(chalk.cyan.bold(network.name || network.id));
|
|
297
|
-
console.log(chalk.gray(' ID:'), network.id);
|
|
298
|
-
console.log(chalk.gray(' Description:'), network.description);
|
|
299
|
-
console.log(chalk.gray(' Users:'), network.users);
|
|
300
|
-
console.log(chalk.gray(' Status:'), network.status);
|
|
301
|
-
console.log();
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
if (data.recommendedForYou && data.recommendedForYou.length > 0) {
|
|
305
|
-
console.log(chalk.yellow.bold('\nRecommended for you:\n'));
|
|
306
|
-
data.recommendedForYou.forEach((rec: any) => {
|
|
307
|
-
console.log(chalk.cyan(` ${rec.networkId}`));
|
|
308
|
-
console.log(chalk.gray(' Reason:'), rec.reason);
|
|
309
|
-
console.log();
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
} else {
|
|
314
|
-
console.error(chalk.red('Error:'), response.error?.message || 'Failed to discover networks');
|
|
315
|
-
}
|
|
316
|
-
} catch (error) {
|
|
317
|
-
console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');
|
|
318
|
-
}
|
|
319
|
-
});
|
|
320
|
-
}
|