@trust-ethos/cli 0.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.
Files changed (104) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1791 -0
  3. package/bin/dev.cmd +3 -0
  4. package/bin/dev.js +5 -0
  5. package/bin/run.cmd +3 -0
  6. package/bin/run.js +5 -0
  7. package/dist/commands/auction/active.d.ts +10 -0
  8. package/dist/commands/auction/active.js +39 -0
  9. package/dist/commands/auction/info.d.ts +16 -0
  10. package/dist/commands/auction/info.js +46 -0
  11. package/dist/commands/auction/list.d.ts +14 -0
  12. package/dist/commands/auction/list.js +61 -0
  13. package/dist/commands/broker/info.d.ts +16 -0
  14. package/dist/commands/broker/info.js +37 -0
  15. package/dist/commands/broker/list.d.ts +15 -0
  16. package/dist/commands/broker/list.js +62 -0
  17. package/dist/commands/config/get.d.ts +9 -0
  18. package/dist/commands/config/get.js +29 -0
  19. package/dist/commands/config/path.d.ts +6 -0
  20. package/dist/commands/config/path.js +12 -0
  21. package/dist/commands/config/set.d.ts +9 -0
  22. package/dist/commands/config/set.js +28 -0
  23. package/dist/commands/listing/info.d.ts +13 -0
  24. package/dist/commands/listing/info.js +41 -0
  25. package/dist/commands/listing/list.d.ts +13 -0
  26. package/dist/commands/listing/list.js +46 -0
  27. package/dist/commands/listing/voters.d.ts +19 -0
  28. package/dist/commands/listing/voters.js +48 -0
  29. package/dist/commands/market/featured.d.ts +10 -0
  30. package/dist/commands/market/featured.js +34 -0
  31. package/dist/commands/market/holders.d.ts +14 -0
  32. package/dist/commands/market/holders.js +46 -0
  33. package/dist/commands/market/info.d.ts +14 -0
  34. package/dist/commands/market/info.js +48 -0
  35. package/dist/commands/market/list.d.ts +16 -0
  36. package/dist/commands/market/list.js +55 -0
  37. package/dist/commands/nft/list.d.ts +15 -0
  38. package/dist/commands/nft/list.js +64 -0
  39. package/dist/commands/review/info.d.ts +17 -0
  40. package/dist/commands/review/info.js +49 -0
  41. package/dist/commands/review/list.d.ts +16 -0
  42. package/dist/commands/review/list.js +68 -0
  43. package/dist/commands/review/votes.d.ts +21 -0
  44. package/dist/commands/review/votes.js +91 -0
  45. package/dist/commands/score/status.d.ts +13 -0
  46. package/dist/commands/score/status.js +54 -0
  47. package/dist/commands/slash/info.d.ts +16 -0
  48. package/dist/commands/slash/info.js +42 -0
  49. package/dist/commands/slash/list.d.ts +15 -0
  50. package/dist/commands/slash/list.js +50 -0
  51. package/dist/commands/slash/votes.d.ts +21 -0
  52. package/dist/commands/slash/votes.js +91 -0
  53. package/dist/commands/user/activity.d.ts +15 -0
  54. package/dist/commands/user/activity.js +71 -0
  55. package/dist/commands/user/info.d.ts +14 -0
  56. package/dist/commands/user/info.js +51 -0
  57. package/dist/commands/user/invitations.d.ts +16 -0
  58. package/dist/commands/user/invitations.js +73 -0
  59. package/dist/commands/user/search.d.ts +15 -0
  60. package/dist/commands/user/search.js +59 -0
  61. package/dist/commands/user/summary.d.ts +14 -0
  62. package/dist/commands/user/summary.js +134 -0
  63. package/dist/commands/validator/info.d.ts +13 -0
  64. package/dist/commands/validator/info.js +53 -0
  65. package/dist/commands/validator/list.d.ts +13 -0
  66. package/dist/commands/validator/list.js +64 -0
  67. package/dist/commands/validator/sales.d.ts +12 -0
  68. package/dist/commands/validator/sales.js +52 -0
  69. package/dist/commands/vouch/info.d.ts +17 -0
  70. package/dist/commands/vouch/info.js +53 -0
  71. package/dist/commands/vouch/list.d.ts +18 -0
  72. package/dist/commands/vouch/list.js +89 -0
  73. package/dist/commands/vouch/mutual.d.ts +15 -0
  74. package/dist/commands/vouch/mutual.js +68 -0
  75. package/dist/commands/vouch/votes.d.ts +21 -0
  76. package/dist/commands/vouch/votes.js +91 -0
  77. package/dist/commands/xp/rank.d.ts +15 -0
  78. package/dist/commands/xp/rank.js +74 -0
  79. package/dist/commands/xp/seasons.d.ts +10 -0
  80. package/dist/commands/xp/seasons.js +42 -0
  81. package/dist/hooks/init.d.ts +3 -0
  82. package/dist/hooks/init.js +40 -0
  83. package/dist/index.d.ts +1 -0
  84. package/dist/index.js +1 -0
  85. package/dist/lib/api/echo-client.d.ts +624 -0
  86. package/dist/lib/api/echo-client.js +408 -0
  87. package/dist/lib/config/index.d.ts +6 -0
  88. package/dist/lib/config/index.js +32 -0
  89. package/dist/lib/errors/cli-error.d.ts +23 -0
  90. package/dist/lib/errors/cli-error.js +57 -0
  91. package/dist/lib/formatting/colors.d.ts +13 -0
  92. package/dist/lib/formatting/colors.js +22 -0
  93. package/dist/lib/formatting/error.d.ts +1 -0
  94. package/dist/lib/formatting/error.js +64 -0
  95. package/dist/lib/formatting/output.d.ts +45 -0
  96. package/dist/lib/formatting/output.js +753 -0
  97. package/dist/lib/help.d.ts +4 -0
  98. package/dist/lib/help.js +28 -0
  99. package/dist/lib/update/index.d.ts +37 -0
  100. package/dist/lib/update/index.js +286 -0
  101. package/dist/lib/validation/userkey.d.ts +11 -0
  102. package/dist/lib/validation/userkey.js +81 -0
  103. package/oclif.manifest.json +2224 -0
  104. package/package.json +87 -0
@@ -0,0 +1,42 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { EchoClient } from '../../lib/api/echo-client.js';
3
+ import { formatSlash, output } from '../../lib/formatting/output.js';
4
+ import { formatError } from '../../lib/formatting/error.js';
5
+ export default class SlashInfo extends Command {
6
+ static description = 'Get details of a specific slash';
7
+ static args = {
8
+ id: Args.integer({ description: 'Slash ID', required: true }),
9
+ };
10
+ static examples = [
11
+ '<%= config.bin %> <%= command.id %> 123',
12
+ '<%= config.bin %> <%= command.id %> 123 --json',
13
+ ];
14
+ static flags = {
15
+ json: Flags.boolean({ char: 'j', description: 'Output as JSON' }),
16
+ verbose: Flags.boolean({ char: 'v', description: 'Show detailed error information' }),
17
+ };
18
+ async run() {
19
+ const { args, flags } = await this.parse(SlashInfo);
20
+ const client = new EchoClient();
21
+ try {
22
+ // Get slashes filtered by ID (API doesn't have direct ID lookup, so filter)
23
+ const response = await client.getSlashes({ limit: 100 });
24
+ const slash = response.data.values.find((s) => s.id === args.id);
25
+ if (!slash) {
26
+ throw new Error(`Slash #${args.id} not found`);
27
+ }
28
+ if (flags.json) {
29
+ this.log(output(slash));
30
+ }
31
+ else {
32
+ this.log(formatSlash(slash));
33
+ }
34
+ }
35
+ catch (error) {
36
+ if (error instanceof Error) {
37
+ this.log(formatError(error, flags.verbose));
38
+ this.exit(1);
39
+ }
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,15 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class SlashList extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ status: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ author: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ subject: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
12
+ offset: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
13
+ };
14
+ run(): Promise<void>;
15
+ }
@@ -0,0 +1,50 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { EchoClient } from '../../lib/api/echo-client.js';
3
+ import { formatSlashes, output } from '../../lib/formatting/output.js';
4
+ import { formatError } from '../../lib/formatting/error.js';
5
+ export default class SlashList extends Command {
6
+ static description = 'List reputation slashes';
7
+ static examples = [
8
+ '<%= config.bin %> <%= command.id %>',
9
+ '<%= config.bin %> <%= command.id %> --status open',
10
+ '<%= config.bin %> <%= command.id %> --subject twitter:0xNowater',
11
+ '<%= config.bin %> <%= command.id %> --limit 5 --json',
12
+ ];
13
+ static flags = {
14
+ json: Flags.boolean({ char: 'j', description: 'Output as JSON' }),
15
+ verbose: Flags.boolean({ char: 'v', description: 'Show detailed error information' }),
16
+ status: Flags.string({
17
+ description: 'Filter by status',
18
+ options: ['open', 'closed'],
19
+ }),
20
+ author: Flags.string({ description: 'Filter by slasher userkey' }),
21
+ subject: Flags.string({ description: 'Filter by subject userkey' }),
22
+ limit: Flags.integer({ char: 'l', description: 'Max results per request', default: 10 }),
23
+ offset: Flags.integer({ char: 'o', description: 'Number of results to skip', default: 0 }),
24
+ };
25
+ async run() {
26
+ const { flags } = await this.parse(SlashList);
27
+ const client = new EchoClient();
28
+ try {
29
+ const response = await client.getSlashes({
30
+ author: flags.author,
31
+ subject: flags.subject,
32
+ status: flags.status,
33
+ limit: flags.limit,
34
+ offset: flags.offset,
35
+ });
36
+ if (flags.json) {
37
+ this.log(output(response.data));
38
+ }
39
+ else {
40
+ this.log(formatSlashes(response.data.values, response.data.total));
41
+ }
42
+ }
43
+ catch (error) {
44
+ if (error instanceof Error) {
45
+ this.log(formatError(error, flags.verbose));
46
+ this.exit(1);
47
+ }
48
+ }
49
+ }
50
+ }
@@ -0,0 +1,21 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class SlashVotes extends Command {
3
+ static args: {
4
+ id: import("@oclif/core/interfaces").Arg<number, {
5
+ max?: number;
6
+ min?: number;
7
+ }>;
8
+ };
9
+ static description: string;
10
+ static examples: string[];
11
+ static flags: {
12
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
+ stats: import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
+ upvotes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
16
+ downvotes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
17
+ limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
18
+ offset: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
19
+ };
20
+ run(): Promise<void>;
21
+ }
@@ -0,0 +1,91 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { EchoClient } from '../../lib/api/echo-client.js';
3
+ import { formatError } from '../../lib/formatting/error.js';
4
+ import { formatVotes, formatVoteStats, output } from '../../lib/formatting/output.js';
5
+ export default class SlashVotes extends Command {
6
+ static args = {
7
+ id: Args.integer({
8
+ description: 'Slash ID',
9
+ required: true,
10
+ }),
11
+ };
12
+ static description = 'Show votes on a slash';
13
+ static examples = [
14
+ '<%= config.bin %> <%= command.id %> 195',
15
+ '<%= config.bin %> <%= command.id %> 195 --stats',
16
+ '<%= config.bin %> <%= command.id %> 195 --upvotes',
17
+ '<%= config.bin %> <%= command.id %> 195 --json',
18
+ ];
19
+ static flags = {
20
+ json: Flags.boolean({
21
+ char: 'j',
22
+ description: 'Output as JSON',
23
+ default: false,
24
+ }),
25
+ verbose: Flags.boolean({
26
+ char: 'v',
27
+ description: 'Show detailed error information',
28
+ default: false,
29
+ }),
30
+ stats: Flags.boolean({
31
+ char: 's',
32
+ description: 'Show vote statistics only',
33
+ default: false,
34
+ }),
35
+ upvotes: Flags.boolean({
36
+ description: 'Show only upvotes',
37
+ exclusive: ['downvotes'],
38
+ }),
39
+ downvotes: Flags.boolean({
40
+ description: 'Show only downvotes',
41
+ exclusive: ['upvotes'],
42
+ }),
43
+ limit: Flags.integer({
44
+ char: 'l',
45
+ description: 'Max results per request',
46
+ default: 10,
47
+ }),
48
+ offset: Flags.integer({
49
+ char: 'o',
50
+ description: 'Number of results to skip',
51
+ default: 0,
52
+ }),
53
+ };
54
+ async run() {
55
+ const { args, flags } = await this.parse(SlashVotes);
56
+ const client = new EchoClient();
57
+ try {
58
+ if (flags.stats) {
59
+ const stats = await client.getVoteStats(args.id, 'slash');
60
+ if (flags.json) {
61
+ this.log(output(stats));
62
+ }
63
+ else {
64
+ this.log(formatVoteStats(stats, 'slash', args.id));
65
+ }
66
+ return;
67
+ }
68
+ const params = {
69
+ limit: flags.limit,
70
+ offset: flags.offset,
71
+ };
72
+ if (flags.upvotes)
73
+ params.isUpvote = true;
74
+ if (flags.downvotes)
75
+ params.isUpvote = false;
76
+ const response = await client.getVotes(args.id, 'slash', params);
77
+ if (flags.json) {
78
+ this.log(output(response));
79
+ }
80
+ else {
81
+ this.log(formatVotes(response.values, response.total, 'slash'));
82
+ }
83
+ }
84
+ catch (error) {
85
+ if (error instanceof Error) {
86
+ this.log(formatError(error, flags.verbose));
87
+ this.exit(1);
88
+ }
89
+ }
90
+ }
91
+ }
@@ -0,0 +1,15 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class UserActivity extends Command {
3
+ static args: {
4
+ identifier: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
11
+ type: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ };
14
+ run(): Promise<void>;
15
+ }
@@ -0,0 +1,71 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { EchoClient } from '../../lib/api/echo-client.js';
3
+ import { formatError } from '../../lib/formatting/error.js';
4
+ import { formatActivities, output } from '../../lib/formatting/output.js';
5
+ export default class UserActivity extends Command {
6
+ static args = {
7
+ identifier: Args.string({
8
+ description: 'Twitter username, ETH address, or ENS name',
9
+ required: true,
10
+ }),
11
+ };
12
+ static description = 'Show recent reviews and vouches for a user';
13
+ static examples = [
14
+ '<%= config.bin %> <%= command.id %> 0xNowater',
15
+ '<%= config.bin %> <%= command.id %> 0xNowater --type vouch',
16
+ '<%= config.bin %> <%= command.id %> 0xNowater --type review --limit 5',
17
+ '<%= config.bin %> <%= command.id %> 0xNowater --json',
18
+ ];
19
+ static flags = {
20
+ json: Flags.boolean({
21
+ char: 'j',
22
+ description: 'Output as JSON',
23
+ default: false,
24
+ }),
25
+ limit: Flags.integer({
26
+ char: 'l',
27
+ description: 'Maximum number of activities',
28
+ default: 10,
29
+ }),
30
+ type: Flags.string({
31
+ char: 't',
32
+ description: 'Filter by activity type',
33
+ options: ['vouch', 'review'],
34
+ }),
35
+ verbose: Flags.boolean({
36
+ char: 'v',
37
+ description: 'Show detailed error information',
38
+ default: false,
39
+ }),
40
+ };
41
+ async run() {
42
+ const { args, flags } = await this.parse(UserActivity);
43
+ if (flags.limit < 1 || flags.limit > 100) {
44
+ this.error('limit must be between 1 and 100', { exit: 2 });
45
+ }
46
+ const client = new EchoClient();
47
+ try {
48
+ const user = await client.resolveUser(args.identifier);
49
+ const userkey = client.getPrimaryUserkey(user);
50
+ if (!userkey) {
51
+ throw new Error('User has no valid userkey for activity lookup');
52
+ }
53
+ const types = flags.type
54
+ ? [flags.type]
55
+ : ['review', 'vouch'];
56
+ const activities = await client.getActivities(userkey, types, flags.limit);
57
+ if (flags.json) {
58
+ this.log(output({ user: user.username || user.displayName, activities }));
59
+ }
60
+ else {
61
+ this.log(formatActivities(activities, user.username || user.displayName));
62
+ }
63
+ }
64
+ catch (error) {
65
+ if (error instanceof Error) {
66
+ this.log(formatError(error, flags.verbose));
67
+ this.exit(1);
68
+ }
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,14 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class UserInfo extends Command {
3
+ static aliases: string[];
4
+ static args: {
5
+ identifier: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
6
+ };
7
+ static description: string;
8
+ static examples: string[];
9
+ static flags: {
10
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ };
13
+ run(): Promise<void>;
14
+ }
@@ -0,0 +1,51 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { EchoClient } from '../../lib/api/echo-client.js';
3
+ import { formatError } from '../../lib/formatting/error.js';
4
+ import { formatUser, output } from '../../lib/formatting/output.js';
5
+ export default class UserInfo extends Command {
6
+ static aliases = ['u', 'ui'];
7
+ static args = {
8
+ identifier: Args.string({
9
+ description: 'Twitter username, ETH address, or ENS name',
10
+ required: true,
11
+ }),
12
+ };
13
+ static description = 'Display user profile by username, address, or ENS name';
14
+ static examples = [
15
+ '<%= config.bin %> <%= command.id %> 0xNowater',
16
+ '<%= config.bin %> <%= command.id %> 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
17
+ '<%= config.bin %> <%= command.id %> vitalik.eth',
18
+ '<%= config.bin %> <%= command.id %> 0xNowater --json',
19
+ ];
20
+ static flags = {
21
+ json: Flags.boolean({
22
+ char: 'j',
23
+ description: 'Output as JSON',
24
+ default: false,
25
+ }),
26
+ verbose: Flags.boolean({
27
+ char: 'v',
28
+ description: 'Show detailed error information',
29
+ default: false,
30
+ }),
31
+ };
32
+ async run() {
33
+ const { args, flags } = await this.parse(UserInfo);
34
+ const client = new EchoClient();
35
+ try {
36
+ const user = await client.resolveUser(args.identifier);
37
+ if (flags.json) {
38
+ this.log(output(user));
39
+ }
40
+ else {
41
+ this.log(formatUser(user));
42
+ }
43
+ }
44
+ catch (error) {
45
+ if (error instanceof Error) {
46
+ this.log(formatError(error, flags.verbose));
47
+ this.exit(1);
48
+ }
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,16 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class UserInvitations extends Command {
3
+ static args: {
4
+ identifier: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ status: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
13
+ offset: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
14
+ };
15
+ run(): Promise<void>;
16
+ }
@@ -0,0 +1,73 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { EchoClient } from '../../lib/api/echo-client.js';
3
+ import { formatError } from '../../lib/formatting/error.js';
4
+ import { formatInvitations, output } from '../../lib/formatting/output.js';
5
+ export default class UserInvitations extends Command {
6
+ static args = {
7
+ identifier: Args.string({
8
+ description: 'Twitter username, ETH address, or ENS name',
9
+ required: true,
10
+ }),
11
+ };
12
+ static description = 'List invitations sent by a user';
13
+ static examples = [
14
+ '<%= config.bin %> <%= command.id %> sethgho',
15
+ '<%= config.bin %> <%= command.id %> 0xNowater --status ACCEPTED',
16
+ '<%= config.bin %> <%= command.id %> vitalik.eth --json',
17
+ ];
18
+ static flags = {
19
+ json: Flags.boolean({
20
+ char: 'j',
21
+ description: 'Output as JSON',
22
+ default: false,
23
+ }),
24
+ verbose: Flags.boolean({
25
+ char: 'v',
26
+ description: 'Show detailed error information',
27
+ default: false,
28
+ }),
29
+ status: Flags.string({
30
+ char: 's',
31
+ description: 'Filter by status',
32
+ options: ['INVITED', 'ACCEPTED'],
33
+ }),
34
+ limit: Flags.integer({
35
+ char: 'l',
36
+ description: 'Max results per request',
37
+ default: 10,
38
+ }),
39
+ offset: Flags.integer({
40
+ char: 'o',
41
+ description: 'Number of results to skip',
42
+ default: 0,
43
+ }),
44
+ };
45
+ async run() {
46
+ const { args, flags } = await this.parse(UserInvitations);
47
+ const client = new EchoClient();
48
+ try {
49
+ const user = await client.resolveUser(args.identifier);
50
+ if (!user.profileId) {
51
+ this.error('User does not have a profile ID', { exit: 1 });
52
+ }
53
+ const response = await client.getInvitations({
54
+ senderProfileId: user.profileId,
55
+ status: flags.status,
56
+ limit: flags.limit,
57
+ offset: flags.offset,
58
+ });
59
+ if (flags.json) {
60
+ this.log(output(response));
61
+ }
62
+ else {
63
+ this.log(formatInvitations(response.values, response.total));
64
+ }
65
+ }
66
+ catch (error) {
67
+ if (error instanceof Error) {
68
+ this.log(formatError(error, flags.verbose));
69
+ this.exit(1);
70
+ }
71
+ }
72
+ }
73
+ }
@@ -0,0 +1,15 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class UserSearch extends Command {
3
+ static aliases: string[];
4
+ static args: {
5
+ query: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
6
+ };
7
+ static description: string;
8
+ static examples: string[];
9
+ static flags: {
10
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
12
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ };
14
+ run(): Promise<void>;
15
+ }
@@ -0,0 +1,59 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { EchoClient } from '../../lib/api/echo-client.js';
3
+ import { formatError } from '../../lib/formatting/error.js';
4
+ import { formatSearchResults, output } from '../../lib/formatting/output.js';
5
+ export default class UserSearch extends Command {
6
+ static aliases = ['find'];
7
+ static args = {
8
+ query: Args.string({
9
+ description: 'Search query',
10
+ required: true,
11
+ }),
12
+ };
13
+ static description = 'Search for users by name, username, or address';
14
+ static examples = [
15
+ '<%= config.bin %> <%= command.id %> vitalik',
16
+ '<%= config.bin %> <%= command.id %> "crypto developer"',
17
+ '<%= config.bin %> <%= command.id %> vitalik --json',
18
+ '<%= config.bin %> <%= command.id %> web3 --limit 5',
19
+ ];
20
+ static flags = {
21
+ json: Flags.boolean({
22
+ char: 'j',
23
+ description: 'Output as JSON',
24
+ default: false,
25
+ }),
26
+ limit: Flags.integer({
27
+ char: 'l',
28
+ description: 'Maximum number of results',
29
+ default: 10,
30
+ }),
31
+ verbose: Flags.boolean({
32
+ char: 'v',
33
+ description: 'Show detailed error information',
34
+ default: false,
35
+ }),
36
+ };
37
+ async run() {
38
+ const { args, flags } = await this.parse(UserSearch);
39
+ if (flags.limit < 1 || flags.limit > 100) {
40
+ this.error('limit must be between 1 and 100', { exit: 2 });
41
+ }
42
+ const client = new EchoClient();
43
+ try {
44
+ const response = await client.searchUsers(args.query, flags.limit);
45
+ if (flags.json) {
46
+ this.log(output(response));
47
+ }
48
+ else {
49
+ this.log(formatSearchResults(response.values));
50
+ }
51
+ }
52
+ catch (error) {
53
+ if (error instanceof Error) {
54
+ this.log(formatError(error, flags.verbose));
55
+ this.exit(1);
56
+ }
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,14 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class UserSummary extends Command {
3
+ static aliases: string[];
4
+ static args: {
5
+ identifier: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
6
+ };
7
+ static description: string;
8
+ static examples: string[];
9
+ static flags: {
10
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ };
13
+ run(): Promise<void>;
14
+ }