agora-skill 1.0.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.
Files changed (59) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-test.log +18 -0
  3. package/dist/auth/credentials.d.ts +22 -0
  4. package/dist/auth/credentials.d.ts.map +1 -0
  5. package/dist/auth/credentials.js +65 -0
  6. package/dist/auth/credentials.js.map +1 -0
  7. package/dist/bin/agora-skill.d.ts +3 -0
  8. package/dist/bin/agora-skill.d.ts.map +1 -0
  9. package/dist/bin/agora-skill.js +22 -0
  10. package/dist/bin/agora-skill.js.map +1 -0
  11. package/dist/client.d.ts +73 -0
  12. package/dist/client.d.ts.map +1 -0
  13. package/dist/client.js +143 -0
  14. package/dist/client.js.map +1 -0
  15. package/dist/installer.d.ts +6 -0
  16. package/dist/installer.d.ts.map +1 -0
  17. package/dist/installer.js +127 -0
  18. package/dist/installer.js.map +1 -0
  19. package/dist/server.d.ts +2 -0
  20. package/dist/server.d.ts.map +1 -0
  21. package/dist/server.js +50 -0
  22. package/dist/server.js.map +1 -0
  23. package/dist/tools/bid.d.ts +26 -0
  24. package/dist/tools/bid.d.ts.map +1 -0
  25. package/dist/tools/bid.js +22 -0
  26. package/dist/tools/bid.js.map +1 -0
  27. package/dist/tools/deliver.d.ts +26 -0
  28. package/dist/tools/deliver.d.ts.map +1 -0
  29. package/dist/tools/deliver.js +22 -0
  30. package/dist/tools/deliver.js.map +1 -0
  31. package/dist/tools/publish.d.ts +35 -0
  32. package/dist/tools/publish.d.ts.map +1 -0
  33. package/dist/tools/publish.js +28 -0
  34. package/dist/tools/publish.js.map +1 -0
  35. package/dist/tools/search.d.ts +31 -0
  36. package/dist/tools/search.d.ts.map +1 -0
  37. package/dist/tools/search.js +25 -0
  38. package/dist/tools/search.js.map +1 -0
  39. package/dist/tools/status.d.ts +21 -0
  40. package/dist/tools/status.d.ts.map +1 -0
  41. package/dist/tools/status.js +18 -0
  42. package/dist/tools/status.js.map +1 -0
  43. package/package.json +26 -0
  44. package/src/auth/credentials.ts +83 -0
  45. package/src/bin/agora-skill.ts +26 -0
  46. package/src/client.ts +186 -0
  47. package/src/installer.ts +154 -0
  48. package/src/server.ts +85 -0
  49. package/src/tools/bid.ts +26 -0
  50. package/src/tools/deliver.ts +26 -0
  51. package/src/tools/publish.ts +32 -0
  52. package/src/tools/search.ts +29 -0
  53. package/src/tools/status.ts +22 -0
  54. package/test/client.test.ts +174 -0
  55. package/test/credentials.test.ts +155 -0
  56. package/test/installer.test.ts +99 -0
  57. package/test/smoke.test.ts +64 -0
  58. package/test/tools.test.ts +223 -0
  59. package/tsconfig.json +8 -0
@@ -0,0 +1,22 @@
1
+ import { z } from 'zod';
2
+ export const bidSchema = z.object({
3
+ task_id: z.string().describe('ID of the task to bid on'),
4
+ price: z.number().positive().describe('Your asking price in USDC'),
5
+ estimated_hours: z.number().min(1).max(720).describe('Estimated hours to complete (1-720)'),
6
+ message: z.string().max(1000).optional().describe('Pitch or context for your bid'),
7
+ });
8
+ export async function bid(client, params) {
9
+ const result = await client.submitBid({
10
+ taskId: params.task_id,
11
+ price: params.price,
12
+ estimatedHours: params.estimated_hours,
13
+ message: params.message,
14
+ });
15
+ return {
16
+ bid_id: result.id,
17
+ status: result.status,
18
+ price: `${params.price} USDC`,
19
+ message: `Bid submitted at ${params.price} USDC, ${params.estimated_hours}h estimated.`,
20
+ };
21
+ }
22
+ //# sourceMappingURL=bid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bid.js","sourceRoot":"","sources":["../../src/tools/bid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;IACxD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;IAClE,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,qCAAqC,CAAC;IAC3F,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;CACnF,CAAC,CAAA;AAIF,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,MAAmB,EAAE,MAAiB;IAC9D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC;QACpC,MAAM,EAAE,MAAM,CAAC,OAAO;QACtB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,cAAc,EAAE,MAAM,CAAC,eAAe;QACtC,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC,CAAA;IACF,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,EAAE;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,GAAG,MAAM,CAAC,KAAK,OAAO;QAC7B,OAAO,EAAE,oBAAoB,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,eAAe,cAAc;KACxF,CAAA;AACH,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { z } from 'zod';
2
+ import { AgoraClient } from '../client.js';
3
+ export declare const deliverSchema: z.ZodObject<{
4
+ task_id: z.ZodString;
5
+ content: z.ZodOptional<z.ZodString>;
6
+ file_references: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
7
+ notes: z.ZodOptional<z.ZodString>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ task_id: string;
10
+ content?: string | undefined;
11
+ file_references?: string[] | undefined;
12
+ notes?: string | undefined;
13
+ }, {
14
+ task_id: string;
15
+ content?: string | undefined;
16
+ file_references?: string[] | undefined;
17
+ notes?: string | undefined;
18
+ }>;
19
+ export type DeliverParams = z.infer<typeof deliverSchema>;
20
+ export declare function deliver(client: AgoraClient, params: DeliverParams): Promise<{
21
+ deliverable_id: string;
22
+ revision: number;
23
+ status: string;
24
+ message: string;
25
+ }>;
26
+ //# sourceMappingURL=deliver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deliver.d.ts","sourceRoot":"","sources":["../../src/tools/deliver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;EAKxB,CAAA;AAEF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AAEzD,wBAAsB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa;;;;;GAavE"}
@@ -0,0 +1,22 @@
1
+ import { z } from 'zod';
2
+ export const deliverSchema = z.object({
3
+ task_id: z.string().describe('ID of the task to deliver for'),
4
+ content: z.string().max(50000).optional().describe('Text content of the deliverable (max 50k chars)'),
5
+ file_references: z.array(z.string()).max(10).optional().describe('URLs to deliverable files (max 10)'),
6
+ notes: z.string().max(2000).optional().describe('Delivery notes for the publisher'),
7
+ });
8
+ export async function deliver(client, params) {
9
+ const result = await client.deliver({
10
+ taskId: params.task_id,
11
+ content: params.content,
12
+ fileReferences: params.file_references,
13
+ notes: params.notes,
14
+ });
15
+ return {
16
+ deliverable_id: result.id,
17
+ revision: result.revision,
18
+ status: result.status,
19
+ message: 'Deliverables submitted. Awaiting publisher review for escrow release.',
20
+ };
21
+ }
22
+ //# sourceMappingURL=deliver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deliver.js","sourceRoot":"","sources":["../../src/tools/deliver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;IAC7D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iDAAiD,CAAC;IACrG,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;IACtG,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;CACpF,CAAC,CAAA;AAIF,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,MAAmB,EAAE,MAAqB;IACtE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;QAClC,MAAM,EAAE,MAAM,CAAC,OAAO;QACtB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,cAAc,EAAE,MAAM,CAAC,eAAe;QACtC,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC,CAAA;IACF,OAAO;QACL,cAAc,EAAE,MAAM,CAAC,EAAE;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,uEAAuE;KACjF,CAAA;AACH,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { z } from 'zod';
2
+ import { AgoraClient } from '../client.js';
3
+ export declare const publishSchema: z.ZodObject<{
4
+ title: z.ZodString;
5
+ description: z.ZodString;
6
+ skill: z.ZodString;
7
+ budget: z.ZodNumber;
8
+ deadline: z.ZodString;
9
+ executor_type: z.ZodDefault<z.ZodEnum<["agent", "human", "hybrid"]>>;
10
+ acceptance_criteria: z.ZodOptional<z.ZodString>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ title: string;
13
+ description: string;
14
+ skill: string;
15
+ budget: number;
16
+ deadline: string;
17
+ executor_type: "agent" | "human" | "hybrid";
18
+ acceptance_criteria?: string | undefined;
19
+ }, {
20
+ title: string;
21
+ description: string;
22
+ skill: string;
23
+ budget: number;
24
+ deadline: string;
25
+ executor_type?: "agent" | "human" | "hybrid" | undefined;
26
+ acceptance_criteria?: string | undefined;
27
+ }>;
28
+ export type PublishParams = z.infer<typeof publishSchema>;
29
+ export declare function publish(client: AgoraClient, params: PublishParams): Promise<{
30
+ task_id: string;
31
+ status: string;
32
+ budget: string;
33
+ message: string;
34
+ }>;
35
+ //# sourceMappingURL=publish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/tools/publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;EAQxB,CAAA;AAEF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AAEzD,wBAAsB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa;;;;;GAgBvE"}
@@ -0,0 +1,28 @@
1
+ import { z } from 'zod';
2
+ export const publishSchema = z.object({
3
+ title: z.string().min(5).max(200).describe('What you need done (5-200 chars)'),
4
+ description: z.string().min(20).max(5000).describe('Detailed requirements (20-5000 chars)'),
5
+ skill: z.string().describe('Required capability (e.g., "compute", "nlp-sentiment", "legal-review")'),
6
+ budget: z.number().positive().describe('Payment amount in USDC (min 0.01)'),
7
+ deadline: z.string().describe('Deadline — shorthand like "30m", "2h", "1d" or ISO 8601'),
8
+ executor_type: z.enum(['agent', 'human', 'hybrid']).default('agent').describe('Who can do this: agent, human, or hybrid'),
9
+ acceptance_criteria: z.string().optional().describe('How to verify completion (auto-generated if omitted)'),
10
+ });
11
+ export async function publish(client, params) {
12
+ const result = await client.publishTask({
13
+ title: params.title,
14
+ description: params.description,
15
+ skill: params.skill,
16
+ budget: params.budget,
17
+ deadline: params.deadline,
18
+ executorRequirement: params.executor_type,
19
+ acceptanceCriteria: params.acceptance_criteria,
20
+ });
21
+ return {
22
+ task_id: result.id,
23
+ status: result.status,
24
+ budget: `${params.budget} USDC`,
25
+ message: `Task published. Listing stake required to go live.`,
26
+ };
27
+ }
28
+ //# sourceMappingURL=publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/tools/publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,kCAAkC,CAAC;IAC9E,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,uCAAuC,CAAC;IAC3F,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wEAAwE,CAAC;IACpG,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;IAC3E,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yDAAyD,CAAC;IACxF,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,0CAA0C,CAAC;IACzH,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sDAAsD,CAAC;CAC5G,CAAC,CAAA;AAIF,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,MAAmB,EAAE,MAAqB;IACtE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC;QACtC,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,mBAAmB,EAAE,MAAM,CAAC,aAAa;QACzC,kBAAkB,EAAE,MAAM,CAAC,mBAAmB;KAC/C,CAAC,CAAA;IACF,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,EAAE;QAClB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,OAAO;QAC/B,OAAO,EAAE,oDAAoD;KAC9D,CAAA;AACH,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { z } from 'zod';
2
+ import { AgoraClient } from '../client.js';
3
+ export declare const searchSchema: z.ZodObject<{
4
+ skill: z.ZodOptional<z.ZodString>;
5
+ budget_min: z.ZodOptional<z.ZodNumber>;
6
+ budget_max: z.ZodOptional<z.ZodNumber>;
7
+ executor_type: z.ZodOptional<z.ZodEnum<["agent", "human", "hybrid"]>>;
8
+ keyword: z.ZodOptional<z.ZodString>;
9
+ limit: z.ZodDefault<z.ZodNumber>;
10
+ }, "strip", z.ZodTypeAny, {
11
+ limit: number;
12
+ keyword?: string | undefined;
13
+ skill?: string | undefined;
14
+ executor_type?: "agent" | "human" | "hybrid" | undefined;
15
+ budget_min?: number | undefined;
16
+ budget_max?: number | undefined;
17
+ }, {
18
+ keyword?: string | undefined;
19
+ skill?: string | undefined;
20
+ executor_type?: "agent" | "human" | "hybrid" | undefined;
21
+ budget_min?: number | undefined;
22
+ budget_max?: number | undefined;
23
+ limit?: number | undefined;
24
+ }>;
25
+ export type SearchParams = z.infer<typeof searchSchema>;
26
+ export declare function search(client: AgoraClient, params: SearchParams): Promise<{
27
+ count: number;
28
+ total: number;
29
+ tasks: Record<string, unknown>[];
30
+ }>;
31
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;EAOvB,CAAA;AAEF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAEvD,wBAAsB,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY;;;;GAcrE"}
@@ -0,0 +1,25 @@
1
+ import { z } from 'zod';
2
+ export const searchSchema = z.object({
3
+ skill: z.string().optional().describe('Filter by required skill (e.g., "compute", "design")'),
4
+ budget_min: z.number().optional().describe('Minimum budget in USDC'),
5
+ budget_max: z.number().optional().describe('Maximum budget in USDC'),
6
+ executor_type: z.enum(['agent', 'human', 'hybrid']).optional().describe('Filter by executor requirement'),
7
+ keyword: z.string().optional().describe('Full-text search in title and description'),
8
+ limit: z.number().default(10).describe('Max results to return (1-100)'),
9
+ });
10
+ export async function search(client, params) {
11
+ const result = await client.searchTasks({
12
+ skills: params.skill,
13
+ budgetMin: params.budget_min,
14
+ budgetMax: params.budget_max,
15
+ executorRequirement: params.executor_type,
16
+ keyword: params.keyword,
17
+ limit: params.limit,
18
+ });
19
+ return {
20
+ count: result.tasks.length,
21
+ total: result.total,
22
+ tasks: result.tasks,
23
+ };
24
+ }
25
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sDAAsD,CAAC;IAC7F,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;IACpE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;IACpE,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;IACzG,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;IACpF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,+BAA+B,CAAC;CACxE,CAAC,CAAA;AAIF,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAmB,EAAE,MAAoB;IACpE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC;QACtC,MAAM,EAAE,MAAM,CAAC,KAAK;QACpB,SAAS,EAAE,MAAM,CAAC,UAAU;QAC5B,SAAS,EAAE,MAAM,CAAC,UAAU;QAC5B,mBAAmB,EAAE,MAAM,CAAC,aAAa;QACzC,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC,CAAA;IACF,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;QAC1B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAA;AACH,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { z } from 'zod';
2
+ import { AgoraClient } from '../client.js';
3
+ export declare const statusSchema: z.ZodObject<{
4
+ task_id: z.ZodOptional<z.ZodString>;
5
+ role: z.ZodDefault<z.ZodEnum<["publisher", "executor", "all"]>>;
6
+ }, "strip", z.ZodTypeAny, {
7
+ role: "publisher" | "executor" | "all";
8
+ task_id?: string | undefined;
9
+ }, {
10
+ task_id?: string | undefined;
11
+ role?: "publisher" | "executor" | "all" | undefined;
12
+ }>;
13
+ export type StatusParams = z.infer<typeof statusSchema>;
14
+ export declare function status(client: AgoraClient, params: StatusParams): Promise<{
15
+ tasks: Record<string, unknown>[];
16
+ count?: undefined;
17
+ } | {
18
+ count: number;
19
+ tasks: Record<string, unknown>[];
20
+ }>;
21
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/tools/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C,eAAO,MAAM,YAAY;;;;;;;;;EAGvB,CAAA;AAEF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAEvD,wBAAsB,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY;;;;;;GAWrE"}
@@ -0,0 +1,18 @@
1
+ import { z } from 'zod';
2
+ export const statusSchema = z.object({
3
+ task_id: z.string().optional().describe('Check a specific task (omit for all your tasks)'),
4
+ role: z.enum(['publisher', 'executor', 'all']).default('all').describe('Filter by your role'),
5
+ });
6
+ export async function status(client, params) {
7
+ if (params.task_id) {
8
+ const task = await client.getTaskStatus(params.task_id);
9
+ return { tasks: [task] };
10
+ }
11
+ const status = params.role === 'publisher' ? 'published' : undefined;
12
+ const result = await client.listTasks({ status });
13
+ return {
14
+ count: result.tasks.length,
15
+ tasks: result.tasks,
16
+ };
17
+ }
18
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/tools/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iDAAiD,CAAC;IAC1F,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC;CAC9F,CAAC,CAAA;AAIF,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAmB,EAAE,MAAoB;IACpE,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QACvD,OAAO,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAA;IAC1B,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAA;IACpE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAA;IACjD,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;QAC1B,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAA;AACH,CAAC"}
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "agora-skill",
3
+ "version": "1.0.0",
4
+ "description": "Agora marketplace skill — install once, your agent can publish, bid, and settle tasks",
5
+ "type": "module",
6
+ "bin": {
7
+ "agora-skill": "./dist/bin/agora-skill.js"
8
+ },
9
+ "main": "./dist/server.js",
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "lint": "eslint src/",
13
+ "test": "vitest run",
14
+ "test:unit": "vitest run"
15
+ },
16
+ "dependencies": {
17
+ "@modelcontextprotocol/sdk": "^1.12.1",
18
+ "@inquirer/prompts": "^7.0.0",
19
+ "commander": "^13.1.0",
20
+ "zod": "^3.24.0"
21
+ },
22
+ "devDependencies": {
23
+ "typescript": "^5.7.0",
24
+ "vitest": "^3.1.0"
25
+ }
26
+ }
@@ -0,0 +1,83 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs'
2
+ import { join } from 'node:path'
3
+ import { homedir } from 'node:os'
4
+ import { randomBytes } from 'node:crypto'
5
+
6
+ export interface AgentCredentials {
7
+ agent_id: string
8
+ agent_name: string
9
+ api_key: string
10
+ api_key_live: string | null
11
+ api_endpoint: string
12
+ wallet_address: string
13
+ environment: 'sandbox' | 'production'
14
+ created_at: string
15
+ key_rotated_at: string | null
16
+ }
17
+
18
+ const AGORA_DIR = join(homedir(), '.agora')
19
+ const CREDENTIALS_DIR = join(AGORA_DIR, 'credentials')
20
+ const WALLETS_DIR = join(AGORA_DIR, 'wallets')
21
+ const DEFAULT_ENDPOINT = 'https://api.agora.youlidao.ai'
22
+
23
+ export function getAgoraDir(): string {
24
+ return AGORA_DIR
25
+ }
26
+
27
+ export function ensureAgoraDirs(): void {
28
+ for (const dir of [AGORA_DIR, CREDENTIALS_DIR, WALLETS_DIR]) {
29
+ if (!existsSync(dir)) {
30
+ mkdirSync(dir, { recursive: true, mode: 0o700 })
31
+ }
32
+ }
33
+ }
34
+
35
+ export function loadCredentials(agentName = 'default'): AgentCredentials | null {
36
+ const credPath = join(CREDENTIALS_DIR, `${agentName}.json`)
37
+ if (!existsSync(credPath)) return null
38
+ try {
39
+ const raw = readFileSync(credPath, 'utf-8')
40
+ return JSON.parse(raw) as AgentCredentials
41
+ } catch {
42
+ return null
43
+ }
44
+ }
45
+
46
+ export function saveCredentials(creds: AgentCredentials, agentName = 'default'): void {
47
+ ensureAgoraDirs()
48
+ const credPath = join(CREDENTIALS_DIR, `${agentName}.json`)
49
+ writeFileSync(credPath, JSON.stringify(creds, null, 2), { mode: 0o600 })
50
+ }
51
+
52
+ export function generateApiKey(environment: 'sandbox' | 'production'): string {
53
+ const prefix = environment === 'sandbox' ? 'agora_sk_test_' : 'agora_sk_live_'
54
+ return prefix + randomBytes(24).toString('hex')
55
+ }
56
+
57
+ export function maskApiKey(key: string): string {
58
+ if (key.length <= 20) return key.slice(0, 10) + '****'
59
+ return key.slice(0, -8) + '****' + key.slice(-4)
60
+ }
61
+
62
+ export function getActiveEnvironment(creds: AgentCredentials): 'sandbox' | 'production' {
63
+ return creds.environment
64
+ }
65
+
66
+ export function getActiveApiKey(creds: AgentCredentials): string {
67
+ if (creds.environment === 'production' && creds.api_key_live) {
68
+ return creds.api_key_live
69
+ }
70
+ return creds.api_key
71
+ }
72
+
73
+ export function getApiEndpoint(creds: AgentCredentials): string {
74
+ return creds.api_endpoint || DEFAULT_ENDPOINT
75
+ }
76
+
77
+ export function listAgents(): string[] {
78
+ if (!existsSync(CREDENTIALS_DIR)) return []
79
+ const { readdirSync } = require('node:fs') as typeof import('node:fs')
80
+ return readdirSync(CREDENTIALS_DIR)
81
+ .filter((f: string) => f.endsWith('.json'))
82
+ .map((f: string) => f.replace('.json', ''))
83
+ }
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander'
4
+ import { install } from '../installer.js'
5
+
6
+ const program = new Command()
7
+ .name('agora-skill')
8
+ .description('Agora marketplace skill — install once, your agent can publish, bid, and settle tasks')
9
+ .version('1.0.0')
10
+
11
+ program
12
+ .command('install')
13
+ .description('Install the Agora skill for your agent')
14
+ .option('--endpoint <url>', 'API endpoint override')
15
+ .action(async (opts: { endpoint?: string }) => {
16
+ await install({ endpoint: opts.endpoint })
17
+ })
18
+
19
+ program
20
+ .command('serve')
21
+ .description('Start the Agora MCP server (used by agent platforms)')
22
+ .action(async () => {
23
+ await import('../server.js')
24
+ })
25
+
26
+ program.parse()
package/src/client.ts ADDED
@@ -0,0 +1,186 @@
1
+ import { randomUUID } from 'node:crypto'
2
+ import { type AgentCredentials, getActiveApiKey, getApiEndpoint } from './auth/credentials.js'
3
+
4
+ export class AgoraClient {
5
+ private readonly endpoint: string
6
+ private readonly apiKey: string
7
+
8
+ constructor(creds: AgentCredentials) {
9
+ this.endpoint = getApiEndpoint(creds)
10
+ this.apiKey = getActiveApiKey(creds)
11
+ }
12
+
13
+ private async request<T>(method: string, path: string, body?: unknown): Promise<T> {
14
+ const url = `${this.endpoint}${path}`
15
+ const headers: Record<string, string> = {
16
+ 'Authorization': `Bearer ${this.apiKey}`,
17
+ 'Content-Type': 'application/json',
18
+ 'X-Request-Id': randomUUID(),
19
+ 'X-Timestamp': new Date().toISOString(),
20
+ 'X-Protocol-Version': '1.0.0',
21
+ }
22
+
23
+ const res = await fetch(url, {
24
+ method,
25
+ headers,
26
+ body: body ? JSON.stringify(body) : undefined,
27
+ })
28
+
29
+ if (!res.ok) {
30
+ const errBody = await res.text()
31
+ throw new Error(`Agora API error ${res.status}: ${errBody}`)
32
+ }
33
+
34
+ return res.json() as Promise<T>
35
+ }
36
+
37
+ // --- Registration (unauthenticated) ---
38
+
39
+ static async register(endpoint: string, params: {
40
+ name: string
41
+ capabilities: string[]
42
+ walletAddress: string
43
+ description?: string
44
+ }): Promise<{ agent: { id: string; apiKey: string; name: string }; protocol: Record<string, unknown> }> {
45
+ const url = `${endpoint}/v1/agents`
46
+ const res = await fetch(url, {
47
+ method: 'POST',
48
+ headers: {
49
+ 'Content-Type': 'application/json',
50
+ 'X-Request-Id': randomUUID(),
51
+ },
52
+ body: JSON.stringify({
53
+ name: params.name,
54
+ capabilities: params.capabilities,
55
+ walletAddress: params.walletAddress,
56
+ description: params.description || `Agent ${params.name} on Agora`,
57
+ }),
58
+ })
59
+
60
+ if (!res.ok) {
61
+ const errBody = await res.text()
62
+ throw new Error(`Registration failed (${res.status}): ${errBody}`)
63
+ }
64
+
65
+ return res.json() as Promise<{ agent: { id: string; apiKey: string; name: string }; protocol: Record<string, unknown> }>
66
+ }
67
+
68
+ // --- Tasks ---
69
+
70
+ async publishTask(params: {
71
+ title: string
72
+ description: string
73
+ skill: string
74
+ budget: number
75
+ deadline: string
76
+ executorRequirement?: string
77
+ acceptanceCriteria?: string
78
+ executionEnvironment?: string
79
+ }): Promise<{ id: string; status: string }> {
80
+ // Convert deadline shorthand (e.g., "2h", "30m") to ISO 8601
81
+ const deadlineDate = resolveDeadline(params.deadline)
82
+
83
+ return this.request('POST', '/v1/tasks', {
84
+ title: params.title,
85
+ description: params.description,
86
+ requiredSkills: [params.skill],
87
+ budget: params.budget,
88
+ deadline: deadlineDate,
89
+ initiatorRole: 'AA',
90
+ executorRequirement: mapExecutorType(params.executorRequirement || 'agent'),
91
+ executionEnvironment: params.executionEnvironment || 'DIG',
92
+ taskComplexity: 'ATM',
93
+ acceptanceCriteria: params.acceptanceCriteria || `Complete the task as described: ${params.title}`,
94
+ paymentMethod: 'x402',
95
+ })
96
+ }
97
+
98
+ async searchTasks(params: {
99
+ skills?: string
100
+ budgetMin?: number
101
+ budgetMax?: number
102
+ executorRequirement?: string
103
+ keyword?: string
104
+ limit?: number
105
+ }): Promise<{ tasks: Array<Record<string, unknown>>; total: number }> {
106
+ const query = new URLSearchParams()
107
+ if (params.skills) query.set('skills', params.skills)
108
+ if (params.budgetMin) query.set('budgetMin', String(params.budgetMin))
109
+ if (params.budgetMax) query.set('budgetMax', String(params.budgetMax))
110
+ if (params.executorRequirement) query.set('executorRequirement', params.executorRequirement)
111
+ if (params.keyword) query.set('keyword', params.keyword)
112
+ if (params.limit) query.set('pageSize', String(params.limit))
113
+
114
+ return this.request('GET', `/v1/tasks/search?${query.toString()}`)
115
+ }
116
+
117
+ async submitBid(params: {
118
+ taskId: string
119
+ price: number
120
+ estimatedHours: number
121
+ message?: string
122
+ }): Promise<{ id: string; status: string }> {
123
+ return this.request('POST', `/v1/tasks/${params.taskId}/bids`, {
124
+ price: params.price,
125
+ estimatedHours: params.estimatedHours,
126
+ message: params.message,
127
+ })
128
+ }
129
+
130
+ async deliver(params: {
131
+ taskId: string
132
+ content?: string
133
+ fileReferences?: string[]
134
+ notes?: string
135
+ }): Promise<{ id: string; status: string; revision: number }> {
136
+ return this.request('POST', `/v1/tasks/${params.taskId}/deliverables`, {
137
+ content: params.content,
138
+ fileReferences: params.fileReferences,
139
+ notes: params.notes,
140
+ })
141
+ }
142
+
143
+ async getTaskStatus(taskId: string): Promise<Record<string, unknown>> {
144
+ return this.request('GET', `/v1/tasks/${taskId}`)
145
+ }
146
+
147
+ async listTasks(params?: {
148
+ status?: string
149
+ page?: number
150
+ pageSize?: number
151
+ }): Promise<{ tasks: Array<Record<string, unknown>>; total: number }> {
152
+ const query = new URLSearchParams()
153
+ if (params?.status) query.set('status', params.status)
154
+ if (params?.page) query.set('page', String(params.page))
155
+ if (params?.pageSize) query.set('pageSize', String(params.pageSize))
156
+ return this.request('GET', `/v1/tasks?${query.toString()}`)
157
+ }
158
+ }
159
+
160
+ function mapExecutorType(friendly: string): string {
161
+ const map: Record<string, string> = {
162
+ 'agent': 'MX',
163
+ 'human': 'HR',
164
+ 'hybrid': 'FL',
165
+ // Also accept raw enum values
166
+ 'MX': 'MX',
167
+ 'HR': 'HR',
168
+ 'FL': 'FL',
169
+ }
170
+ return map[friendly] || 'FL'
171
+ }
172
+
173
+ function resolveDeadline(shorthand: string): string {
174
+ const now = new Date()
175
+ const match = shorthand.match(/^(\d+)(m|h|d)$/)
176
+ if (match) {
177
+ const [, num, unit] = match
178
+ const value = parseInt(num!, 10)
179
+ if (unit === 'm') now.setMinutes(now.getMinutes() + value)
180
+ else if (unit === 'h') now.setHours(now.getHours() + value)
181
+ else if (unit === 'd') now.setDate(now.getDate() + value)
182
+ return now.toISOString()
183
+ }
184
+ // Assume ISO 8601 already
185
+ return shorthand
186
+ }