opencode-lark 0.1.1

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 (138) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/LICENSE +21 -0
  3. package/README.md +322 -0
  4. package/README.zh-CN.md +324 -0
  5. package/bin/opencode-lark.js +2 -0
  6. package/dist/channel/base-plugin.d.ts +31 -0
  7. package/dist/channel/base-plugin.d.ts.map +1 -0
  8. package/dist/channel/base-plugin.js +42 -0
  9. package/dist/channel/base-plugin.js.map +1 -0
  10. package/dist/channel/feishu/feishu-plugin.d.ts +36 -0
  11. package/dist/channel/feishu/feishu-plugin.d.ts.map +1 -0
  12. package/dist/channel/feishu/feishu-plugin.js +149 -0
  13. package/dist/channel/feishu/feishu-plugin.js.map +1 -0
  14. package/dist/channel/feishu/index.d.ts +2 -0
  15. package/dist/channel/feishu/index.d.ts.map +1 -0
  16. package/dist/channel/feishu/index.js +2 -0
  17. package/dist/channel/feishu/index.js.map +1 -0
  18. package/dist/channel/index.d.ts +4 -0
  19. package/dist/channel/index.d.ts.map +1 -0
  20. package/dist/channel/index.js +4 -0
  21. package/dist/channel/index.js.map +1 -0
  22. package/dist/channel/manager.d.ts +37 -0
  23. package/dist/channel/manager.d.ts.map +1 -0
  24. package/dist/channel/manager.js +68 -0
  25. package/dist/channel/manager.js.map +1 -0
  26. package/dist/channel/mock/mock-plugin.d.ts +24 -0
  27. package/dist/channel/mock/mock-plugin.d.ts.map +1 -0
  28. package/dist/channel/mock/mock-plugin.js +42 -0
  29. package/dist/channel/mock/mock-plugin.js.map +1 -0
  30. package/dist/channel/types.d.ts +226 -0
  31. package/dist/channel/types.d.ts.map +1 -0
  32. package/dist/channel/types.js +7 -0
  33. package/dist/channel/types.js.map +1 -0
  34. package/dist/cron/cron-service.d.ts +40 -0
  35. package/dist/cron/cron-service.d.ts.map +1 -0
  36. package/dist/cron/cron-service.js +140 -0
  37. package/dist/cron/cron-service.js.map +1 -0
  38. package/dist/cron/heartbeat.d.ts +30 -0
  39. package/dist/cron/heartbeat.d.ts.map +1 -0
  40. package/dist/cron/heartbeat.js +76 -0
  41. package/dist/cron/heartbeat.js.map +1 -0
  42. package/dist/feishu/api-client.d.ts +19 -0
  43. package/dist/feishu/api-client.d.ts.map +1 -0
  44. package/dist/feishu/api-client.js +98 -0
  45. package/dist/feishu/api-client.js.map +1 -0
  46. package/dist/feishu/card-builder.d.ts +10 -0
  47. package/dist/feishu/card-builder.d.ts.map +1 -0
  48. package/dist/feishu/card-builder.js +74 -0
  49. package/dist/feishu/card-builder.js.map +1 -0
  50. package/dist/feishu/cardkit-client.d.ts +48 -0
  51. package/dist/feishu/cardkit-client.d.ts.map +1 -0
  52. package/dist/feishu/cardkit-client.js +97 -0
  53. package/dist/feishu/cardkit-client.js.map +1 -0
  54. package/dist/feishu/message-dedup.d.ts +28 -0
  55. package/dist/feishu/message-dedup.d.ts.map +1 -0
  56. package/dist/feishu/message-dedup.js +58 -0
  57. package/dist/feishu/message-dedup.js.map +1 -0
  58. package/dist/feishu/webhook-server.d.ts +20 -0
  59. package/dist/feishu/webhook-server.d.ts.map +1 -0
  60. package/dist/feishu/webhook-server.js +111 -0
  61. package/dist/feishu/webhook-server.js.map +1 -0
  62. package/dist/feishu/ws-client.d.ts +17 -0
  63. package/dist/feishu/ws-client.d.ts.map +1 -0
  64. package/dist/feishu/ws-client.js +158 -0
  65. package/dist/feishu/ws-client.js.map +1 -0
  66. package/dist/handler/interactive-handler.d.ts +16 -0
  67. package/dist/handler/interactive-handler.d.ts.map +1 -0
  68. package/dist/handler/interactive-handler.js +86 -0
  69. package/dist/handler/interactive-handler.js.map +1 -0
  70. package/dist/handler/interactive-poller.d.ts +16 -0
  71. package/dist/handler/interactive-poller.d.ts.map +1 -0
  72. package/dist/handler/interactive-poller.js +147 -0
  73. package/dist/handler/interactive-poller.js.map +1 -0
  74. package/dist/handler/message-handler.d.ts +34 -0
  75. package/dist/handler/message-handler.d.ts.map +1 -0
  76. package/dist/handler/message-handler.js +305 -0
  77. package/dist/handler/message-handler.js.map +1 -0
  78. package/dist/handler/streaming-integration.d.ts +21 -0
  79. package/dist/handler/streaming-integration.d.ts.map +1 -0
  80. package/dist/handler/streaming-integration.js +325 -0
  81. package/dist/handler/streaming-integration.js.map +1 -0
  82. package/dist/index.d.ts +16 -0
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +281 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/memory/memory-manager.d.ts +16 -0
  87. package/dist/memory/memory-manager.d.ts.map +1 -0
  88. package/dist/memory/memory-manager.js +58 -0
  89. package/dist/memory/memory-manager.js.map +1 -0
  90. package/dist/session/progress-tracker.d.ts +12 -0
  91. package/dist/session/progress-tracker.d.ts.map +1 -0
  92. package/dist/session/progress-tracker.js +46 -0
  93. package/dist/session/progress-tracker.js.map +1 -0
  94. package/dist/session/session-manager.d.ts +15 -0
  95. package/dist/session/session-manager.d.ts.map +1 -0
  96. package/dist/session/session-manager.js +91 -0
  97. package/dist/session/session-manager.js.map +1 -0
  98. package/dist/streaming/event-processor.d.ts +74 -0
  99. package/dist/streaming/event-processor.d.ts.map +1 -0
  100. package/dist/streaming/event-processor.js +240 -0
  101. package/dist/streaming/event-processor.js.map +1 -0
  102. package/dist/streaming/session-observer.d.ts +19 -0
  103. package/dist/streaming/session-observer.d.ts.map +1 -0
  104. package/dist/streaming/session-observer.js +140 -0
  105. package/dist/streaming/session-observer.js.map +1 -0
  106. package/dist/streaming/streaming-card.d.ts +37 -0
  107. package/dist/streaming/streaming-card.d.ts.map +1 -0
  108. package/dist/streaming/streaming-card.js +139 -0
  109. package/dist/streaming/streaming-card.js.map +1 -0
  110. package/dist/streaming/subagent-card.d.ts +32 -0
  111. package/dist/streaming/subagent-card.d.ts.map +1 -0
  112. package/dist/streaming/subagent-card.js +103 -0
  113. package/dist/streaming/subagent-card.js.map +1 -0
  114. package/dist/streaming/subagent-tracker.d.ts +45 -0
  115. package/dist/streaming/subagent-tracker.d.ts.map +1 -0
  116. package/dist/streaming/subagent-tracker.js +118 -0
  117. package/dist/streaming/subagent-tracker.js.map +1 -0
  118. package/dist/types.d.ts +55 -0
  119. package/dist/types.d.ts.map +1 -0
  120. package/dist/types.js +5 -0
  121. package/dist/types.js.map +1 -0
  122. package/dist/utils/config.d.ts +197 -0
  123. package/dist/utils/config.d.ts.map +1 -0
  124. package/dist/utils/config.js +87 -0
  125. package/dist/utils/config.js.map +1 -0
  126. package/dist/utils/db.d.ts +12 -0
  127. package/dist/utils/db.d.ts.map +1 -0
  128. package/dist/utils/db.js +35 -0
  129. package/dist/utils/db.js.map +1 -0
  130. package/dist/utils/event-listeners.d.ts +12 -0
  131. package/dist/utils/event-listeners.d.ts.map +1 -0
  132. package/dist/utils/event-listeners.js +21 -0
  133. package/dist/utils/event-listeners.js.map +1 -0
  134. package/dist/utils/logger.d.ts +11 -0
  135. package/dist/utils/logger.d.ts.map +1 -0
  136. package/dist/utils/logger.js +38 -0
  137. package/dist/utils/logger.js.map +1 -0
  138. package/package.json +41 -0
@@ -0,0 +1,325 @@
1
+ import { addListener, removeListener } from "../utils/event-listeners.js";
2
+ import { StreamingCardSession } from "../streaming/streaming-card.js";
3
+ // ── Constants ──
4
+ const FIRST_EVENT_TIMEOUT_MS = 15_000;
5
+ // ── Factory ──
6
+ export function createStreamingBridge(deps) {
7
+ const { cardkitClient, feishuClient, subAgentTracker, logger, seenInteractiveIds } = deps;
8
+ return {
9
+ async handleMessage(chatId, sessionId, eventListeners, eventProcessor, sendMessage, onComplete, messageId, reactionId) {
10
+ let card = null;
11
+ let cardStartPromise = null;
12
+ const ensureCard = () => {
13
+ if (card || cardStartPromise)
14
+ return;
15
+ card = new StreamingCardSession({
16
+ cardkitClient,
17
+ feishuClient,
18
+ chatId,
19
+ });
20
+ cardStartPromise = card.start().then(() => {
21
+ logger.info(`Streaming card started for session ${sessionId} in chat ${chatId}`);
22
+ });
23
+ };
24
+ return new Promise((resolve, reject) => {
25
+ let textBuffer = "";
26
+ let gotFirstEvent = false;
27
+ let settled = false;
28
+ let syncResponseBody = "";
29
+ // Helper: send text reply and clean up reaction
30
+ const sendFinalResponse = async (text) => {
31
+ await feishuClient.replyMessage(messageId, {
32
+ msg_type: "text",
33
+ content: JSON.stringify({ text }),
34
+ });
35
+ if (reactionId) {
36
+ try {
37
+ await feishuClient.deleteReaction(messageId, reactionId);
38
+ }
39
+ catch (err) {
40
+ logger.warn(`deleteReaction failed: ${err}`);
41
+ }
42
+ }
43
+ };
44
+ // Named listener reference — stored for removeListener calls
45
+ const myListener = (rawEvent) => {
46
+ const action = eventProcessor.processEvent(rawEvent);
47
+ if (!action)
48
+ return;
49
+ if (action.sessionId !== sessionId)
50
+ return;
51
+ gotFirstEvent = true;
52
+ switch (action.type) {
53
+ case "TextDelta": {
54
+ textBuffer += action.text;
55
+ if (textBuffer.length > 102_400) {
56
+ textBuffer = textBuffer.slice(0, 102_400) + "\n\n…(内容过长,已截断)";
57
+ }
58
+ break;
59
+ }
60
+ case "ToolStateChange":
61
+ ensureCard();
62
+ if (cardStartPromise) {
63
+ cardStartPromise.then(() => {
64
+ card
65
+ .setToolStatus(action.toolName, action.state, action.title)
66
+ .catch((err) => {
67
+ logger.warn(`setToolStatus failed: ${err}`);
68
+ });
69
+ }).catch((err) => {
70
+ logger.warn(`card start for tool failed: ${err}`);
71
+ });
72
+ }
73
+ break;
74
+ case "SubtaskDiscovered": {
75
+ subAgentTracker
76
+ .onSubtaskDiscovered(action)
77
+ .then((tracked) => {
78
+ const childSessionId = tracked.childSessionId ?? action.sessionId;
79
+ // Build and send a separate card for this sub-agent
80
+ const cardData = buildSubAgentNotificationCard(action.description, action.agent ?? "sub-agent", childSessionId);
81
+ return feishuClient.sendMessage(chatId, {
82
+ msg_type: "interactive",
83
+ content: JSON.stringify(cardData),
84
+ });
85
+ })
86
+ .catch((err) => {
87
+ logger.warn(`SubtaskDiscovered handling failed: ${err}`);
88
+ });
89
+ break;
90
+ }
91
+ case "QuestionAsked": {
92
+ if (seenInteractiveIds.has(action.requestId))
93
+ break;
94
+ seenInteractiveIds.add(action.requestId);
95
+ logger.info(`Question event received in bridge for session ${sessionId}, requestId=${action.requestId}`);
96
+ const questionCard = buildQuestionCard(action);
97
+ feishuClient.sendMessage(chatId, {
98
+ msg_type: "interactive",
99
+ content: JSON.stringify(questionCard),
100
+ }).catch((err) => {
101
+ logger.warn(`Question card send failed: ${err}`);
102
+ });
103
+ break;
104
+ }
105
+ case "PermissionRequested": {
106
+ if (seenInteractiveIds.has(action.requestId))
107
+ break;
108
+ seenInteractiveIds.add(action.requestId);
109
+ logger.info(`Permission event received in bridge for session ${sessionId}, requestId=${action.requestId}`);
110
+ const permissionCard = buildPermissionCard(action);
111
+ feishuClient.sendMessage(chatId, {
112
+ msg_type: "interactive",
113
+ content: JSON.stringify(permissionCard),
114
+ }).catch((err) => {
115
+ logger.warn(`Permission card send failed: ${err}`);
116
+ });
117
+ break;
118
+ }
119
+ case "SessionIdle": {
120
+ if (settled)
121
+ return;
122
+ settled = true;
123
+ clearTimeout(firstEventTimer);
124
+ removeListener(eventListeners, sessionId, myListener);
125
+ const responseText = textBuffer.trim() || "(无回复)";
126
+ const closeCard = card
127
+ ? (cardStartPromise ?? Promise.resolve()).then(() => card.close())
128
+ : Promise.resolve();
129
+ closeCard
130
+ .then(async () => {
131
+ try {
132
+ await sendFinalResponse(responseText);
133
+ }
134
+ catch (err) {
135
+ logger.warn(`sendFinalResponse failed: ${err}`);
136
+ }
137
+ onComplete(responseText);
138
+ resolve();
139
+ })
140
+ .catch(async (err) => {
141
+ logger.warn(`card.close() failed: ${err}`);
142
+ try {
143
+ await sendFinalResponse(responseText);
144
+ }
145
+ catch (replyErr) {
146
+ logger.warn(`sendFinalResponse failed after card.close error: ${replyErr}`);
147
+ }
148
+ onComplete(responseText);
149
+ resolve();
150
+ });
151
+ break;
152
+ }
153
+ default:
154
+ break;
155
+ }
156
+ };
157
+ const firstEventTimer = setTimeout(async () => {
158
+ if (gotFirstEvent || settled)
159
+ return;
160
+ settled = true;
161
+ removeListener(eventListeners, sessionId, myListener);
162
+ logger.warn(`No SSE events received within ${FIRST_EVENT_TIMEOUT_MS}ms for ${sessionId}, falling back to sync response`);
163
+ const fallbackText = parseSyncResponse(syncResponseBody, logger);
164
+ try {
165
+ if (card)
166
+ await card.close(fallbackText);
167
+ }
168
+ catch (err) {
169
+ logger.warn(`card.close() in timeout fallback failed: ${err}`);
170
+ }
171
+ // Send fallback text as reply
172
+ try {
173
+ await sendFinalResponse(fallbackText);
174
+ }
175
+ catch (err) {
176
+ logger.warn(`sendFinalResponse in timeout fallback failed: ${err}`);
177
+ }
178
+ onComplete(fallbackText);
179
+ resolve();
180
+ }, FIRST_EVENT_TIMEOUT_MS);
181
+ // Register event listener BEFORE the POST to avoid race condition
182
+ addListener(eventListeners, sessionId, myListener);
183
+ sendMessage()
184
+ .then((responseBody) => {
185
+ syncResponseBody = responseBody;
186
+ logger.info(`POST completed for session ${sessionId} (${responseBody.length} bytes)`);
187
+ })
188
+ .catch((err) => {
189
+ if (settled)
190
+ return;
191
+ // If SSE events have been flowing, the POST timeout is expected
192
+ // (e.g. agent blocked on question/permission). Keep the listener alive.
193
+ if (gotFirstEvent) {
194
+ logger.info(`POST timed out for session ${sessionId} but SSE events are flowing — keeping listener active`);
195
+ return;
196
+ }
197
+ settled = true;
198
+ clearTimeout(firstEventTimer);
199
+ removeListener(eventListeners, sessionId, myListener);
200
+ if (card)
201
+ card.close().catch(() => { });
202
+ reject(err);
203
+ });
204
+ });
205
+ },
206
+ };
207
+ }
208
+ // ── Helpers ──
209
+ function parseSyncResponse(rawText, logger) {
210
+ if (!rawText.trim())
211
+ return "(无回复)";
212
+ try {
213
+ const data = JSON.parse(rawText);
214
+ return (data.parts
215
+ ?.filter((p) => p.type === "text" && p.text)
216
+ .map((p) => p.text ?? "")
217
+ .join("\n")
218
+ .trim() || "(无回复)");
219
+ }
220
+ catch (e) {
221
+ logger.warn(`Failed to parse sync response: ${e}`);
222
+ return rawText.trim() || "(无回复)";
223
+ }
224
+ }
225
+ function buildSubAgentNotificationCard(description, agent, childSessionId) {
226
+ return {
227
+ config: { wide_screen_mode: true },
228
+ header: {
229
+ title: { tag: "plain_text", content: `🤖 ${agent}` },
230
+ template: "indigo",
231
+ },
232
+ elements: [
233
+ {
234
+ tag: "div",
235
+ text: { tag: "lark_md", content: description },
236
+ },
237
+ {
238
+ tag: "action",
239
+ actions: [
240
+ {
241
+ tag: "button",
242
+ text: { tag: "plain_text", content: "🔍 View Details" },
243
+ type: "primary",
244
+ value: { action: "view_subagent", childSessionId },
245
+ },
246
+ ],
247
+ },
248
+ ],
249
+ };
250
+ }
251
+ export function buildQuestionCard(action) {
252
+ const elements = [];
253
+ // Render each question (support multi-question requests)
254
+ for (let qi = 0; qi < action.questions.length; qi++) {
255
+ const question = action.questions[qi];
256
+ if (qi > 0) {
257
+ elements.push({ tag: "hr" });
258
+ }
259
+ elements.push({
260
+ tag: "div",
261
+ text: { tag: "lark_md", content: question.question },
262
+ });
263
+ elements.push({
264
+ tag: "action",
265
+ actions: question.options.map((opt, idx) => ({
266
+ tag: "button",
267
+ text: { tag: "plain_text", content: opt.label },
268
+ type: idx === 0 ? "primary" : "default",
269
+ value: {
270
+ action: "question_answer",
271
+ requestId: action.requestId,
272
+ answers: JSON.stringify([[opt.label]]),
273
+ },
274
+ })),
275
+ });
276
+ }
277
+ const header = action.questions[0]?.header ?? "Question";
278
+ return {
279
+ config: { wide_screen_mode: true },
280
+ header: {
281
+ title: { tag: "plain_text", content: `❓ ${header}` },
282
+ template: "orange",
283
+ },
284
+ elements,
285
+ };
286
+ }
287
+ export function buildPermissionCard(action) {
288
+ return {
289
+ config: { wide_screen_mode: true },
290
+ header: {
291
+ title: { tag: "plain_text", content: `🔐 Permission: ${action.permissionType}` },
292
+ template: "yellow",
293
+ },
294
+ elements: [
295
+ {
296
+ tag: "div",
297
+ text: { tag: "lark_md", content: action.title },
298
+ },
299
+ {
300
+ tag: "action",
301
+ actions: [
302
+ {
303
+ tag: "button",
304
+ text: { tag: "plain_text", content: "✅ Allow Once" },
305
+ type: "primary",
306
+ value: { action: "permission_reply", requestId: action.requestId, reply: "once" },
307
+ },
308
+ {
309
+ tag: "button",
310
+ text: { tag: "plain_text", content: "✅ Always Allow" },
311
+ type: "default",
312
+ value: { action: "permission_reply", requestId: action.requestId, reply: "always" },
313
+ },
314
+ {
315
+ tag: "button",
316
+ text: { tag: "plain_text", content: "❌ Reject" },
317
+ type: "danger",
318
+ value: { action: "permission_reply", requestId: action.requestId, reply: "reject" },
319
+ },
320
+ ],
321
+ },
322
+ ],
323
+ };
324
+ }
325
+ //# sourceMappingURL=streaming-integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming-integration.js","sourceRoot":"","sources":["../../src/handler/streaming-integration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * OhMyOpenclaw — Feishu channel integration for opencode.
3
+ *
4
+ * Standalone process entry point:
5
+ * 1. Load config
6
+ * 2. Connect to existing opencode server (createOpencodeClient)
7
+ * 3. Initialize SQLite database
8
+ * 4. Create shared services (session, memory, event processor, etc.)
9
+ * 5. Create FeishuPlugin + ChannelManager
10
+ * 6. Subscribe to opencode events (SSE)
11
+ * 7. Route incoming messages via message handler
12
+ * 8. Optionally start CronService + HeartbeatService
13
+ * 9. Graceful shutdown
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
package/dist/index.js ADDED
@@ -0,0 +1,281 @@
1
+ /**
2
+ * OhMyOpenclaw — Feishu channel integration for opencode.
3
+ *
4
+ * Standalone process entry point:
5
+ * 1. Load config
6
+ * 2. Connect to existing opencode server (createOpencodeClient)
7
+ * 3. Initialize SQLite database
8
+ * 4. Create shared services (session, memory, event processor, etc.)
9
+ * 5. Create FeishuPlugin + ChannelManager
10
+ * 6. Subscribe to opencode events (SSE)
11
+ * 7. Route incoming messages via message handler
12
+ * 8. Optionally start CronService + HeartbeatService
13
+ * 9. Graceful shutdown
14
+ */
15
+ import { createOpencodeClient } from "@opencode-ai/sdk/v2";
16
+ import { loadConfig } from "./utils/config.js";
17
+ import { initDatabase } from "./utils/db.js";
18
+ import { createLogger } from "./utils/logger.js";
19
+ import { createFeishuApiClient } from "./feishu/api-client.js";
20
+ import { CardKitClient } from "./feishu/cardkit-client.js";
21
+ import { MessageDedup } from "./feishu/message-dedup.js";
22
+ import { createSessionManager } from "./session/session-manager.js";
23
+ import { createProgressTracker } from "./session/progress-tracker.js";
24
+ import { createMemoryManager } from "./memory/memory-manager.js";
25
+ import { EventProcessor } from "./streaming/event-processor.js";
26
+ import { SubAgentTracker } from "./streaming/subagent-tracker.js";
27
+ import { createMessageHandler } from "./handler/message-handler.js";
28
+ import { createStreamingBridge } from "./handler/streaming-integration.js";
29
+ import { createSessionObserver } from "./streaming/session-observer.js";
30
+ import { addListener, removeListener } from "./utils/event-listeners.js";
31
+ import { createSubAgentCardHandler } from "./streaming/subagent-card.js";
32
+ import { createInteractiveHandler } from "./handler/interactive-handler.js";
33
+ import { createInteractivePoller } from "./handler/interactive-poller.js";
34
+ import { createFeishuGateway } from "./feishu/webhook-server.js";
35
+ import { FeishuPlugin } from "./channel/feishu/feishu-plugin.js";
36
+ import { ChannelManager } from "./channel/manager.js";
37
+ import { CronService } from "./cron/cron-service.js";
38
+ import { HeartbeatService } from "./cron/heartbeat.js";
39
+ const logger = createLogger("opencode-lark");
40
+ async function main() {
41
+ // ═══════════════════════════════════════════
42
+ // Phase 1: Load Config
43
+ // ═══════════════════════════════════════════
44
+ logger.info("Phase 1: Loading config...");
45
+ const config = await loadConfig();
46
+ if (!config.feishu.appId || !config.feishu.appSecret) {
47
+ logger.error("Feishu credentials missing. Set FEISHU_APP_ID and FEISHU_APP_SECRET.");
48
+ process.exit(1);
49
+ }
50
+ // ═══════════════════════════════════════════
51
+ // Phase 2: Connect to Opencode Server
52
+ // ═══════════════════════════════════════════
53
+ logger.info("Phase 2: Connecting to opencode server...");
54
+ const serverUrl = (process.env.OPENCODE_SERVER_URL ?? "http://localhost:4096").replace("localhost", "127.0.0.1");
55
+ logger.info(`Connecting to opencode server at ${serverUrl}`);
56
+ const client = createOpencodeClient({
57
+ baseUrl: serverUrl,
58
+ });
59
+ async function waitForServer(maxRetries = 10) {
60
+ let delay = 250;
61
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
62
+ try {
63
+ await client.session.status();
64
+ return;
65
+ }
66
+ catch {
67
+ if (attempt === maxRetries) {
68
+ throw new Error(`Opencode server not reachable after ${maxRetries} attempts`);
69
+ }
70
+ logger.info(`Waiting for opencode server (attempt ${attempt}/${maxRetries})...`);
71
+ await new Promise((r) => setTimeout(r, delay));
72
+ delay = Math.min(delay * 2, 5000);
73
+ }
74
+ }
75
+ }
76
+ await waitForServer();
77
+ logger.info("Opencode server ready");
78
+ // ═══════════════════════════════════════════
79
+ // Phase 3: Database Init
80
+ // ═══════════════════════════════════════════
81
+ logger.info("Phase 3: Initializing database...");
82
+ const db = initDatabase(config.dataDir);
83
+ // ═══════════════════════════════════════════
84
+ // Phase 4: Create Shared Services
85
+ // ═══════════════════════════════════════════
86
+ logger.info("Phase 4: Creating shared services...");
87
+ const feishuClient = createFeishuApiClient({
88
+ appId: config.feishu.appId,
89
+ appSecret: config.feishu.appSecret,
90
+ });
91
+ const cardkitClient = new CardKitClient({
92
+ appId: config.feishu.appId,
93
+ appSecret: config.feishu.appSecret,
94
+ });
95
+ const sessionManager = createSessionManager({
96
+ serverUrl,
97
+ db: db.sessions,
98
+ defaultAgent: config.defaultAgent,
99
+ });
100
+ const dedup = new MessageDedup({ db: db.sessions, ttlMs: 60_000 });
101
+ const progressTracker = createProgressTracker({ feishuClient });
102
+ const memoryManager = createMemoryManager({ db: db.memory });
103
+ const ownedSessions = new Set();
104
+ const eventListeners = new Map();
105
+ const seenInteractiveIds = new Set();
106
+ const eventProcessor = new EventProcessor({ ownedSessions, logger });
107
+ const subAgentTracker = new SubAgentTracker({ serverUrl });
108
+ const streamingBridge = createStreamingBridge({
109
+ cardkitClient,
110
+ feishuClient,
111
+ subAgentTracker,
112
+ logger,
113
+ seenInteractiveIds,
114
+ });
115
+ const observer = createSessionObserver({
116
+ feishuClient,
117
+ eventProcessor,
118
+ addListener: (sessionId, fn) => addListener(eventListeners, sessionId, fn),
119
+ removeListener: (sessionId, fn) => removeListener(eventListeners, sessionId, fn),
120
+ logger,
121
+ seenInteractiveIds,
122
+ });
123
+ const handleMessage = createMessageHandler({
124
+ serverUrl,
125
+ sessionManager,
126
+ memoryManager,
127
+ dedup,
128
+ eventProcessor,
129
+ feishuClient,
130
+ progressTracker,
131
+ eventListeners,
132
+ ownedSessions,
133
+ logger,
134
+ streamingBridge,
135
+ observer,
136
+ });
137
+ // Create card action handlers
138
+ const subAgentCardHandler = createSubAgentCardHandler({
139
+ subAgentTracker,
140
+ feishuClient,
141
+ logger,
142
+ });
143
+ const interactiveHandler = createInteractiveHandler({
144
+ serverUrl,
145
+ logger,
146
+ });
147
+ const interactivePoller = createInteractivePoller({
148
+ serverUrl,
149
+ feishuClient,
150
+ logger,
151
+ getChatForSession: (sessionId) => observer.getChatForSession(sessionId),
152
+ seenInteractiveIds,
153
+ });
154
+ interactivePoller.start();
155
+ const handleCardAction = async (action) => {
156
+ const actionType = action.action?.value?.action;
157
+ if (actionType === "view_subagent") {
158
+ return subAgentCardHandler(action);
159
+ }
160
+ if (actionType === "question_answer" || actionType === "permission_reply") {
161
+ return interactiveHandler(action);
162
+ }
163
+ logger.warn(`Unknown card action type: ${actionType}`);
164
+ };
165
+ // ═══════════════════════════════════════════
166
+ // Phase 5: Subscribe to Opencode Events (SSE)
167
+ // ═══════════════════════════════════════════
168
+ logger.info("Phase 5: Subscribing to opencode events...");
169
+ (async () => {
170
+ try {
171
+ const events = await client.event.subscribe();
172
+ logger.info("SSE event stream connected");
173
+ for await (const event of events.stream) {
174
+ const eventType = event?.type;
175
+ if (eventType) {
176
+ const props = event?.properties;
177
+ const sessionID = props?.sessionID ?? (props?.part && typeof props.part === "object" ? props.part.sessionID : undefined);
178
+ logger.debug(`SSE: ${eventType} session=${sessionID ?? "n/a"}`);
179
+ }
180
+ for (const [key, listeners] of eventListeners.entries()) {
181
+ for (const listener of listeners) {
182
+ try {
183
+ listener(event);
184
+ }
185
+ catch (err) {
186
+ logger.warn(`Event listener for ${key} threw: ${err}`);
187
+ }
188
+ }
189
+ }
190
+ }
191
+ logger.warn("SSE event stream ended");
192
+ }
193
+ catch (err) {
194
+ logger.error(`SSE subscription failed: ${err}`);
195
+ }
196
+ })();
197
+ // ═══════════════════════════════════════════
198
+ // Phase 6: Create FeishuPlugin + ChannelManager
199
+ // ═══════════════════════════════════════════
200
+ logger.info("Phase 6: Creating channel manager...");
201
+ const feishuPlugin = new FeishuPlugin({
202
+ appConfig: config,
203
+ feishuClient,
204
+ cardkitClient,
205
+ logger,
206
+ onMessage: handleMessage,
207
+ onCardAction: handleCardAction,
208
+ });
209
+ const channelManager = new ChannelManager({ logger });
210
+ channelManager.register(feishuPlugin);
211
+ // ═══════════════════════════════════════════
212
+ // Phase 7: Start Channels + Webhook Server
213
+ // ═══════════════════════════════════════════
214
+ logger.info("Phase 7: Starting channels...");
215
+ const abortController = new AbortController();
216
+ await channelManager.startAll(abortController.signal);
217
+ // Start webhook server for card action callbacks
218
+ logger.info("Phase 7b: Starting webhook server for card actions...");
219
+ const webhookPort = parseInt(process.env.FEISHU_WEBHOOK_PORT ?? "3001", 10);
220
+ const webhookServer = await createFeishuGateway({
221
+ port: webhookPort,
222
+ verificationToken: config.feishu.verificationToken ?? "",
223
+ onMessage: handleMessage,
224
+ onCardAction: handleCardAction,
225
+ dedup,
226
+ });
227
+ logger.info(`Webhook server started on port ${webhookPort}`);
228
+ // ═══════════════════════════════════════════
229
+ // Phase 8: Optional Services (Cron + Heartbeat)
230
+ // ═══════════════════════════════════════════
231
+ let cronService;
232
+ let heartbeatService;
233
+ if (config.cron) {
234
+ logger.info("Starting cron service...");
235
+ cronService = new CronService({
236
+ config: config.cron,
237
+ sessionManager,
238
+ feishuClient,
239
+ serverUrl,
240
+ logger,
241
+ });
242
+ cronService.start();
243
+ }
244
+ if (config.heartbeat) {
245
+ logger.info("Starting heartbeat service...");
246
+ heartbeatService = new HeartbeatService({
247
+ intervalMs: config.heartbeat.intervalMs,
248
+ serverUrl,
249
+ feishuClient,
250
+ statusChatId: config.heartbeat.statusChatId,
251
+ logger,
252
+ });
253
+ heartbeatService.start();
254
+ }
255
+ // ═══════════════════════════════════════════
256
+ // Graceful Shutdown
257
+ // ═══════════════════════════════════════════
258
+ function shutdown(signal) {
259
+ return async () => {
260
+ logger.info(`${signal} received, shutting down...`);
261
+ abortController.abort();
262
+ await channelManager.stopAll();
263
+ await webhookServer.close();
264
+ cronService?.stop();
265
+ heartbeatService?.stop();
266
+ interactivePoller.stop();
267
+ observer.stop();
268
+ dedup.close();
269
+ db.close();
270
+ process.exit(0);
271
+ };
272
+ }
273
+ process.on("SIGTERM", shutdown("SIGTERM"));
274
+ process.on("SIGINT", shutdown("SIGINT"));
275
+ logger.info("OhMyOpenclaw started — channels active");
276
+ }
277
+ main().catch((err) => {
278
+ logger.error("Fatal error:", err);
279
+ process.exit(1);
280
+ });
281
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}