@yolk-sdk/connectors 0.0.1-canary.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 (106) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +195 -0
  3. package/dist/action.d.mts +37 -0
  4. package/dist/action.d.mts.map +1 -0
  5. package/dist/action.mjs +24 -0
  6. package/dist/action.mjs.map +1 -0
  7. package/dist/agent.d.mts +21 -0
  8. package/dist/agent.d.mts.map +1 -0
  9. package/dist/agent.mjs +66 -0
  10. package/dist/agent.mjs.map +1 -0
  11. package/dist/config.d.mts +10 -0
  12. package/dist/config.d.mts.map +1 -0
  13. package/dist/config.mjs +21 -0
  14. package/dist/config.mjs.map +1 -0
  15. package/dist/connector.d.mts +27 -0
  16. package/dist/connector.d.mts.map +1 -0
  17. package/dist/connector.mjs +32 -0
  18. package/dist/connector.mjs.map +1 -0
  19. package/dist/credential.d.mts +62 -0
  20. package/dist/credential.d.mts.map +1 -0
  21. package/dist/credential.mjs +62 -0
  22. package/dist/credential.mjs.map +1 -0
  23. package/dist/error.d.mts +17 -0
  24. package/dist/error.d.mts.map +1 -0
  25. package/dist/error.mjs +22 -0
  26. package/dist/error.mjs.map +1 -0
  27. package/dist/figma/index.d.mts +48 -0
  28. package/dist/figma/index.d.mts.map +1 -0
  29. package/dist/figma/index.mjs +97 -0
  30. package/dist/figma/index.mjs.map +1 -0
  31. package/dist/google/calendar.d.mts +53 -0
  32. package/dist/google/calendar.d.mts.map +1 -0
  33. package/dist/google/calendar.mjs +111 -0
  34. package/dist/google/calendar.mjs.map +1 -0
  35. package/dist/google/gmail.d.mts +53 -0
  36. package/dist/google/gmail.d.mts.map +1 -0
  37. package/dist/google/gmail.mjs +103 -0
  38. package/dist/google/gmail.mjs.map +1 -0
  39. package/dist/google/index.d.mts +14 -0
  40. package/dist/google/index.d.mts.map +1 -0
  41. package/dist/google/index.mjs +15 -0
  42. package/dist/google/index.mjs.map +1 -0
  43. package/dist/google/oauth.d.mts +18 -0
  44. package/dist/google/oauth.d.mts.map +1 -0
  45. package/dist/google/oauth.mjs +25 -0
  46. package/dist/google/oauth.mjs.map +1 -0
  47. package/dist/google/shared.d.mts +20 -0
  48. package/dist/google/shared.d.mts.map +1 -0
  49. package/dist/google/shared.mjs +36 -0
  50. package/dist/google/shared.mjs.map +1 -0
  51. package/dist/http.d.mts +32 -0
  52. package/dist/http.d.mts.map +1 -0
  53. package/dist/http.mjs +36 -0
  54. package/dist/http.mjs.map +1 -0
  55. package/dist/index.d.mts +9 -0
  56. package/dist/index.mjs +9 -0
  57. package/dist/integration.d.mts +24 -0
  58. package/dist/integration.d.mts.map +1 -0
  59. package/dist/integration.mjs +22 -0
  60. package/dist/integration.mjs.map +1 -0
  61. package/dist/linkedin-search/index.d.mts +60 -0
  62. package/dist/linkedin-search/index.d.mts.map +1 -0
  63. package/dist/linkedin-search/index.mjs +162 -0
  64. package/dist/linkedin-search/index.mjs.map +1 -0
  65. package/dist/notion/index.d.mts +69 -0
  66. package/dist/notion/index.d.mts.map +1 -0
  67. package/dist/notion/index.mjs +169 -0
  68. package/dist/notion/index.mjs.map +1 -0
  69. package/dist/r2-storage/index.d.mts +48 -0
  70. package/dist/r2-storage/index.d.mts.map +1 -0
  71. package/dist/r2-storage/index.mjs +91 -0
  72. package/dist/r2-storage/index.mjs.map +1 -0
  73. package/dist/result.d.mts +32 -0
  74. package/dist/result.d.mts.map +1 -0
  75. package/dist/result.mjs +23 -0
  76. package/dist/result.mjs.map +1 -0
  77. package/dist/telegram/index.d.mts +34 -0
  78. package/dist/telegram/index.d.mts.map +1 -0
  79. package/dist/telegram/index.mjs +109 -0
  80. package/dist/telegram/index.mjs.map +1 -0
  81. package/dist/todoist/index.d.mts +70 -0
  82. package/dist/todoist/index.d.mts.map +1 -0
  83. package/dist/todoist/index.mjs +176 -0
  84. package/dist/todoist/index.mjs.map +1 -0
  85. package/package.json +96 -0
  86. package/src/action.ts +75 -0
  87. package/src/agent.ts +120 -0
  88. package/src/config.ts +28 -0
  89. package/src/connector.ts +62 -0
  90. package/src/credential.ts +86 -0
  91. package/src/error.ts +20 -0
  92. package/src/figma/index.ts +121 -0
  93. package/src/google/calendar.ts +145 -0
  94. package/src/google/gmail.ts +127 -0
  95. package/src/google/index.ts +46 -0
  96. package/src/google/oauth.ts +26 -0
  97. package/src/google/shared.ts +56 -0
  98. package/src/http.ts +51 -0
  99. package/src/index.ts +36 -0
  100. package/src/integration.ts +28 -0
  101. package/src/linkedin-search/index.ts +217 -0
  102. package/src/notion/index.ts +234 -0
  103. package/src/r2-storage/index.ts +118 -0
  104. package/src/result.ts +35 -0
  105. package/src/telegram/index.ts +144 -0
  106. package/src/todoist/index.ts +227 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/telegram/index.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { defineAction } from '../action.ts'\nimport { requiredStringConfig } from '../config.ts'\nimport { defineConnector } from '../connector.ts'\nimport { CredentialSlot, resolveCredential } from '../credential.ts'\nimport { ConnectorHttpClient, ConnectorHttpRequest } from '../http.ts'\nimport { ActionResult, ProviderFailure } from '../result.ts'\nimport type { ConnectorIntegration } from '../integration.ts'\n\nexport const telegramConnectorId = 'telegram'\nexport const telegramBotTokenSlotId = 'telegram.bot_token'\nexport const telegramApiBaseUrl = 'https://api.telegram.org'\n\nexport const TelegramBotTokenSlot = CredentialSlot.make({\n id: telegramBotTokenSlotId,\n kind: 'api_key'\n})\n\nconst resolveTelegramBotToken = (integration: ConnectorIntegration) =>\n Effect.gen(function* () {\n const credential = yield* resolveCredential(integration, TelegramBotTokenSlot)\n\n switch (credential._tag) {\n case 'ApiKeyCredential':\n return credential.key\n case 'BearerTokenCredential':\n return credential.token\n case 'OAuthCredential':\n return credential.accessToken\n }\n })\n\nconst isSuccessStatus = (status: number) => status >= 200 && status < 300\n\nconst telegramProviderFailure = (input: {\n readonly code: string\n readonly message: string\n readonly status: number\n readonly body: string\n}) =>\n ActionResult.failure(\n new ProviderFailure({\n code: input.code,\n message: input.message,\n status: input.status,\n underlying: input.body\n })\n )\n\nexport class TelegramSendMessageInput extends Schema.Class<TelegramSendMessageInput>(\n 'TelegramSendMessageInput'\n)({\n message: Schema.String,\n disableWebPagePreview: Schema.optional(Schema.Boolean)\n}) {}\n\nexport class TelegramSendMessageOutput extends Schema.Class<TelegramSendMessageOutput>(\n 'TelegramSendMessageOutput'\n)({\n sent: Schema.Boolean,\n chatId: Schema.String\n}) {}\n\nexport class TelegramValidateOutput extends Schema.Class<TelegramValidateOutput>('TelegramValidateOutput')({\n ok: Schema.Boolean,\n chatId: Schema.String\n}) {}\n\nexport const telegramSendMessageAction = defineAction({\n id: 'telegram.send_message',\n description: 'Send a Telegram message to the configured chat.',\n inputSchema: TelegramSendMessageInput,\n outputSchema: TelegramSendMessageOutput,\n execute: ({ integration, input }) =>\n Effect.gen(function* () {\n const botToken = yield* resolveTelegramBotToken(integration)\n const chatId = yield* requiredStringConfig(integration, 'chatId')\n const http = yield* ConnectorHttpClient\n const response = yield* http.request(\n ConnectorHttpRequest.make({\n method: 'POST',\n url: `${telegramApiBaseUrl}/bot${botToken}/sendMessage`,\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n chat_id: chatId,\n text: input.message,\n disable_web_page_preview: input.disableWebPagePreview ?? true\n })\n })\n )\n\n if (!isSuccessStatus(response.status)) {\n return telegramProviderFailure({\n code: response.status === 429 ? 'telegram_rate_limited' : 'telegram_send_failed',\n message: 'Telegram send message failed',\n status: response.status,\n body: response.body\n })\n }\n\n return ActionResult.success(TelegramSendMessageOutput.make({ sent: true, chatId }))\n })\n})\n\nexport const telegramValidateAction = defineAction({\n id: 'telegram.validate',\n description: 'Validate the Telegram bot token and configured chat.',\n inputSchema: Schema.Struct({}),\n outputSchema: TelegramValidateOutput,\n execute: ({ integration }) =>\n Effect.gen(function* () {\n const botToken = yield* resolveTelegramBotToken(integration)\n const chatId = yield* requiredStringConfig(integration, 'chatId')\n const http = yield* ConnectorHttpClient\n const response = yield* http.request(\n ConnectorHttpRequest.make({\n method: 'POST',\n url: `${telegramApiBaseUrl}/bot${botToken}/getChat`,\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ chat_id: chatId })\n })\n )\n\n if (!isSuccessStatus(response.status)) {\n return telegramProviderFailure({\n code: 'telegram_validate_failed',\n message: 'Telegram validation failed',\n status: response.status,\n body: response.body\n })\n }\n\n return ActionResult.success(TelegramValidateOutput.make({ ok: true, chatId }))\n })\n})\n\nexport const telegramActions = [telegramSendMessageAction, telegramValidateAction]\n\nexport const TelegramConnector = defineConnector({\n id: telegramConnectorId,\n description: 'Telegram bot connector actions.',\n actions: telegramActions\n})\n"],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import { ConnectorError } from "../error.mjs";
2
+ import { CredentialResolver, CredentialSlot } from "../credential.mjs";
3
+ import { ConnectorAction } from "../action.mjs";
4
+ import { Connector } from "../connector.mjs";
5
+ import { ConnectorHttpClient } from "../http.mjs";
6
+ import * as Schema from "effect/Schema";
7
+
8
+ //#region src/todoist/index.d.ts
9
+ declare const todoistConnectorId = "todoist";
10
+ declare const todoistApiTokenSlotId = "todoist.api_token";
11
+ declare const todoistApiBaseUrl = "https://api.todoist.com/rest/v2";
12
+ declare const TodoistApiTokenSlot: CredentialSlot;
13
+ declare const todoistAuthorizationHeaders: (token: string) => {
14
+ authorization: string;
15
+ };
16
+ declare const TodoistTask_base: Schema.Class<TodoistTask, Schema.Struct<{
17
+ readonly id: Schema.String;
18
+ readonly content: Schema.String;
19
+ readonly description: Schema.optional<Schema.String>;
20
+ readonly projectId: Schema.optional<Schema.String>;
21
+ readonly sectionId: Schema.optional<Schema.String>;
22
+ readonly parentId: Schema.optional<Schema.String>;
23
+ readonly labels: Schema.optional<Schema.$Array<Schema.String>>;
24
+ readonly priority: Schema.optional<Schema.Number>;
25
+ readonly due: Schema.optional<Schema.Unknown>;
26
+ readonly url: Schema.optional<Schema.String>;
27
+ }>, {}>;
28
+ declare class TodoistTask extends TodoistTask_base {}
29
+ declare const TodoistListTasksInput_base: Schema.Class<TodoistListTasksInput, Schema.Struct<{
30
+ readonly projectId: Schema.optional<Schema.String>;
31
+ readonly sectionId: Schema.optional<Schema.String>;
32
+ readonly parentId: Schema.optional<Schema.String>;
33
+ readonly label: Schema.optional<Schema.String>;
34
+ readonly filter: Schema.optional<Schema.String>;
35
+ }>, {}>;
36
+ declare class TodoistListTasksInput extends TodoistListTasksInput_base {}
37
+ declare const TodoistListTasksOutput_base: Schema.Class<TodoistListTasksOutput, Schema.Struct<{
38
+ readonly tasks: Schema.$Array<typeof TodoistTask>;
39
+ }>, {}>;
40
+ declare class TodoistListTasksOutput extends TodoistListTasksOutput_base {}
41
+ declare const TodoistCreateTaskInput_base: Schema.Class<TodoistCreateTaskInput, Schema.Struct<{
42
+ readonly content: Schema.String;
43
+ readonly description: Schema.optional<Schema.String>;
44
+ readonly projectId: Schema.optional<Schema.String>;
45
+ readonly sectionId: Schema.optional<Schema.String>;
46
+ readonly parentId: Schema.optional<Schema.String>;
47
+ readonly labels: Schema.optional<Schema.$Array<Schema.String>>;
48
+ readonly priority: Schema.optional<Schema.Number>;
49
+ readonly dueString: Schema.optional<Schema.String>;
50
+ readonly dueDate: Schema.optional<Schema.String>;
51
+ readonly dueDatetime: Schema.optional<Schema.String>;
52
+ }>, {}>;
53
+ declare class TodoistCreateTaskInput extends TodoistCreateTaskInput_base {}
54
+ declare const TodoistCloseTaskInput_base: Schema.Class<TodoistCloseTaskInput, Schema.Struct<{
55
+ readonly id: Schema.String;
56
+ }>, {}>;
57
+ declare class TodoistCloseTaskInput extends TodoistCloseTaskInput_base {}
58
+ declare const TodoistCloseTaskOutput_base: Schema.Class<TodoistCloseTaskOutput, Schema.Struct<{
59
+ readonly id: Schema.String;
60
+ readonly closed: Schema.Boolean;
61
+ }>, {}>;
62
+ declare class TodoistCloseTaskOutput extends TodoistCloseTaskOutput_base {}
63
+ declare const todoistListTasksAction: ConnectorAction<ConnectorHttpClient | CredentialResolver, ConnectorError>;
64
+ declare const todoistCreateTaskAction: ConnectorAction<ConnectorHttpClient | CredentialResolver, ConnectorError>;
65
+ declare const todoistCloseTaskAction: ConnectorAction<ConnectorHttpClient | CredentialResolver, ConnectorError>;
66
+ declare const todoistActions: ConnectorAction<ConnectorHttpClient | CredentialResolver, ConnectorError>[];
67
+ declare const TodoistConnector: Connector<ConnectorHttpClient | CredentialResolver, ConnectorError>;
68
+ //#endregion
69
+ export { TodoistApiTokenSlot, TodoistCloseTaskInput, TodoistCloseTaskOutput, TodoistConnector, TodoistCreateTaskInput, TodoistListTasksInput, TodoistListTasksOutput, TodoistTask, todoistActions, todoistApiBaseUrl, todoistApiTokenSlotId, todoistAuthorizationHeaders, todoistCloseTaskAction, todoistConnectorId, todoistCreateTaskAction, todoistListTasksAction };
70
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/todoist/index.ts"],"mappings":";;;;;;;;cASa,kBAAA;AAAA,cACA,qBAAA;AAAA,cACA,iBAAA;AAAA,cAEA,mBAAA,EAAmB,cAG9B;AAAA,cAEW,2BAAA,GAA+B,KAAA;EAAA,aAAA;AAAA;AAAA,cAE1C,gBAAA;;;;;;;;;;;;cAiCW,WAAA,SAAoB,gBAW/B;AAAA,cAAG,0BAAA;;;;;;;cAEQ,qBAAA,SAA8B,0BAMzC;AAAA,cAAG,2BAAA;;;cAEQ,sBAAA,SAA+B,2BAE1C;AAAA,cAAG,2BAAA;;;;;;;;;;;;cAEQ,sBAAA,SAA+B,2BAW1C;AAAA,cAAG,0BAAA;;;cAEQ,qBAAA,SAA8B,0BAEzC;AAAA,cAAG,2BAAA;;;;cAEQ,sBAAA,SAA+B,2BAG1C;AAAA,cAQW,sBAAA,EAAsB,eAAA,CAAA,mBAAA,GAAA,kBAAA,EAAA,cAAA;AAAA,cAsCtB,uBAAA,EAAuB,eAAA,CAAA,mBAAA,GAAA,kBAAA,EAAA,cAAA;AAAA,cA8CvB,sBAAA,EAAsB,eAAA,CAAA,mBAAA,GAAA,kBAAA,EAAA,cAAA;AAAA,cA8BtB,cAAA,EAAc,eAAA,CAAA,mBAAA,GAAA,kBAAA,EAAA,cAAA;AAAA,cAEd,gBAAA,EAAgB,SAAA,CAAA,mBAAA,GAAA,kBAAA,EAAA,cAAA"}
@@ -0,0 +1,176 @@
1
+ import { defineAction } from "../action.mjs";
2
+ import { defineConnector } from "../connector.mjs";
3
+ import { CredentialSlot, resolveCredential } from "../credential.mjs";
4
+ import { ConnectorHttpClient, ConnectorHttpRequest, decodeJsonResponse } from "../http.mjs";
5
+ import { ActionResult, ProviderFailure } from "../result.mjs";
6
+ import { Effect } from "effect";
7
+ import * as Schema from "effect/Schema";
8
+ //#region src/todoist/index.ts
9
+ const todoistConnectorId = "todoist";
10
+ const todoistApiTokenSlotId = "todoist.api_token";
11
+ const todoistApiBaseUrl = "https://api.todoist.com/rest/v2";
12
+ const TodoistApiTokenSlot = CredentialSlot.make({
13
+ id: todoistApiTokenSlotId,
14
+ kind: "api_key"
15
+ });
16
+ const todoistAuthorizationHeaders = (token) => ({ authorization: `Bearer ${token}` });
17
+ const isSuccessStatus = (status) => status >= 200 && status < 300;
18
+ const todoistProviderFailure = (input) => ActionResult.failure(new ProviderFailure({
19
+ code: input.code,
20
+ message: input.message,
21
+ status: input.status,
22
+ underlying: input.body
23
+ }));
24
+ const resolveTodoistToken = (integration) => Effect.gen(function* () {
25
+ const credential = yield* resolveCredential(integration, TodoistApiTokenSlot);
26
+ switch (credential._tag) {
27
+ case "ApiKeyCredential": return credential.key;
28
+ case "BearerTokenCredential": return credential.token;
29
+ case "OAuthCredential": return credential.accessToken;
30
+ }
31
+ });
32
+ var TodoistTask = class extends Schema.Class("TodoistTask")({
33
+ id: Schema.String,
34
+ content: Schema.String,
35
+ description: Schema.optional(Schema.String),
36
+ projectId: Schema.optional(Schema.String),
37
+ sectionId: Schema.optional(Schema.String),
38
+ parentId: Schema.optional(Schema.String),
39
+ labels: Schema.optional(Schema.Array(Schema.String)),
40
+ priority: Schema.optional(Schema.Number),
41
+ due: Schema.optional(Schema.Unknown),
42
+ url: Schema.optional(Schema.String)
43
+ }) {};
44
+ var TodoistListTasksInput = class extends Schema.Class("TodoistListTasksInput")({
45
+ projectId: Schema.optional(Schema.String),
46
+ sectionId: Schema.optional(Schema.String),
47
+ parentId: Schema.optional(Schema.String),
48
+ label: Schema.optional(Schema.String),
49
+ filter: Schema.optional(Schema.String)
50
+ }) {};
51
+ var TodoistListTasksOutput = class extends Schema.Class("TodoistListTasksOutput")({ tasks: Schema.Array(TodoistTask) }) {};
52
+ var TodoistCreateTaskInput = class extends Schema.Class("TodoistCreateTaskInput")({
53
+ content: Schema.String,
54
+ description: Schema.optional(Schema.String),
55
+ projectId: Schema.optional(Schema.String),
56
+ sectionId: Schema.optional(Schema.String),
57
+ parentId: Schema.optional(Schema.String),
58
+ labels: Schema.optional(Schema.Array(Schema.String)),
59
+ priority: Schema.optional(Schema.Number),
60
+ dueString: Schema.optional(Schema.String),
61
+ dueDate: Schema.optional(Schema.String),
62
+ dueDatetime: Schema.optional(Schema.String)
63
+ }) {};
64
+ var TodoistCloseTaskInput = class extends Schema.Class("TodoistCloseTaskInput")({ id: Schema.String }) {};
65
+ var TodoistCloseTaskOutput = class extends Schema.Class("TodoistCloseTaskOutput")({
66
+ id: Schema.String,
67
+ closed: Schema.Boolean
68
+ }) {};
69
+ const appendSearchParam = (params, key, value) => {
70
+ if (value !== void 0 && value.trim() !== "") params.set(key, value);
71
+ };
72
+ const todoistListTasksAction = defineAction({
73
+ id: "todoist.list_tasks",
74
+ description: "List Todoist active tasks.",
75
+ inputSchema: TodoistListTasksInput,
76
+ outputSchema: TodoistListTasksOutput,
77
+ execute: ({ integration, input }) => Effect.gen(function* () {
78
+ const token = yield* resolveTodoistToken(integration);
79
+ const http = yield* ConnectorHttpClient;
80
+ const params = new URLSearchParams();
81
+ appendSearchParam(params, "project_id", input.projectId);
82
+ appendSearchParam(params, "section_id", input.sectionId);
83
+ appendSearchParam(params, "parent_id", input.parentId);
84
+ appendSearchParam(params, "label", input.label);
85
+ appendSearchParam(params, "filter", input.filter);
86
+ const query = params.toString();
87
+ const response = yield* http.request(ConnectorHttpRequest.make({
88
+ method: "GET",
89
+ url: `${todoistApiBaseUrl}/tasks${query === "" ? "" : `?${query}`}`,
90
+ headers: todoistAuthorizationHeaders(token)
91
+ }));
92
+ if (!isSuccessStatus(response.status)) return todoistProviderFailure({
93
+ code: "todoist_list_tasks_failed",
94
+ message: "Todoist list tasks failed",
95
+ status: response.status,
96
+ body: response.body
97
+ });
98
+ const tasks = yield* decodeJsonResponse(Schema.Array(TodoistTask), response);
99
+ return ActionResult.success(TodoistListTasksOutput.make({ tasks }));
100
+ })
101
+ });
102
+ const todoistCreateTaskAction = defineAction({
103
+ id: "todoist.create_task",
104
+ description: "Create a Todoist task.",
105
+ inputSchema: TodoistCreateTaskInput,
106
+ outputSchema: TodoistTask,
107
+ execute: ({ integration, input }) => Effect.gen(function* () {
108
+ const token = yield* resolveTodoistToken(integration);
109
+ const response = yield* (yield* ConnectorHttpClient).request(ConnectorHttpRequest.make({
110
+ method: "POST",
111
+ url: `${todoistApiBaseUrl}/tasks`,
112
+ headers: {
113
+ ...todoistAuthorizationHeaders(token),
114
+ "content-type": "application/json"
115
+ },
116
+ body: JSON.stringify({
117
+ content: input.content,
118
+ description: input.description,
119
+ project_id: input.projectId,
120
+ section_id: input.sectionId,
121
+ parent_id: input.parentId,
122
+ labels: input.labels,
123
+ priority: input.priority,
124
+ due_string: input.dueString,
125
+ due_date: input.dueDate,
126
+ due_datetime: input.dueDatetime
127
+ })
128
+ }));
129
+ if (!isSuccessStatus(response.status)) return todoistProviderFailure({
130
+ code: "todoist_create_task_failed",
131
+ message: "Todoist create task failed",
132
+ status: response.status,
133
+ body: response.body
134
+ });
135
+ const output = yield* decodeJsonResponse(TodoistTask, response);
136
+ return ActionResult.success(output);
137
+ })
138
+ });
139
+ const todoistCloseTaskAction = defineAction({
140
+ id: "todoist.close_task",
141
+ description: "Close a Todoist task.",
142
+ inputSchema: TodoistCloseTaskInput,
143
+ outputSchema: TodoistCloseTaskOutput,
144
+ execute: ({ integration, input }) => Effect.gen(function* () {
145
+ const token = yield* resolveTodoistToken(integration);
146
+ const response = yield* (yield* ConnectorHttpClient).request(ConnectorHttpRequest.make({
147
+ method: "POST",
148
+ url: `${todoistApiBaseUrl}/tasks/${encodeURIComponent(input.id)}/close`,
149
+ headers: todoistAuthorizationHeaders(token)
150
+ }));
151
+ if (!isSuccessStatus(response.status)) return todoistProviderFailure({
152
+ code: "todoist_close_task_failed",
153
+ message: "Todoist close task failed",
154
+ status: response.status,
155
+ body: response.body
156
+ });
157
+ return ActionResult.success(TodoistCloseTaskOutput.make({
158
+ id: input.id,
159
+ closed: true
160
+ }));
161
+ })
162
+ });
163
+ const todoistActions = [
164
+ todoistListTasksAction,
165
+ todoistCreateTaskAction,
166
+ todoistCloseTaskAction
167
+ ];
168
+ const TodoistConnector = defineConnector({
169
+ id: todoistConnectorId,
170
+ description: "Todoist task connector actions.",
171
+ actions: todoistActions
172
+ });
173
+ //#endregion
174
+ export { TodoistApiTokenSlot, TodoistCloseTaskInput, TodoistCloseTaskOutput, TodoistConnector, TodoistCreateTaskInput, TodoistListTasksInput, TodoistListTasksOutput, TodoistTask, todoistActions, todoistApiBaseUrl, todoistApiTokenSlotId, todoistAuthorizationHeaders, todoistCloseTaskAction, todoistConnectorId, todoistCreateTaskAction, todoistListTasksAction };
175
+
176
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/todoist/index.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { defineAction } from '../action.ts'\nimport { defineConnector } from '../connector.ts'\nimport { CredentialSlot, resolveCredential } from '../credential.ts'\nimport { ConnectorHttpClient, ConnectorHttpRequest, decodeJsonResponse } from '../http.ts'\nimport { ActionResult, ProviderFailure } from '../result.ts'\nimport type { ConnectorIntegration } from '../integration.ts'\n\nexport const todoistConnectorId = 'todoist'\nexport const todoistApiTokenSlotId = 'todoist.api_token'\nexport const todoistApiBaseUrl = 'https://api.todoist.com/rest/v2'\n\nexport const TodoistApiTokenSlot = CredentialSlot.make({\n id: todoistApiTokenSlotId,\n kind: 'api_key'\n})\n\nexport const todoistAuthorizationHeaders = (token: string) => ({\n authorization: `Bearer ${token}`\n})\n\nconst isSuccessStatus = (status: number) => status >= 200 && status < 300\n\nconst todoistProviderFailure = (input: {\n readonly code: string\n readonly message: string\n readonly status: number\n readonly body: string\n}) =>\n ActionResult.failure(\n new ProviderFailure({\n code: input.code,\n message: input.message,\n status: input.status,\n underlying: input.body\n })\n )\n\nconst resolveTodoistToken = (integration: ConnectorIntegration) =>\n Effect.gen(function* () {\n const credential = yield* resolveCredential(integration, TodoistApiTokenSlot)\n\n switch (credential._tag) {\n case 'ApiKeyCredential':\n return credential.key\n case 'BearerTokenCredential':\n return credential.token\n case 'OAuthCredential':\n return credential.accessToken\n }\n })\n\nexport class TodoistTask extends Schema.Class<TodoistTask>('TodoistTask')({\n id: Schema.String,\n content: Schema.String,\n description: Schema.optional(Schema.String),\n projectId: Schema.optional(Schema.String),\n sectionId: Schema.optional(Schema.String),\n parentId: Schema.optional(Schema.String),\n labels: Schema.optional(Schema.Array(Schema.String)),\n priority: Schema.optional(Schema.Number),\n due: Schema.optional(Schema.Unknown),\n url: Schema.optional(Schema.String)\n}) {}\n\nexport class TodoistListTasksInput extends Schema.Class<TodoistListTasksInput>('TodoistListTasksInput')({\n projectId: Schema.optional(Schema.String),\n sectionId: Schema.optional(Schema.String),\n parentId: Schema.optional(Schema.String),\n label: Schema.optional(Schema.String),\n filter: Schema.optional(Schema.String)\n}) {}\n\nexport class TodoistListTasksOutput extends Schema.Class<TodoistListTasksOutput>('TodoistListTasksOutput')({\n tasks: Schema.Array(TodoistTask)\n}) {}\n\nexport class TodoistCreateTaskInput extends Schema.Class<TodoistCreateTaskInput>('TodoistCreateTaskInput')({\n content: Schema.String,\n description: Schema.optional(Schema.String),\n projectId: Schema.optional(Schema.String),\n sectionId: Schema.optional(Schema.String),\n parentId: Schema.optional(Schema.String),\n labels: Schema.optional(Schema.Array(Schema.String)),\n priority: Schema.optional(Schema.Number),\n dueString: Schema.optional(Schema.String),\n dueDate: Schema.optional(Schema.String),\n dueDatetime: Schema.optional(Schema.String)\n}) {}\n\nexport class TodoistCloseTaskInput extends Schema.Class<TodoistCloseTaskInput>('TodoistCloseTaskInput')({\n id: Schema.String\n}) {}\n\nexport class TodoistCloseTaskOutput extends Schema.Class<TodoistCloseTaskOutput>('TodoistCloseTaskOutput')({\n id: Schema.String,\n closed: Schema.Boolean\n}) {}\n\nconst appendSearchParam = (params: URLSearchParams, key: string, value: string | undefined) => {\n if (value !== undefined && value.trim() !== '') {\n params.set(key, value)\n }\n}\n\nexport const todoistListTasksAction = defineAction({\n id: 'todoist.list_tasks',\n description: 'List Todoist active tasks.',\n inputSchema: TodoistListTasksInput,\n outputSchema: TodoistListTasksOutput,\n execute: ({ integration, input }) =>\n Effect.gen(function* () {\n const token = yield* resolveTodoistToken(integration)\n const http = yield* ConnectorHttpClient\n const params = new URLSearchParams()\n appendSearchParam(params, 'project_id', input.projectId)\n appendSearchParam(params, 'section_id', input.sectionId)\n appendSearchParam(params, 'parent_id', input.parentId)\n appendSearchParam(params, 'label', input.label)\n appendSearchParam(params, 'filter', input.filter)\n const query = params.toString()\n const response = yield* http.request(\n ConnectorHttpRequest.make({\n method: 'GET',\n url: `${todoistApiBaseUrl}/tasks${query === '' ? '' : `?${query}`}`,\n headers: todoistAuthorizationHeaders(token)\n })\n )\n\n if (!isSuccessStatus(response.status)) {\n return todoistProviderFailure({\n code: 'todoist_list_tasks_failed',\n message: 'Todoist list tasks failed',\n status: response.status,\n body: response.body\n })\n }\n\n const tasks = yield* decodeJsonResponse(Schema.Array(TodoistTask), response)\n return ActionResult.success(TodoistListTasksOutput.make({ tasks }))\n })\n})\n\nexport const todoistCreateTaskAction = defineAction({\n id: 'todoist.create_task',\n description: 'Create a Todoist task.',\n inputSchema: TodoistCreateTaskInput,\n outputSchema: TodoistTask,\n execute: ({ integration, input }) =>\n Effect.gen(function* () {\n const token = yield* resolveTodoistToken(integration)\n const http = yield* ConnectorHttpClient\n const response = yield* http.request(\n ConnectorHttpRequest.make({\n method: 'POST',\n url: `${todoistApiBaseUrl}/tasks`,\n headers: {\n ...todoistAuthorizationHeaders(token),\n 'content-type': 'application/json'\n },\n body: JSON.stringify({\n content: input.content,\n description: input.description,\n project_id: input.projectId,\n section_id: input.sectionId,\n parent_id: input.parentId,\n labels: input.labels,\n priority: input.priority,\n due_string: input.dueString,\n due_date: input.dueDate,\n due_datetime: input.dueDatetime\n })\n })\n )\n\n if (!isSuccessStatus(response.status)) {\n return todoistProviderFailure({\n code: 'todoist_create_task_failed',\n message: 'Todoist create task failed',\n status: response.status,\n body: response.body\n })\n }\n\n const output = yield* decodeJsonResponse(TodoistTask, response)\n return ActionResult.success(output)\n })\n})\n\nexport const todoistCloseTaskAction = defineAction({\n id: 'todoist.close_task',\n description: 'Close a Todoist task.',\n inputSchema: TodoistCloseTaskInput,\n outputSchema: TodoistCloseTaskOutput,\n execute: ({ integration, input }) =>\n Effect.gen(function* () {\n const token = yield* resolveTodoistToken(integration)\n const http = yield* ConnectorHttpClient\n const response = yield* http.request(\n ConnectorHttpRequest.make({\n method: 'POST',\n url: `${todoistApiBaseUrl}/tasks/${encodeURIComponent(input.id)}/close`,\n headers: todoistAuthorizationHeaders(token)\n })\n )\n\n if (!isSuccessStatus(response.status)) {\n return todoistProviderFailure({\n code: 'todoist_close_task_failed',\n message: 'Todoist close task failed',\n status: response.status,\n body: response.body\n })\n }\n\n return ActionResult.success(TodoistCloseTaskOutput.make({ id: input.id, closed: true }))\n })\n})\n\nexport const todoistActions = [todoistListTasksAction, todoistCreateTaskAction, todoistCloseTaskAction]\n\nexport const TodoistConnector = defineConnector({\n id: todoistConnectorId,\n description: 'Todoist task connector actions.',\n actions: todoistActions\n})\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,96 @@
1
+ {
2
+ "name": "@yolk-sdk/connectors",
3
+ "version": "0.0.1-canary.0",
4
+ "description": "Effect-native connector, integration, credential, and action primitives for Yolk hosts.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/magoz/yolk-sdk.git",
11
+ "directory": "packages/connectors"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/magoz/yolk-sdk/issues"
15
+ },
16
+ "homepage": "https://github.com/magoz/yolk-sdk#readme",
17
+ "keywords": [
18
+ "connectors",
19
+ "integrations",
20
+ "agents",
21
+ "tools",
22
+ "effect"
23
+ ],
24
+ "engines": {
25
+ "node": ">=22"
26
+ },
27
+ "exports": {
28
+ "./package.json": "./package.json",
29
+ ".": {
30
+ "types": "./dist/index.d.mts",
31
+ "import": "./dist/index.mjs",
32
+ "default": "./dist/index.mjs"
33
+ },
34
+ "./agent": {
35
+ "types": "./dist/agent.d.mts",
36
+ "import": "./dist/agent.mjs",
37
+ "default": "./dist/agent.mjs"
38
+ },
39
+ "./figma": {
40
+ "types": "./dist/figma/index.d.mts",
41
+ "import": "./dist/figma/index.mjs",
42
+ "default": "./dist/figma/index.mjs"
43
+ },
44
+ "./google": {
45
+ "types": "./dist/google/index.d.mts",
46
+ "import": "./dist/google/index.mjs",
47
+ "default": "./dist/google/index.mjs"
48
+ },
49
+ "./linkedin-search": {
50
+ "types": "./dist/linkedin-search/index.d.mts",
51
+ "import": "./dist/linkedin-search/index.mjs",
52
+ "default": "./dist/linkedin-search/index.mjs"
53
+ },
54
+ "./notion": {
55
+ "types": "./dist/notion/index.d.mts",
56
+ "import": "./dist/notion/index.mjs",
57
+ "default": "./dist/notion/index.mjs"
58
+ },
59
+ "./r2-storage": {
60
+ "types": "./dist/r2-storage/index.d.mts",
61
+ "import": "./dist/r2-storage/index.mjs",
62
+ "default": "./dist/r2-storage/index.mjs"
63
+ },
64
+ "./telegram": {
65
+ "types": "./dist/telegram/index.d.mts",
66
+ "import": "./dist/telegram/index.mjs",
67
+ "default": "./dist/telegram/index.mjs"
68
+ },
69
+ "./todoist": {
70
+ "types": "./dist/todoist/index.d.mts",
71
+ "import": "./dist/todoist/index.mjs",
72
+ "default": "./dist/todoist/index.mjs"
73
+ }
74
+ },
75
+ "files": [
76
+ "src/**/*.ts",
77
+ "!src/**/*.test.ts",
78
+ "!src/**/*.test.tsx",
79
+ "dist/**/*",
80
+ "README.md"
81
+ ],
82
+ "publishConfig": {
83
+ "access": "public",
84
+ "provenance": true
85
+ },
86
+ "dependencies": {
87
+ "effect": "4.0.0-beta.65",
88
+ "@yolk-sdk/agent": "^0.0.1-canary.0"
89
+ },
90
+ "scripts": {
91
+ "build": "tsdown",
92
+ "check": "tsc -p tsconfig.json --noEmit",
93
+ "test": "vitest run --passWithNoTests",
94
+ "test:run": "vitest run --passWithNoTests"
95
+ }
96
+ }
package/src/action.ts ADDED
@@ -0,0 +1,75 @@
1
+ import { Effect } from 'effect'
2
+ import * as Schema from 'effect/Schema'
3
+ import { ConnectorError } from './error.ts'
4
+ import type { ActionResult } from './result.ts'
5
+ import type { ConnectorIntegration } from './integration.ts'
6
+
7
+ type ActionInputSchema = Schema.Schema<unknown> & { readonly DecodingServices: never }
8
+ type ActionOutputSchema = Schema.Schema<unknown>
9
+
10
+ export type ActionExecutionInput<Input> = {
11
+ readonly integration: ConnectorIntegration
12
+ readonly input: Input
13
+ }
14
+
15
+ export type UnknownActionExecutionInput = {
16
+ readonly integration: ConnectorIntegration
17
+ readonly input: unknown
18
+ }
19
+
20
+ export type ConnectorAction<Env = never, Error = never> = {
21
+ readonly id: string
22
+ readonly description?: string
23
+ readonly inputSchema: ActionInputSchema
24
+ readonly outputSchema: ActionOutputSchema
25
+ readonly execute: (
26
+ input: UnknownActionExecutionInput
27
+ ) => Effect.Effect<ActionResult<unknown>, Error | ConnectorError, Env>
28
+ }
29
+
30
+ export type DefineActionOptions<
31
+ InputSchema extends ActionInputSchema,
32
+ Output,
33
+ Env,
34
+ Error
35
+ > = {
36
+ readonly id: string
37
+ readonly description?: string
38
+ readonly inputSchema: InputSchema
39
+ readonly outputSchema: Schema.Schema<Output>
40
+ readonly execute: (
41
+ input: ActionExecutionInput<InputSchema['Type']>
42
+ ) => Effect.Effect<ActionResult<Output>, Error | ConnectorError, Env>
43
+ }
44
+
45
+ const validationError = (actionId: string, error: unknown) =>
46
+ new ConnectorError({
47
+ cause: 'validation_failed',
48
+ message: `Invalid input for action: ${actionId}`,
49
+ actionId,
50
+ underlying: error
51
+ })
52
+
53
+ export const defineAction = <
54
+ InputSchema extends ActionInputSchema,
55
+ Output,
56
+ Env = never,
57
+ Error = never
58
+ >(
59
+ options: DefineActionOptions<InputSchema, Output, Env, Error>
60
+ ): ConnectorAction<Env, Error> => ({
61
+ id: options.id,
62
+ description: options.description,
63
+ inputSchema: options.inputSchema,
64
+ outputSchema: options.outputSchema,
65
+ execute: input =>
66
+ Schema.decodeUnknownEffect(options.inputSchema)(input.input).pipe(
67
+ Effect.mapError(error => validationError(options.id, error)),
68
+ Effect.flatMap(params =>
69
+ options.execute({
70
+ integration: input.integration,
71
+ input: params
72
+ })
73
+ )
74
+ )
75
+ })
package/src/agent.ts ADDED
@@ -0,0 +1,120 @@
1
+ import { Effect } from 'effect'
2
+ import type { Layer } from 'effect'
3
+ import * as Schema from 'effect/Schema'
4
+ import { ToolError } from '@yolk-sdk/agent/loop'
5
+ import { makeTool, type ToolAccess, type ToolModule, type ToolRegistration } from '@yolk-sdk/agent/tools'
6
+ import { ToolResult } from '@yolk-sdk/agent/protocol'
7
+ import type { Connector } from './connector.ts'
8
+ import type { ConnectorIntegration } from './integration.ts'
9
+ import type { ProviderFailure } from './result.ts'
10
+
11
+ export type ConnectorIntegrationResolver<Context> =
12
+ | ConnectorIntegration
13
+ | ((context: Context) => Effect.Effect<ConnectorIntegration, ToolError>)
14
+
15
+ export type ConnectorToolAccessResolver = ToolAccess | ((actionId: string) => ToolAccess)
16
+
17
+ export type MakeConnectorToolModuleOptions<Context, Env> = {
18
+ readonly integration: ConnectorIntegrationResolver<Context>
19
+ readonly layer: Layer.Layer<Env>
20
+ readonly moduleId?: string
21
+ readonly namePrefix?: string
22
+ readonly access?: ConnectorToolAccessResolver
23
+ }
24
+
25
+ const resolveIntegration = <Context>(resolver: ConnectorIntegrationResolver<Context>, context: Context) => {
26
+ if (typeof resolver === 'function') {
27
+ return resolver(context)
28
+ }
29
+
30
+ return Effect.succeed(resolver)
31
+ }
32
+
33
+ const resolveAccess = (resolver: ConnectorToolAccessResolver | undefined, actionId: string): ToolAccess => {
34
+ if (typeof resolver === 'function') {
35
+ return resolver(actionId)
36
+ }
37
+
38
+ return resolver ?? 'read'
39
+ }
40
+
41
+ const unknownToMessage = (error: unknown) => {
42
+ if (error instanceof Error) {
43
+ return error.message
44
+ }
45
+
46
+ return String(error)
47
+ }
48
+
49
+ const failureContent = (failure: ProviderFailure) => `${failure.code}: ${failure.message}`
50
+
51
+ const successContent = (value: unknown) => {
52
+ if (typeof value === 'string') {
53
+ return value
54
+ }
55
+
56
+ return JSON.stringify(value)
57
+ }
58
+
59
+ const toolName = (prefix: string | undefined, actionId: string) =>
60
+ prefix === undefined ? actionId : `${prefix}.${actionId}`
61
+
62
+ export const makeConnectorToolRegistration = <Context, Env = never, Error = never>(
63
+ connector: Connector<Env, Error>,
64
+ actionId: string,
65
+ options: MakeConnectorToolModuleOptions<Context, Env>
66
+ ): ToolRegistration<Context> => {
67
+ const action = connector.actions.find(item => item.id === actionId)
68
+ const name = toolName(options.namePrefix, actionId)
69
+
70
+ return makeTool({
71
+ name,
72
+ description: action?.description ?? `Invoke connector action ${actionId}.`,
73
+ parameters: action?.inputSchema ?? Schema.Unknown,
74
+ access: resolveAccess(options.access, actionId),
75
+ invalidParamsMessage: error => `Invalid ${name} arguments: ${unknownToMessage(error)}`,
76
+ execute: ({ call, context, params }) =>
77
+ resolveIntegration(options.integration, context).pipe(
78
+ Effect.flatMap(integration =>
79
+ connector.invoke({
80
+ integration,
81
+ action: actionId,
82
+ input: params
83
+ }).pipe(Effect.provide(options.layer))
84
+ ),
85
+ Effect.map(result => {
86
+ switch (result._tag) {
87
+ case 'Success':
88
+ return ToolResult.make({
89
+ toolCallId: call.id,
90
+ content: successContent(result.value),
91
+ structuredContent: result.value
92
+ })
93
+ case 'Failure':
94
+ return ToolResult.make({
95
+ toolCallId: call.id,
96
+ content: failureContent(result.error),
97
+ isError: true,
98
+ structuredContent: result.error
99
+ })
100
+ }
101
+ }),
102
+ Effect.mapError(
103
+ error =>
104
+ new ToolError({
105
+ tool: name,
106
+ message: unknownToMessage(error),
107
+ cause: 'execution'
108
+ })
109
+ )
110
+ )
111
+ })
112
+ }
113
+
114
+ export const makeConnectorToolModule = <Context, Env = never, Error = never>(
115
+ connector: Connector<Env, Error>,
116
+ options: MakeConnectorToolModuleOptions<Context, Env>
117
+ ): ToolModule<Context> => ({
118
+ id: options.moduleId ?? connector.id,
119
+ tools: connector.actions.map(action => makeConnectorToolRegistration(connector, action.id, options))
120
+ })
package/src/config.ts ADDED
@@ -0,0 +1,28 @@
1
+ import { Effect } from 'effect'
2
+ import { ConnectorError } from './error.ts'
3
+ import type { ConnectorIntegration } from './integration.ts'
4
+
5
+ const configValue = (integration: ConnectorIntegration, key: string) =>
6
+ Object.getOwnPropertyDescriptor(integration.config, key)?.value
7
+
8
+ export const requiredStringConfig = (integration: ConnectorIntegration, key: string) => {
9
+ const value = configValue(integration, key)
10
+
11
+ if (typeof value === 'string' && value.trim() !== '') {
12
+ return Effect.succeed(value)
13
+ }
14
+
15
+ return Effect.fail(
16
+ new ConnectorError({
17
+ cause: 'validation_failed',
18
+ message: `Missing integration config: ${key}`,
19
+ connectorId: integration.connectorId
20
+ })
21
+ )
22
+ }
23
+
24
+ export const optionalStringConfig = (integration: ConnectorIntegration, key: string) => {
25
+ const value = configValue(integration, key)
26
+
27
+ return typeof value === 'string' && value.trim() !== '' ? value : undefined
28
+ }