@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
package/bin/dev.cmd ADDED
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ node --loader ts-node/esm --no-warnings=ExperimentalWarning "%~dp0\dev" %*
package/bin/dev.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env -S node --loader ts-node/esm --disable-warning=ExperimentalWarning
2
+
3
+ import {execute} from '@oclif/core'
4
+
5
+ await execute({development: true, dir: import.meta.url})
package/bin/run.cmd ADDED
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ node "%~dp0\run" %*
package/bin/run.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {execute} from '@oclif/core'
4
+
5
+ await execute({dir: import.meta.url})
@@ -0,0 +1,10 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class AuctionActive 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
+ };
9
+ run(): Promise<void>;
10
+ }
@@ -0,0 +1,39 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import pc from 'picocolors';
3
+ import { EchoClient } from '../../lib/api/echo-client.js';
4
+ import { formatAuction, output } from '../../lib/formatting/output.js';
5
+ import { formatError } from '../../lib/formatting/error.js';
6
+ export default class AuctionActive extends Command {
7
+ static description = 'Show the currently active auction';
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %>',
10
+ '<%= config.bin %> <%= command.id %> --json',
11
+ ];
12
+ static flags = {
13
+ json: Flags.boolean({ char: 'j', description: 'Output as JSON' }),
14
+ verbose: Flags.boolean({ char: 'v', description: 'Show detailed error information' }),
15
+ };
16
+ async run() {
17
+ const { flags } = await this.parse(AuctionActive);
18
+ const client = new EchoClient();
19
+ try {
20
+ const auction = await client.getActiveAuction();
21
+ if (!auction) {
22
+ this.log(pc.yellow('No active auction at the moment.'));
23
+ return;
24
+ }
25
+ if (flags.json) {
26
+ this.log(output(auction));
27
+ }
28
+ else {
29
+ this.log(formatAuction(auction));
30
+ }
31
+ }
32
+ catch (error) {
33
+ if (error instanceof Error) {
34
+ this.log(formatError(error, flags.verbose));
35
+ this.exit(1);
36
+ }
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,16 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class AuctionInfo extends Command {
3
+ static description: string;
4
+ static args: {
5
+ id: import("@oclif/core/interfaces").Arg<number, {
6
+ max?: number;
7
+ min?: number;
8
+ }>;
9
+ };
10
+ static examples: string[];
11
+ static flags: {
12
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
+ };
15
+ run(): Promise<void>;
16
+ }
@@ -0,0 +1,46 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { EchoClient } from '../../lib/api/echo-client.js';
3
+ import { formatAuction, output } from '../../lib/formatting/output.js';
4
+ import { formatError } from '../../lib/formatting/error.js';
5
+ export default class AuctionInfo extends Command {
6
+ static description = 'Get details of a specific auction';
7
+ static args = {
8
+ id: Args.integer({ description: 'Auction ID', required: true }),
9
+ };
10
+ static examples = [
11
+ '<%= config.bin %> <%= command.id %> 1',
12
+ '<%= config.bin %> <%= command.id %> 1 --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(AuctionInfo);
20
+ const client = new EchoClient();
21
+ try {
22
+ let auction = await client.getAuction(args.id);
23
+ if (auction.buyerAddress) {
24
+ try {
25
+ const buyer = await client.getUserByAddress(auction.buyerAddress);
26
+ auction = { ...auction, buyerUser: { displayName: buyer.displayName, username: buyer.username } };
27
+ }
28
+ catch {
29
+ auction = { ...auction, buyerUser: null };
30
+ }
31
+ }
32
+ if (flags.json) {
33
+ this.log(output(auction));
34
+ }
35
+ else {
36
+ this.log(formatAuction(auction));
37
+ }
38
+ }
39
+ catch (error) {
40
+ if (error instanceof Error) {
41
+ this.log(formatError(error, flags.verbose));
42
+ this.exit(1);
43
+ }
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,14 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class AuctionList 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
+ limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
10
+ offset: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
11
+ };
12
+ run(): Promise<void>;
13
+ private enrichWithBuyerInfo;
14
+ }
@@ -0,0 +1,61 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { EchoClient } from '../../lib/api/echo-client.js';
3
+ import { formatAuctions, output } from '../../lib/formatting/output.js';
4
+ import { formatError } from '../../lib/formatting/error.js';
5
+ export default class AuctionList extends Command {
6
+ static description = 'List validator NFT auctions';
7
+ static examples = [
8
+ '<%= config.bin %> <%= command.id %>',
9
+ '<%= config.bin %> <%= command.id %> --status active',
10
+ '<%= config.bin %> <%= command.id %> --json',
11
+ ];
12
+ static flags = {
13
+ json: Flags.boolean({ char: 'j', description: 'Output as JSON' }),
14
+ verbose: Flags.boolean({ char: 'v', description: 'Show detailed error information' }),
15
+ status: Flags.string({
16
+ description: 'Filter by status',
17
+ options: ['pending', 'active', 'ended', 'settled'],
18
+ }),
19
+ limit: Flags.integer({ char: 'l', description: 'Max results per request', default: 10 }),
20
+ offset: Flags.integer({ char: 'o', description: 'Number of results to skip', default: 0 }),
21
+ };
22
+ async run() {
23
+ const { flags } = await this.parse(AuctionList);
24
+ const client = new EchoClient();
25
+ try {
26
+ const response = await client.getAuctions({ limit: flags.limit, offset: flags.offset, status: flags.status });
27
+ const enrichedAuctions = await this.enrichWithBuyerInfo(client, response.values);
28
+ if (flags.json) {
29
+ this.log(output({ ...response, values: enrichedAuctions }));
30
+ }
31
+ else {
32
+ this.log(formatAuctions(enrichedAuctions, response.total));
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
+ async enrichWithBuyerInfo(client, auctions) {
43
+ const buyerAddresses = [...new Set(auctions.filter(a => a.buyerAddress).map(a => a.buyerAddress))];
44
+ if (buyerAddresses.length === 0)
45
+ return auctions;
46
+ const buyerMap = new Map();
47
+ await Promise.all(buyerAddresses.map(async (address) => {
48
+ try {
49
+ const user = await client.getUserByAddress(address);
50
+ buyerMap.set(address, { displayName: user.displayName, username: user.username });
51
+ }
52
+ catch {
53
+ buyerMap.set(address, {});
54
+ }
55
+ }));
56
+ return auctions.map(auction => ({
57
+ ...auction,
58
+ buyerUser: auction.buyerAddress ? buyerMap.get(auction.buyerAddress) : null,
59
+ }));
60
+ }
61
+ }
@@ -0,0 +1,16 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class BrokerInfo extends Command {
3
+ static description: string;
4
+ static args: {
5
+ id: import("@oclif/core/interfaces").Arg<number, {
6
+ max?: number;
7
+ min?: number;
8
+ }>;
9
+ };
10
+ static examples: string[];
11
+ static flags: {
12
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
+ };
15
+ run(): Promise<void>;
16
+ }
@@ -0,0 +1,37 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { EchoClient } from '../../lib/api/echo-client.js';
3
+ import { formatBrokerPost, output } from '../../lib/formatting/output.js';
4
+ import { formatError } from '../../lib/formatting/error.js';
5
+ export default class BrokerInfo extends Command {
6
+ static description = 'Get details of a specific broker post';
7
+ static args = {
8
+ id: Args.integer({ description: 'Broker post 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(BrokerInfo);
20
+ const client = new EchoClient();
21
+ try {
22
+ const post = await client.getBrokerPost(args.id);
23
+ if (flags.json) {
24
+ this.log(output(post));
25
+ }
26
+ else {
27
+ this.log(formatBrokerPost(post));
28
+ }
29
+ }
30
+ catch (error) {
31
+ if (error instanceof Error) {
32
+ this.log(formatError(error, flags.verbose));
33
+ this.exit(1);
34
+ }
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,15 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class BrokerList 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
+ type: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ search: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ sort: import("@oclif/core/interfaces").OptionFlag<string, 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,62 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { EchoClient } from '../../lib/api/echo-client.js';
3
+ import { formatBrokerPosts, output } from '../../lib/formatting/output.js';
4
+ import { formatError } from '../../lib/formatting/error.js';
5
+ const TYPE_MAP = {
6
+ 'sell': 'SELL',
7
+ 'buy': 'BUY',
8
+ 'hire': 'HIRE',
9
+ 'for-hire': 'FOR_HIRE',
10
+ 'bounty': 'BOUNTY',
11
+ };
12
+ export default class BrokerList extends Command {
13
+ static description = 'List broker posts (jobs, services, bounties)';
14
+ static examples = [
15
+ '<%= config.bin %> <%= command.id %>',
16
+ '<%= config.bin %> <%= command.id %> --type hire',
17
+ '<%= config.bin %> <%= command.id %> --search "solidity developer"',
18
+ '<%= config.bin %> <%= command.id %> --type sell --limit 5 --json',
19
+ ];
20
+ static flags = {
21
+ json: Flags.boolean({ char: 'j', description: 'Output as JSON' }),
22
+ verbose: Flags.boolean({ char: 'v', description: 'Show detailed error information' }),
23
+ type: Flags.string({
24
+ char: 't',
25
+ description: 'Filter by post type',
26
+ options: ['sell', 'buy', 'hire', 'for-hire', 'bounty'],
27
+ }),
28
+ search: Flags.string({ char: 's', description: 'Search in title/description' }),
29
+ sort: Flags.string({
30
+ description: 'Sort order',
31
+ options: ['newest', 'top', 'hot'],
32
+ default: 'hot',
33
+ }),
34
+ limit: Flags.integer({ char: 'l', description: 'Max results per request', default: 10 }),
35
+ offset: Flags.integer({ char: 'o', description: 'Number of results to skip', default: 0 }),
36
+ };
37
+ async run() {
38
+ const { flags } = await this.parse(BrokerList);
39
+ const client = new EchoClient();
40
+ try {
41
+ const response = await client.getBrokerPosts({
42
+ type: flags.type ? TYPE_MAP[flags.type] : undefined,
43
+ search: flags.search,
44
+ sortBy: flags.sort,
45
+ limit: flags.limit,
46
+ offset: flags.offset,
47
+ });
48
+ if (flags.json) {
49
+ this.log(output(response));
50
+ }
51
+ else {
52
+ this.log(formatBrokerPosts(response.values, response.total));
53
+ }
54
+ }
55
+ catch (error) {
56
+ if (error instanceof Error) {
57
+ this.log(formatError(error, flags.verbose));
58
+ this.exit(1);
59
+ }
60
+ }
61
+ }
62
+ }
@@ -0,0 +1,9 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ConfigGet extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
@@ -0,0 +1,29 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import pc from 'picocolors';
3
+ import { loadConfig, getConfigPath } from '../../lib/config/index.js';
4
+ export default class ConfigGet extends Command {
5
+ static description = 'Show current configuration';
6
+ static examples = [
7
+ '<%= config.bin %> <%= command.id %>',
8
+ '<%= config.bin %> <%= command.id %> --json',
9
+ ];
10
+ static flags = {
11
+ json: Flags.boolean({
12
+ char: 'j',
13
+ description: 'Output as JSON',
14
+ default: false,
15
+ }),
16
+ };
17
+ async run() {
18
+ const { flags } = await this.parse(ConfigGet);
19
+ const config = loadConfig();
20
+ const configPath = getConfigPath();
21
+ if (flags.json) {
22
+ this.log(JSON.stringify({ ...config, configPath }, null, 2));
23
+ }
24
+ else {
25
+ this.log(`${pc.dim('apiUrl:')} ${config.apiUrl}`);
26
+ this.log(`${pc.dim('config:')} ${configPath}`);
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,6 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ConfigPath extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ import { getConfigPath } from '../../lib/config/index.js';
3
+ export default class ConfigPath extends Command {
4
+ static description = 'Show config file path';
5
+ static examples = [
6
+ '<%= config.bin %> <%= command.id %>',
7
+ ];
8
+ async run() {
9
+ await this.parse(ConfigPath);
10
+ this.log(getConfigPath());
11
+ }
12
+ }
@@ -0,0 +1,9 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ConfigSet extends Command {
3
+ static description: string;
4
+ static args: {
5
+ value: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
6
+ };
7
+ static examples: string[];
8
+ run(): Promise<void>;
9
+ }
@@ -0,0 +1,28 @@
1
+ import { Args, Command } from '@oclif/core';
2
+ import pc from 'picocolors';
3
+ import { saveConfig } from '../../lib/config/index.js';
4
+ export default class ConfigSet extends Command {
5
+ static description = 'Set configuration value';
6
+ static args = {
7
+ value: Args.string({
8
+ description: 'Configuration in format: apiUrl=<url>',
9
+ required: true,
10
+ }),
11
+ };
12
+ static examples = [
13
+ '<%= config.bin %> <%= command.id %> apiUrl=https://api.ethos.network',
14
+ '<%= config.bin %> <%= command.id %> apiUrl=https://api.dev.ethos.network',
15
+ ];
16
+ async run() {
17
+ const { args } = await this.parse(ConfigSet);
18
+ if (!args.value.startsWith('apiUrl=')) {
19
+ this.error('Invalid format. Use: ethos config set apiUrl=<url>', { exit: 2 });
20
+ }
21
+ const apiUrl = args.value.slice('apiUrl='.length);
22
+ if (!apiUrl.startsWith('http://') && !apiUrl.startsWith('https://')) {
23
+ this.error(`Invalid URL: ${apiUrl}`, { exit: 2 });
24
+ }
25
+ saveConfig({ apiUrl });
26
+ this.log(`${pc.green('Updated:')} apiUrl=${apiUrl}`);
27
+ }
28
+ }
@@ -0,0 +1,13 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ListingInfo extends Command {
3
+ static description: string;
4
+ static args: {
5
+ identifier: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
6
+ };
7
+ static examples: string[];
8
+ static flags: {
9
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,41 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { EchoClient } from '../../lib/api/echo-client.js';
3
+ import { formatListing, output } from '../../lib/formatting/output.js';
4
+ import { formatError } from '../../lib/formatting/error.js';
5
+ export default class ListingInfo extends Command {
6
+ static description = 'Get details of a specific listing/project';
7
+ static args = {
8
+ identifier: Args.string({ description: 'Project ID or username', required: true }),
9
+ };
10
+ static examples = [
11
+ '<%= config.bin %> <%= command.id %> 123',
12
+ '<%= config.bin %> <%= command.id %> uniswap',
13
+ '<%= config.bin %> <%= command.id %> uniswap --json',
14
+ ];
15
+ static flags = {
16
+ json: Flags.boolean({ char: 'j', description: 'Output as JSON' }),
17
+ verbose: Flags.boolean({ char: 'v', description: 'Show detailed error information' }),
18
+ };
19
+ async run() {
20
+ const { args, flags } = await this.parse(ListingInfo);
21
+ const client = new EchoClient();
22
+ try {
23
+ const isNumeric = /^\d+$/.test(args.identifier);
24
+ const project = isNumeric
25
+ ? await client.getProjectDetails(parseInt(args.identifier))
26
+ : await client.getProjectByUsername(args.identifier);
27
+ if (flags.json) {
28
+ this.log(output(project));
29
+ }
30
+ else {
31
+ this.log(formatListing(project));
32
+ }
33
+ }
34
+ catch (error) {
35
+ if (error instanceof Error) {
36
+ this.log(formatError(error, flags.verbose));
37
+ this.exit(1);
38
+ }
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,13 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ListingList 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, import("@oclif/core/interfaces").CustomOptions>;
9
+ limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
10
+ offset: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,46 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { EchoClient } from '../../lib/api/echo-client.js';
3
+ import { formatListings, output } from '../../lib/formatting/output.js';
4
+ import { formatError } from '../../lib/formatting/error.js';
5
+ export default class ListingList extends Command {
6
+ static description = 'List projects on Ethos Listings';
7
+ static examples = [
8
+ '<%= config.bin %> <%= command.id %>',
9
+ '<%= config.bin %> <%= command.id %> --status active',
10
+ '<%= config.bin %> <%= command.id %> --limit 20 --json',
11
+ ];
12
+ static flags = {
13
+ json: Flags.boolean({ char: 'j', description: 'Output as JSON' }),
14
+ verbose: Flags.boolean({ char: 'v', description: 'Show detailed error information' }),
15
+ status: Flags.string({
16
+ description: 'Filter by status',
17
+ options: ['active', 'pending', 'archived'],
18
+ default: 'active',
19
+ }),
20
+ limit: Flags.integer({ char: 'l', description: 'Max results per request', default: 10 }),
21
+ offset: Flags.integer({ char: 'o', description: 'Number of results to skip', default: 0 }),
22
+ };
23
+ async run() {
24
+ const { flags } = await this.parse(ListingList);
25
+ const client = new EchoClient();
26
+ try {
27
+ const response = await client.getProjects({
28
+ status: [flags.status.toUpperCase()],
29
+ limit: flags.limit,
30
+ offset: flags.offset,
31
+ });
32
+ if (flags.json) {
33
+ this.log(output(response));
34
+ }
35
+ else {
36
+ this.log(formatListings(response.projects, response.total));
37
+ }
38
+ }
39
+ catch (error) {
40
+ if (error instanceof Error) {
41
+ this.log(formatError(error, flags.verbose));
42
+ this.exit(1);
43
+ }
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,19 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ListingVoters extends Command {
3
+ static description: string;
4
+ static args: {
5
+ projectId: import("@oclif/core/interfaces").Arg<number, {
6
+ max?: number;
7
+ min?: number;
8
+ }>;
9
+ };
10
+ static examples: string[];
11
+ static flags: {
12
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
+ sentiment: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
+ limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
16
+ offset: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
17
+ };
18
+ run(): Promise<void>;
19
+ }
@@ -0,0 +1,48 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { EchoClient } from '../../lib/api/echo-client.js';
3
+ import { formatListingVoters, output } from '../../lib/formatting/output.js';
4
+ import { formatError } from '../../lib/formatting/error.js';
5
+ export default class ListingVoters extends Command {
6
+ static description = 'Show voters for a listing/project';
7
+ static args = {
8
+ projectId: Args.integer({ description: 'Project ID', required: true }),
9
+ };
10
+ static examples = [
11
+ '<%= config.bin %> <%= command.id %> 123',
12
+ '<%= config.bin %> <%= command.id %> 123 --sentiment bullish',
13
+ '<%= config.bin %> <%= command.id %> 123 --limit 20 --json',
14
+ ];
15
+ static flags = {
16
+ json: Flags.boolean({ char: 'j', description: 'Output as JSON' }),
17
+ verbose: Flags.boolean({ char: 'v', description: 'Show detailed error information' }),
18
+ sentiment: Flags.string({
19
+ description: 'Filter by sentiment',
20
+ options: ['bullish', 'bearish'],
21
+ }),
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 { args, flags } = await this.parse(ListingVoters);
27
+ const client = new EchoClient();
28
+ try {
29
+ const response = await client.getProjectVoters(args.projectId, {
30
+ limit: flags.limit,
31
+ offset: flags.offset,
32
+ sentiment: flags.sentiment,
33
+ });
34
+ if (flags.json) {
35
+ this.log(output(response));
36
+ }
37
+ else {
38
+ this.log(formatListingVoters(response.values, response.totals));
39
+ }
40
+ }
41
+ catch (error) {
42
+ if (error instanceof Error) {
43
+ this.log(formatError(error, flags.verbose));
44
+ this.exit(1);
45
+ }
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,10 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class MarketFeatured 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
+ };
9
+ run(): Promise<void>;
10
+ }