@dobby.ai/dobby 0.1.1 → 0.1.2

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 (136) hide show
  1. package/README.md +20 -7
  2. package/dist/src/agent/event-forwarder.js +185 -16
  3. package/dist/src/cli/commands/cron.js +39 -35
  4. package/dist/src/cli/program.js +0 -6
  5. package/dist/src/core/types.js +2 -0
  6. package/dist/src/cron/config.js +2 -2
  7. package/dist/src/cron/service.js +87 -23
  8. package/dist/src/cron/store.js +1 -1
  9. package/package.json +9 -3
  10. package/.env.example +0 -8
  11. package/AGENTS.md +0 -267
  12. package/ROADMAP.md +0 -34
  13. package/config/cron.example.json +0 -9
  14. package/config/gateway.example.json +0 -132
  15. package/dist/plugins/connector-discord/src/mapper.js +0 -75
  16. package/dist/src/cli/tests/config-command.test.js +0 -42
  17. package/dist/src/cli/tests/config-io.test.js +0 -64
  18. package/dist/src/cli/tests/config-mutators.test.js +0 -47
  19. package/dist/src/cli/tests/discord-mapper.test.js +0 -90
  20. package/dist/src/cli/tests/doctor.test.js +0 -252
  21. package/dist/src/cli/tests/init-catalog.test.js +0 -134
  22. package/dist/src/cli/tests/program-options.test.js +0 -78
  23. package/dist/src/cli/tests/routing-config.test.js +0 -254
  24. package/dist/src/core/tests/control-command.test.js +0 -17
  25. package/dist/src/core/tests/runtime-registry.test.js +0 -116
  26. package/dist/src/core/tests/typing-controller.test.js +0 -103
  27. package/docs/BOXLITE_SANDBOX_FEASIBILITY.md +0 -175
  28. package/docs/CRON_SCHEDULER_DESIGN.md +0 -374
  29. package/docs/DOCKER_SANDBOX_vs_BOXLITE.md +0 -77
  30. package/docs/EXTENSION_SYSTEM_ARCHITECTURE.md +0 -119
  31. package/docs/MVP.md +0 -135
  32. package/docs/RUNBOOK.md +0 -243
  33. package/docs/TEAMWORK_HANDOFF_DESIGN.md +0 -440
  34. package/plugins/connector-discord/dobby.manifest.json +0 -18
  35. package/plugins/connector-discord/index.js +0 -1
  36. package/plugins/connector-discord/package-lock.json +0 -360
  37. package/plugins/connector-discord/package.json +0 -38
  38. package/plugins/connector-discord/src/connector.ts +0 -345
  39. package/plugins/connector-discord/src/contribution.ts +0 -21
  40. package/plugins/connector-discord/src/mapper.ts +0 -101
  41. package/plugins/connector-discord/tsconfig.json +0 -19
  42. package/plugins/connector-feishu/dobby.manifest.json +0 -18
  43. package/plugins/connector-feishu/index.js +0 -1
  44. package/plugins/connector-feishu/package-lock.json +0 -618
  45. package/plugins/connector-feishu/package.json +0 -38
  46. package/plugins/connector-feishu/src/connector.ts +0 -343
  47. package/plugins/connector-feishu/src/contribution.ts +0 -26
  48. package/plugins/connector-feishu/src/mapper.ts +0 -401
  49. package/plugins/connector-feishu/tsconfig.json +0 -19
  50. package/plugins/plugin-sdk/index.d.ts +0 -261
  51. package/plugins/plugin-sdk/index.js +0 -1
  52. package/plugins/plugin-sdk/package-lock.json +0 -12
  53. package/plugins/plugin-sdk/package.json +0 -22
  54. package/plugins/provider-claude/dobby.manifest.json +0 -17
  55. package/plugins/provider-claude/index.js +0 -1
  56. package/plugins/provider-claude/package-lock.json +0 -3398
  57. package/plugins/provider-claude/package.json +0 -39
  58. package/plugins/provider-claude/src/contribution.ts +0 -1018
  59. package/plugins/provider-claude/tsconfig.json +0 -19
  60. package/plugins/provider-claude-cli/dobby.manifest.json +0 -17
  61. package/plugins/provider-claude-cli/index.js +0 -1
  62. package/plugins/provider-claude-cli/package-lock.json +0 -2898
  63. package/plugins/provider-claude-cli/package.json +0 -38
  64. package/plugins/provider-claude-cli/src/contribution.ts +0 -1673
  65. package/plugins/provider-claude-cli/tsconfig.json +0 -19
  66. package/plugins/provider-pi/dobby.manifest.json +0 -17
  67. package/plugins/provider-pi/index.js +0 -1
  68. package/plugins/provider-pi/package-lock.json +0 -3877
  69. package/plugins/provider-pi/package.json +0 -40
  70. package/plugins/provider-pi/src/contribution.ts +0 -606
  71. package/plugins/provider-pi/tsconfig.json +0 -19
  72. package/plugins/sandbox-core/boxlite.js +0 -1
  73. package/plugins/sandbox-core/dobby.manifest.json +0 -17
  74. package/plugins/sandbox-core/docker.js +0 -1
  75. package/plugins/sandbox-core/package-lock.json +0 -136
  76. package/plugins/sandbox-core/package.json +0 -39
  77. package/plugins/sandbox-core/src/boxlite-context.ts +0 -2
  78. package/plugins/sandbox-core/src/boxlite-contribution.ts +0 -53
  79. package/plugins/sandbox-core/src/boxlite-executor.ts +0 -911
  80. package/plugins/sandbox-core/src/docker-contribution.ts +0 -43
  81. package/plugins/sandbox-core/src/docker-executor.ts +0 -217
  82. package/plugins/sandbox-core/tsconfig.json +0 -19
  83. package/scripts/local-extensions.mjs +0 -168
  84. package/src/agent/event-forwarder.ts +0 -414
  85. package/src/cli/commands/config.ts +0 -328
  86. package/src/cli/commands/configure.ts +0 -92
  87. package/src/cli/commands/cron.ts +0 -410
  88. package/src/cli/commands/doctor.ts +0 -331
  89. package/src/cli/commands/extension.ts +0 -207
  90. package/src/cli/commands/init.ts +0 -211
  91. package/src/cli/commands/start.ts +0 -223
  92. package/src/cli/commands/topology.ts +0 -415
  93. package/src/cli/index.ts +0 -9
  94. package/src/cli/program.ts +0 -314
  95. package/src/cli/shared/config-io.ts +0 -245
  96. package/src/cli/shared/config-mutators.ts +0 -470
  97. package/src/cli/shared/config-schema.ts +0 -228
  98. package/src/cli/shared/config-types.ts +0 -129
  99. package/src/cli/shared/configure-sections.ts +0 -595
  100. package/src/cli/shared/discord-config.ts +0 -14
  101. package/src/cli/shared/init-catalog.ts +0 -249
  102. package/src/cli/shared/local-extension-specs.ts +0 -108
  103. package/src/cli/shared/runtime.ts +0 -33
  104. package/src/cli/shared/schema-prompts.ts +0 -443
  105. package/src/cli/tests/config-command.test.ts +0 -56
  106. package/src/cli/tests/config-io.test.ts +0 -92
  107. package/src/cli/tests/config-mutators.test.ts +0 -59
  108. package/src/cli/tests/discord-mapper.test.ts +0 -128
  109. package/src/cli/tests/doctor.test.ts +0 -269
  110. package/src/cli/tests/init-catalog.test.ts +0 -144
  111. package/src/cli/tests/program-options.test.ts +0 -95
  112. package/src/cli/tests/routing-config.test.ts +0 -281
  113. package/src/core/control-command.ts +0 -12
  114. package/src/core/dedup-store.ts +0 -103
  115. package/src/core/gateway.ts +0 -609
  116. package/src/core/routing.ts +0 -404
  117. package/src/core/runtime-registry.ts +0 -141
  118. package/src/core/tests/control-command.test.ts +0 -20
  119. package/src/core/tests/runtime-registry.test.ts +0 -140
  120. package/src/core/tests/typing-controller.test.ts +0 -129
  121. package/src/core/types.ts +0 -324
  122. package/src/core/typing-controller.ts +0 -119
  123. package/src/cron/config.ts +0 -154
  124. package/src/cron/schedule.ts +0 -61
  125. package/src/cron/service.ts +0 -249
  126. package/src/cron/store.ts +0 -155
  127. package/src/cron/types.ts +0 -60
  128. package/src/extension/loader.ts +0 -145
  129. package/src/extension/manager.ts +0 -355
  130. package/src/extension/manifest.ts +0 -26
  131. package/src/extension/registry.ts +0 -229
  132. package/src/main.ts +0 -8
  133. package/src/sandbox/executor.ts +0 -44
  134. package/src/sandbox/host-executor.ts +0 -118
  135. package/src/shared/dobby-repo.ts +0 -48
  136. package/tsconfig.json +0 -18
@@ -1,343 +0,0 @@
1
- import { randomUUID } from "node:crypto";
2
- import * as Lark from "@larksuiteoapi/node-sdk";
3
- import type {
4
- ConnectorCapabilities,
5
- ConnectorContext,
6
- ConnectorPlugin,
7
- ConnectorSendResult,
8
- GatewayLogger,
9
- OutboundEnvelope,
10
- } from "@dobby.ai/plugin-sdk";
11
- import { mapFeishuMessageEvent, type FeishuMessageEvent } from "./mapper.js";
12
-
13
- export interface FeishuConnectorConfig {
14
- appId: string;
15
- appSecret: string;
16
- domain?: "feishu" | "lark";
17
- botName?: string;
18
- botOpenId?: string;
19
- messageFormat?: "text" | "card_markdown";
20
- replyMode?: "direct" | "reply";
21
- cardTitle?: string;
22
- downloadAttachments?: boolean;
23
- }
24
-
25
- const FEISHU_CARD_MAX_TEXT_LENGTH = 8_000;
26
- const FEISHU_TEXT_MAX_TEXT_LENGTH = 12_000;
27
-
28
- function resolveDomain(domain?: "feishu" | "lark"): string {
29
- return domain === "lark" ? "https://open.larksuite.com" : "https://open.feishu.cn";
30
- }
31
-
32
- function textContent(text: string): string {
33
- return JSON.stringify({ text });
34
- }
35
-
36
- function cardContent(text: string, title: string): string {
37
- return JSON.stringify({
38
- schema: "2.0",
39
- config: {
40
- wide_screen_mode: true,
41
- update_multi: true,
42
- },
43
- header: {
44
- template: "blue",
45
- title: {
46
- tag: "plain_text",
47
- content: title,
48
- },
49
- },
50
- body: {
51
- direction: "vertical",
52
- padding: "12px 12px 12px 12px",
53
- elements: [
54
- {
55
- tag: "markdown",
56
- content: text.trim().length > 0 ? text : "(empty response)",
57
- },
58
- ],
59
- },
60
- });
61
- }
62
-
63
- function toSendResult(messageId?: string): ConnectorSendResult {
64
- return messageId ? { messageId } : {};
65
- }
66
-
67
- export class FeishuConnector implements ConnectorPlugin {
68
- readonly id: string;
69
- readonly platform = "feishu" as const;
70
- readonly name = "feishu";
71
- readonly capabilities: ConnectorCapabilities;
72
-
73
- private ctx: ConnectorContext | null = null;
74
- private client: Lark.Client | null = null;
75
- private wsClient: Lark.WSClient | null = null;
76
-
77
- constructor(
78
- id: string,
79
- private readonly config: FeishuConnectorConfig,
80
- private readonly attachmentsRoot: string,
81
- private readonly logger: GatewayLogger,
82
- ) {
83
- this.id = id;
84
- this.capabilities = {
85
- updateStrategy: this.messageFormat === "card_markdown" ? "final_only" : "edit",
86
- supportedSources: ["chat"],
87
- supportsThread: this.replyMode === "reply",
88
- supportsTyping: false,
89
- supportsFileUpload: false,
90
- maxTextLength: this.messageFormat === "card_markdown" ? FEISHU_CARD_MAX_TEXT_LENGTH : FEISHU_TEXT_MAX_TEXT_LENGTH,
91
- };
92
- }
93
-
94
- async start(ctx: ConnectorContext): Promise<void> {
95
- if (this.wsClient) {
96
- this.logger.warn({ connectorId: this.id }, "Feishu connector start called while already started");
97
- return;
98
- }
99
-
100
- const baseConfig = {
101
- appId: this.config.appId,
102
- appSecret: this.config.appSecret,
103
- domain: resolveDomain(this.config.domain),
104
- };
105
-
106
- this.ctx = ctx;
107
- this.client = new Lark.Client(baseConfig);
108
- this.wsClient = new Lark.WSClient(baseConfig);
109
- await this.logAppSubscriptionState();
110
-
111
- const dispatcher = new Lark.EventDispatcher({}).register({
112
- "im.message.receive_v1": async (event: FeishuMessageEvent) => {
113
- if (!this.ctx || !this.client) {
114
- return;
115
- }
116
-
117
- this.logger.info(
118
- {
119
- connectorId: this.id,
120
- chatId: event.message.chat_id,
121
- messageId: event.message.message_id,
122
- chatType: event.message.chat_type,
123
- messageType: event.message.message_type,
124
- mentionCount: event.message.mentions?.length ?? 0,
125
- },
126
- "Feishu inbound event received",
127
- );
128
-
129
- const inbound = await mapFeishuMessageEvent({
130
- event,
131
- connectorId: this.id,
132
- attachmentsRoot: this.attachmentsRoot,
133
- client: this.client,
134
- logger: this.logger,
135
- downloadAttachments: this.config.downloadAttachments !== false,
136
- ...(this.config.botOpenId ? { botOpenId: this.config.botOpenId } : {}),
137
- ...(this.config.botName ? { botName: this.config.botName } : {}),
138
- });
139
- if (!inbound) {
140
- return;
141
- }
142
-
143
- this.logger.info(
144
- {
145
- connectorId: this.id,
146
- chatId: inbound.chatId,
147
- messageId: inbound.messageId,
148
- isDirectMessage: inbound.isDirectMessage,
149
- mentionedBot: inbound.mentionedBot,
150
- textLength: inbound.text.length,
151
- attachmentCount: inbound.attachments.length,
152
- },
153
- "Feishu inbound event mapped",
154
- );
155
-
156
- await this.ctx.emitInbound(inbound);
157
- },
158
- });
159
-
160
- await this.wsClient.start({
161
- eventDispatcher: dispatcher,
162
- });
163
-
164
- this.logger.info(
165
- {
166
- connectorId: this.id,
167
- domain: this.config.domain ?? "feishu",
168
- messageFormat: this.messageFormat,
169
- replyMode: this.replyMode,
170
- },
171
- "Feishu connector ready",
172
- );
173
- }
174
-
175
- async send(message: OutboundEnvelope): Promise<ConnectorSendResult> {
176
- if (!this.client) {
177
- throw new Error("Feishu connector is not started");
178
- }
179
-
180
- if (message.attachments && message.attachments.length > 0) {
181
- this.logger.warn(
182
- {
183
- connectorId: this.id,
184
- chatId: message.chatId,
185
- attachmentCount: message.attachments.length,
186
- },
187
- "Outbound Feishu attachments are not supported yet; sending text only",
188
- );
189
- }
190
-
191
- if (message.mode === "update") {
192
- if (!message.targetMessageId) {
193
- throw new Error("targetMessageId is required for update mode");
194
- }
195
-
196
- if (this.messageFormat === "card_markdown") {
197
- await this.client.im.v1.message.patch({
198
- path: {
199
- message_id: message.targetMessageId,
200
- },
201
- data: {
202
- content: this.renderContent(message.text),
203
- },
204
- });
205
- return { messageId: message.targetMessageId };
206
- }
207
-
208
- const response = await this.client.im.v1.message.update({
209
- path: {
210
- message_id: message.targetMessageId,
211
- },
212
- data: {
213
- msg_type: "text",
214
- content: this.renderContent(message.text),
215
- },
216
- });
217
- return { messageId: response.data?.message_id ?? message.targetMessageId };
218
- }
219
-
220
- if (this.replyMode === "reply" && message.replyToMessageId) {
221
- const response = await this.client.im.v1.message.reply({
222
- path: {
223
- message_id: message.replyToMessageId,
224
- },
225
- data: {
226
- msg_type: this.renderMessageType(),
227
- content: this.renderContent(message.text),
228
- reply_in_thread: Boolean(message.threadId),
229
- uuid: randomUUID(),
230
- },
231
- });
232
- return toSendResult(response.data?.message_id);
233
- }
234
-
235
- if (this.replyMode === "reply" && message.threadId) {
236
- const response = await this.client.im.v1.message.reply({
237
- path: {
238
- message_id: message.threadId,
239
- },
240
- data: {
241
- msg_type: this.renderMessageType(),
242
- content: this.renderContent(message.text),
243
- reply_in_thread: true,
244
- uuid: randomUUID(),
245
- },
246
- });
247
- return toSendResult(response.data?.message_id);
248
- }
249
-
250
- const response = await this.client.im.v1.message.create({
251
- params: {
252
- receive_id_type: "chat_id",
253
- },
254
- data: {
255
- receive_id: message.chatId,
256
- msg_type: this.renderMessageType(),
257
- content: this.renderContent(message.text),
258
- uuid: randomUUID(),
259
- },
260
- });
261
- return toSendResult(response.data?.message_id);
262
- }
263
-
264
- async stop(): Promise<void> {
265
- const wsClient = this.wsClient;
266
- this.wsClient = null;
267
- this.client = null;
268
- this.ctx = null;
269
- wsClient?.close({ force: true });
270
- }
271
-
272
- private async logAppSubscriptionState(): Promise<void> {
273
- if (!this.client) {
274
- return;
275
- }
276
-
277
- try {
278
- const response = await this.client.application.v6.application.get({
279
- path: {
280
- app_id: this.config.appId,
281
- },
282
- params: {
283
- lang: "zh_cn",
284
- },
285
- });
286
-
287
- const subscribedEvents = response.data?.app?.event?.subscribed_events ?? [];
288
- this.logger.info(
289
- {
290
- connectorId: this.id,
291
- appId: this.config.appId,
292
- appName: response.data?.app?.app_name ?? this.config.botName ?? null,
293
- onlineVersionId: response.data?.app?.online_version_id ?? null,
294
- draftVersionId: response.data?.app?.unaudit_version_id ?? null,
295
- subscriptionType: response.data?.app?.event?.subscription_type ?? null,
296
- subscribedEvents,
297
- },
298
- "Feishu published application info loaded",
299
- );
300
-
301
- if (!subscribedEvents.includes("im.message.receive_v1")) {
302
- this.logger.warn(
303
- {
304
- connectorId: this.id,
305
- appId: this.config.appId,
306
- onlineVersionId: response.data?.app?.online_version_id ?? null,
307
- draftVersionId: response.data?.app?.unaudit_version_id ?? null,
308
- subscribedEvents,
309
- },
310
- "Published Feishu app config does not show im.message.receive_v1",
311
- );
312
- }
313
- } catch (error) {
314
- this.logger.warn(
315
- {
316
- err: error,
317
- connectorId: this.id,
318
- appId: this.config.appId,
319
- },
320
- "Failed to load Feishu application info",
321
- );
322
- }
323
- }
324
-
325
- private get messageFormat(): "text" | "card_markdown" {
326
- return this.config.messageFormat ?? "card_markdown";
327
- }
328
-
329
- private get replyMode(): "direct" | "reply" {
330
- return this.config.replyMode ?? "direct";
331
- }
332
-
333
- private renderMessageType(): "text" | "interactive" {
334
- return this.messageFormat === "card_markdown" ? "interactive" : "text";
335
- }
336
-
337
- private renderContent(text: string): string {
338
- if (this.messageFormat === "card_markdown") {
339
- return cardContent(text, this.config.cardTitle ?? this.config.botName ?? "dobby");
340
- }
341
- return textContent(text);
342
- }
343
- }
@@ -1,26 +0,0 @@
1
- import { z } from "zod";
2
- import type { ConnectorContributionModule } from "@dobby.ai/plugin-sdk";
3
- import { FeishuConnector, type FeishuConnectorConfig } from "./connector.js";
4
-
5
- const feishuConnectorConfigSchema = z.object({
6
- appId: z.string().min(1),
7
- appSecret: z.string().min(1),
8
- domain: z.enum(["feishu", "lark"]).default("feishu"),
9
- botName: z.string().min(1).optional(),
10
- botOpenId: z.string().min(1).optional(),
11
- messageFormat: z.enum(["text", "card_markdown"]).default("card_markdown"),
12
- replyMode: z.enum(["direct", "reply"]).default("direct"),
13
- cardTitle: z.string().min(1).optional(),
14
- downloadAttachments: z.boolean().default(true),
15
- });
16
-
17
- export const connectorFeishuContribution: ConnectorContributionModule = {
18
- kind: "connector",
19
- configSchema: z.toJSONSchema(feishuConnectorConfigSchema),
20
- createInstance(options) {
21
- const config = feishuConnectorConfigSchema.parse(options.config) as FeishuConnectorConfig;
22
- return new FeishuConnector(options.instanceId, config, options.attachmentsRoot, options.host.logger);
23
- },
24
- };
25
-
26
- export default connectorFeishuContribution;