@openclaw/feishu 2026.5.2 → 2026.5.3-beta.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.
- package/dist/accounts-Ba3-WP1z.js +423 -0
- package/dist/api.js +2280 -0
- package/dist/app-registration-B8qc1MCM.js +184 -0
- package/dist/audio-preflight.runtime-BPlzkO3l.js +7 -0
- package/dist/card-interaction-BfRLgvw_.js +96 -0
- package/dist/channel-CSD_Jt8I.js +1668 -0
- package/dist/channel-entry.js +22 -0
- package/dist/channel-plugin-api.js +2 -0
- package/dist/channel.runtime-DYsXcD36.js +700 -0
- package/dist/client-DBVoQL5w.js +157 -0
- package/dist/contract-api.js +9 -0
- package/dist/conversation-id-DWS3Ep2A.js +139 -0
- package/dist/directory.static-f3EeoRJd.js +44 -0
- package/dist/drive-C5eJLJr7.js +883 -0
- package/dist/index.js +68 -0
- package/dist/monitor-CT189QfR.js +60 -0
- package/dist/monitor.account-dJV2jO8C.js +4990 -0
- package/dist/monitor.state-DYM02ipp.js +100 -0
- package/dist/policy-D6c-wMPl.js +118 -0
- package/dist/probe-BNzzU_uR.js +149 -0
- package/dist/rolldown-runtime-DUslC3ob.js +14 -0
- package/dist/runtime-CG0DuRCy.js +8 -0
- package/dist/runtime-api.js +14 -0
- package/dist/secret-contract-Dm4Z_zQN.js +119 -0
- package/dist/secret-contract-api.js +2 -0
- package/dist/security-audit-DqJdocrN.js +11 -0
- package/dist/security-audit-shared-ByuMx9cJ.js +38 -0
- package/dist/security-contract-api.js +2 -0
- package/dist/send-DowxxbpH.js +1218 -0
- package/dist/session-conversation-B4nrW-vo.js +27 -0
- package/dist/session-key-api.js +2 -0
- package/dist/setup-api.js +2 -0
- package/dist/setup-entry.js +15 -0
- package/dist/subagent-hooks-C3UhPVLV.js +227 -0
- package/dist/subagent-hooks-api.js +23 -0
- package/dist/targets-JMFJRKSe.js +48 -0
- package/dist/thread-bindings-BmS6TLes.js +222 -0
- package/package.json +15 -6
- package/api.ts +0 -31
- package/channel-entry.ts +0 -20
- package/channel-plugin-api.ts +0 -1
- package/contract-api.ts +0 -16
- package/index.ts +0 -82
- package/runtime-api.ts +0 -55
- package/secret-contract-api.ts +0 -5
- package/security-contract-api.ts +0 -1
- package/session-key-api.ts +0 -1
- package/setup-api.ts +0 -3
- package/setup-entry.test.ts +0 -14
- package/setup-entry.ts +0 -13
- package/src/accounts.test.ts +0 -459
- package/src/accounts.ts +0 -326
- package/src/app-registration.ts +0 -331
- package/src/approval-auth.test.ts +0 -24
- package/src/approval-auth.ts +0 -25
- package/src/async.test.ts +0 -35
- package/src/async.ts +0 -104
- package/src/audio-preflight.runtime.ts +0 -9
- package/src/bitable.test.ts +0 -131
- package/src/bitable.ts +0 -762
- package/src/bot-content.ts +0 -474
- package/src/bot-group-name.test.ts +0 -108
- package/src/bot-runtime-api.ts +0 -12
- package/src/bot-sender-name.ts +0 -125
- package/src/bot.broadcast.test.ts +0 -463
- package/src/bot.card-action.test.ts +0 -577
- package/src/bot.checkBotMentioned.test.ts +0 -265
- package/src/bot.helpers.test.ts +0 -118
- package/src/bot.stripBotMention.test.ts +0 -126
- package/src/bot.test.ts +0 -3040
- package/src/bot.ts +0 -1559
- package/src/card-action.ts +0 -447
- package/src/card-interaction.test.ts +0 -129
- package/src/card-interaction.ts +0 -159
- package/src/card-test-helpers.ts +0 -47
- package/src/card-ux-approval.ts +0 -65
- package/src/card-ux-launcher.test.ts +0 -99
- package/src/card-ux-launcher.ts +0 -121
- package/src/card-ux-shared.ts +0 -33
- package/src/channel-runtime-api.ts +0 -16
- package/src/channel.runtime.ts +0 -47
- package/src/channel.test.ts +0 -959
- package/src/channel.ts +0 -1313
- package/src/chat-schema.ts +0 -25
- package/src/chat.test.ts +0 -196
- package/src/chat.ts +0 -188
- package/src/client.test.ts +0 -433
- package/src/client.ts +0 -290
- package/src/comment-dispatcher-runtime-api.ts +0 -6
- package/src/comment-dispatcher.test.ts +0 -169
- package/src/comment-dispatcher.ts +0 -107
- package/src/comment-handler-runtime-api.ts +0 -3
- package/src/comment-handler.test.ts +0 -486
- package/src/comment-handler.ts +0 -309
- package/src/comment-reaction.test.ts +0 -166
- package/src/comment-reaction.ts +0 -259
- package/src/comment-shared.test.ts +0 -182
- package/src/comment-shared.ts +0 -406
- package/src/comment-target.ts +0 -44
- package/src/config-schema.test.ts +0 -309
- package/src/config-schema.ts +0 -333
- package/src/conversation-id.test.ts +0 -18
- package/src/conversation-id.ts +0 -199
- package/src/dedup-runtime-api.ts +0 -1
- package/src/dedup.ts +0 -141
- package/src/directory.static.ts +0 -61
- package/src/directory.test.ts +0 -136
- package/src/directory.ts +0 -124
- package/src/doc-schema.ts +0 -182
- package/src/docx-batch-insert.test.ts +0 -91
- package/src/docx-batch-insert.ts +0 -223
- package/src/docx-color-text.ts +0 -154
- package/src/docx-table-ops.test.ts +0 -53
- package/src/docx-table-ops.ts +0 -316
- package/src/docx-types.ts +0 -38
- package/src/docx.account-selection.test.ts +0 -79
- package/src/docx.test.ts +0 -685
- package/src/docx.ts +0 -1616
- package/src/drive-schema.ts +0 -92
- package/src/drive.test.ts +0 -1219
- package/src/drive.ts +0 -829
- package/src/dynamic-agent.ts +0 -137
- package/src/event-types.ts +0 -45
- package/src/external-keys.test.ts +0 -20
- package/src/external-keys.ts +0 -19
- package/src/lifecycle.test-support.ts +0 -220
- package/src/media.test.ts +0 -900
- package/src/media.ts +0 -861
- package/src/mention-target.types.ts +0 -5
- package/src/mention.ts +0 -114
- package/src/message-action-contract.ts +0 -13
- package/src/monitor-state-runtime-api.ts +0 -7
- package/src/monitor-transport-runtime-api.ts +0 -7
- package/src/monitor.account.ts +0 -468
- package/src/monitor.acp-init-failure.lifecycle.test-support.ts +0 -219
- package/src/monitor.bot-identity.ts +0 -86
- package/src/monitor.bot-menu-handler.ts +0 -165
- package/src/monitor.bot-menu.lifecycle.test-support.ts +0 -224
- package/src/monitor.bot-menu.test.ts +0 -178
- package/src/monitor.broadcast.reply-once.lifecycle.test-support.ts +0 -264
- package/src/monitor.card-action.lifecycle.test-support.ts +0 -373
- package/src/monitor.cleanup.test.ts +0 -376
- package/src/monitor.comment-notice-handler.ts +0 -105
- package/src/monitor.comment.test.ts +0 -937
- package/src/monitor.comment.ts +0 -1386
- package/src/monitor.lifecycle.test.ts +0 -4
- package/src/monitor.message-handler.ts +0 -339
- package/src/monitor.reaction.lifecycle.test-support.ts +0 -68
- package/src/monitor.reaction.test.ts +0 -713
- package/src/monitor.startup.test.ts +0 -192
- package/src/monitor.startup.ts +0 -74
- package/src/monitor.state.defaults.test.ts +0 -46
- package/src/monitor.state.ts +0 -170
- package/src/monitor.synthetic-error.ts +0 -18
- package/src/monitor.test-mocks.ts +0 -45
- package/src/monitor.transport.ts +0 -424
- package/src/monitor.ts +0 -100
- package/src/monitor.webhook-e2e.test.ts +0 -272
- package/src/monitor.webhook-security.test.ts +0 -264
- package/src/monitor.webhook.test-helpers.ts +0 -116
- package/src/outbound-runtime-api.ts +0 -1
- package/src/outbound.test.ts +0 -935
- package/src/outbound.ts +0 -718
- package/src/perm-schema.ts +0 -52
- package/src/perm.ts +0 -170
- package/src/pins.ts +0 -108
- package/src/policy.test.ts +0 -334
- package/src/policy.ts +0 -236
- package/src/post.test.ts +0 -105
- package/src/post.ts +0 -275
- package/src/probe.test.ts +0 -275
- package/src/probe.ts +0 -166
- package/src/processing-claims.ts +0 -59
- package/src/qr-terminal.ts +0 -1
- package/src/reactions.ts +0 -123
- package/src/reasoning-preview.test.ts +0 -59
- package/src/reasoning-preview.ts +0 -20
- package/src/reply-dispatcher-runtime-api.ts +0 -7
- package/src/reply-dispatcher.test.ts +0 -1144
- package/src/reply-dispatcher.ts +0 -650
- package/src/runtime.ts +0 -9
- package/src/secret-contract.ts +0 -145
- package/src/secret-input.ts +0 -1
- package/src/security-audit-shared.ts +0 -69
- package/src/security-audit.test.ts +0 -61
- package/src/security-audit.ts +0 -1
- package/src/send-result.ts +0 -29
- package/src/send-target.test.ts +0 -80
- package/src/send-target.ts +0 -35
- package/src/send.reply-fallback.test.ts +0 -292
- package/src/send.test.ts +0 -550
- package/src/send.ts +0 -800
- package/src/sequential-key.test.ts +0 -72
- package/src/sequential-key.ts +0 -28
- package/src/sequential-queue.test.ts +0 -92
- package/src/sequential-queue.ts +0 -16
- package/src/session-conversation.ts +0 -42
- package/src/session-route.ts +0 -48
- package/src/setup-core.ts +0 -51
- package/src/setup-surface.test.ts +0 -174
- package/src/setup-surface.ts +0 -581
- package/src/streaming-card.test.ts +0 -190
- package/src/streaming-card.ts +0 -490
- package/src/subagent-hooks.test.ts +0 -603
- package/src/subagent-hooks.ts +0 -397
- package/src/targets.ts +0 -97
- package/src/test-support/lifecycle-test-support.ts +0 -453
- package/src/thread-bindings.test.ts +0 -143
- package/src/thread-bindings.ts +0 -330
- package/src/tool-account-routing.test.ts +0 -187
- package/src/tool-account.test.ts +0 -44
- package/src/tool-account.ts +0 -93
- package/src/tool-factory-test-harness.ts +0 -79
- package/src/tool-result.test.ts +0 -32
- package/src/tool-result.ts +0 -16
- package/src/tools-config.test.ts +0 -21
- package/src/tools-config.ts +0 -22
- package/src/types.ts +0 -104
- package/src/typing.test.ts +0 -144
- package/src/typing.ts +0 -214
- package/src/wiki-schema.ts +0 -55
- package/src/wiki.ts +0 -227
- package/subagent-hooks-api.ts +0 -31
- package/tsconfig.json +0 -16
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-DWS3Ep2A.js";
|
|
2
|
+
//#region extensions/feishu/src/session-conversation.ts
|
|
3
|
+
function resolveFeishuParentConversationCandidates(rawId) {
|
|
4
|
+
const parsed = parseFeishuConversationId({ conversationId: rawId });
|
|
5
|
+
if (!parsed) return [];
|
|
6
|
+
switch (parsed.scope) {
|
|
7
|
+
case "group_topic_sender": return [buildFeishuConversationId({
|
|
8
|
+
chatId: parsed.chatId,
|
|
9
|
+
scope: "group_topic",
|
|
10
|
+
topicId: parsed.topicId
|
|
11
|
+
}), parsed.chatId];
|
|
12
|
+
case "group_topic":
|
|
13
|
+
case "group_sender": return [parsed.chatId];
|
|
14
|
+
default: return [];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function resolveFeishuSessionConversation(params) {
|
|
18
|
+
const parsed = parseFeishuConversationId({ conversationId: params.rawId });
|
|
19
|
+
if (!parsed) return null;
|
|
20
|
+
return {
|
|
21
|
+
id: parsed.canonicalConversationId,
|
|
22
|
+
baseConversationId: parsed.chatId,
|
|
23
|
+
parentConversationCandidates: resolveFeishuParentConversationCandidates(parsed.canonicalConversationId)
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { resolveFeishuSessionConversation as t };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defineBundledChannelSetupEntry } from "openclaw/plugin-sdk/channel-entry-contract";
|
|
2
|
+
//#region extensions/feishu/setup-entry.ts
|
|
3
|
+
var setup_entry_default = defineBundledChannelSetupEntry({
|
|
4
|
+
importMetaUrl: import.meta.url,
|
|
5
|
+
plugin: {
|
|
6
|
+
specifier: "./setup-api.js",
|
|
7
|
+
exportName: "feishuPlugin"
|
|
8
|
+
},
|
|
9
|
+
secrets: {
|
|
10
|
+
specifier: "./secret-contract-api.js",
|
|
11
|
+
exportName: "channelSecrets"
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
//#endregion
|
|
15
|
+
export { setup_entry_default as default };
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-DUslC3ob.js";
|
|
2
|
+
import { r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-DWS3Ep2A.js";
|
|
3
|
+
import { r as normalizeFeishuTarget } from "./targets-JMFJRKSe.js";
|
|
4
|
+
import { r as getFeishuThreadBindingManager } from "./thread-bindings-BmS6TLes.js";
|
|
5
|
+
import { normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
|
6
|
+
//#region extensions/feishu/src/subagent-hooks.ts
|
|
7
|
+
var subagent_hooks_exports = /* @__PURE__ */ __exportAll({
|
|
8
|
+
handleFeishuSubagentDeliveryTarget: () => handleFeishuSubagentDeliveryTarget,
|
|
9
|
+
handleFeishuSubagentEnded: () => handleFeishuSubagentEnded,
|
|
10
|
+
handleFeishuSubagentSpawning: () => handleFeishuSubagentSpawning
|
|
11
|
+
});
|
|
12
|
+
function summarizeError(err) {
|
|
13
|
+
if (err instanceof Error) return err.message;
|
|
14
|
+
if (typeof err === "string") return err;
|
|
15
|
+
return "error";
|
|
16
|
+
}
|
|
17
|
+
function stripProviderPrefix(raw) {
|
|
18
|
+
return raw.replace(/^(feishu|lark):/i, "").trim();
|
|
19
|
+
}
|
|
20
|
+
function resolveFeishuRequesterConversation(params) {
|
|
21
|
+
const manager = getFeishuThreadBindingManager(params.accountId);
|
|
22
|
+
if (!manager) return null;
|
|
23
|
+
const rawTo = params.to?.trim();
|
|
24
|
+
const withoutProviderPrefix = rawTo ? stripProviderPrefix(rawTo) : "";
|
|
25
|
+
const normalizedTarget = rawTo ? normalizeFeishuTarget(rawTo) : null;
|
|
26
|
+
const threadId = params.threadId != null && params.threadId !== "" ? String(params.threadId).trim() : "";
|
|
27
|
+
const isChatTarget = /^(chat|group|channel):/i.test(withoutProviderPrefix);
|
|
28
|
+
const parsedRequesterTopic = normalizedTarget && threadId && isChatTarget ? parseFeishuConversationId({
|
|
29
|
+
conversationId: buildFeishuConversationId({
|
|
30
|
+
chatId: normalizedTarget,
|
|
31
|
+
scope: "group_topic",
|
|
32
|
+
topicId: threadId
|
|
33
|
+
}),
|
|
34
|
+
parentConversationId: normalizedTarget
|
|
35
|
+
}) : null;
|
|
36
|
+
const requesterSessionKey = params.requesterSessionKey?.trim();
|
|
37
|
+
if (requesterSessionKey) {
|
|
38
|
+
const existingBindings = manager.listBySessionKey(requesterSessionKey);
|
|
39
|
+
if (existingBindings.length === 1) {
|
|
40
|
+
const existing = existingBindings[0];
|
|
41
|
+
return {
|
|
42
|
+
accountId: existing.accountId,
|
|
43
|
+
conversationId: existing.conversationId,
|
|
44
|
+
parentConversationId: existing.parentConversationId
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
if (existingBindings.length > 1) {
|
|
48
|
+
if (rawTo && normalizedTarget && !threadId && !isChatTarget) {
|
|
49
|
+
const directMatches = existingBindings.filter((entry) => entry.accountId === manager.accountId && entry.conversationId === normalizedTarget && !entry.parentConversationId);
|
|
50
|
+
if (directMatches.length === 1) {
|
|
51
|
+
const existing = directMatches[0];
|
|
52
|
+
return {
|
|
53
|
+
accountId: existing.accountId,
|
|
54
|
+
conversationId: existing.conversationId,
|
|
55
|
+
parentConversationId: existing.parentConversationId
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
if (parsedRequesterTopic) {
|
|
61
|
+
const matchingTopicBindings = existingBindings.filter((entry) => {
|
|
62
|
+
const parsed = parseFeishuConversationId({
|
|
63
|
+
conversationId: entry.conversationId,
|
|
64
|
+
parentConversationId: entry.parentConversationId
|
|
65
|
+
});
|
|
66
|
+
return parsed?.chatId === parsedRequesterTopic.chatId && parsed?.topicId === parsedRequesterTopic.topicId;
|
|
67
|
+
});
|
|
68
|
+
if (matchingTopicBindings.length === 1) {
|
|
69
|
+
const existing = matchingTopicBindings[0];
|
|
70
|
+
return {
|
|
71
|
+
accountId: existing.accountId,
|
|
72
|
+
conversationId: existing.conversationId,
|
|
73
|
+
parentConversationId: existing.parentConversationId
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const senderScopedTopicBindings = matchingTopicBindings.filter((entry) => {
|
|
77
|
+
return parseFeishuConversationId({
|
|
78
|
+
conversationId: entry.conversationId,
|
|
79
|
+
parentConversationId: entry.parentConversationId
|
|
80
|
+
})?.scope === "group_topic_sender";
|
|
81
|
+
});
|
|
82
|
+
if (senderScopedTopicBindings.length === 1 && matchingTopicBindings.length === senderScopedTopicBindings.length) {
|
|
83
|
+
const existing = senderScopedTopicBindings[0];
|
|
84
|
+
return {
|
|
85
|
+
accountId: existing.accountId,
|
|
86
|
+
conversationId: existing.conversationId,
|
|
87
|
+
parentConversationId: existing.parentConversationId
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (!rawTo) return null;
|
|
95
|
+
if (!normalizedTarget) return null;
|
|
96
|
+
if (threadId) {
|
|
97
|
+
if (!isChatTarget) return null;
|
|
98
|
+
return {
|
|
99
|
+
accountId: manager.accountId,
|
|
100
|
+
conversationId: buildFeishuConversationId({
|
|
101
|
+
chatId: normalizedTarget,
|
|
102
|
+
scope: "group_topic",
|
|
103
|
+
topicId: threadId
|
|
104
|
+
}),
|
|
105
|
+
parentConversationId: normalizedTarget
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
if (isChatTarget) return null;
|
|
109
|
+
return {
|
|
110
|
+
accountId: manager.accountId,
|
|
111
|
+
conversationId: normalizedTarget
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function resolveFeishuDeliveryOrigin(params) {
|
|
115
|
+
const deliveryTo = params.deliveryTo?.trim();
|
|
116
|
+
const deliveryThreadId = params.deliveryThreadId?.trim();
|
|
117
|
+
if (deliveryTo) return {
|
|
118
|
+
channel: "feishu",
|
|
119
|
+
accountId: params.accountId,
|
|
120
|
+
to: deliveryTo,
|
|
121
|
+
...deliveryThreadId ? { threadId: deliveryThreadId } : {}
|
|
122
|
+
};
|
|
123
|
+
const parsed = parseFeishuConversationId({
|
|
124
|
+
conversationId: params.conversationId,
|
|
125
|
+
parentConversationId: params.parentConversationId
|
|
126
|
+
});
|
|
127
|
+
if (parsed?.topicId) return {
|
|
128
|
+
channel: "feishu",
|
|
129
|
+
accountId: params.accountId,
|
|
130
|
+
to: `chat:${params.parentConversationId?.trim() || parsed.chatId}`,
|
|
131
|
+
threadId: parsed.topicId
|
|
132
|
+
};
|
|
133
|
+
return {
|
|
134
|
+
channel: "feishu",
|
|
135
|
+
accountId: params.accountId,
|
|
136
|
+
to: `user:${params.conversationId}`
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function resolveMatchingChildBinding(params) {
|
|
140
|
+
const manager = getFeishuThreadBindingManager(params.accountId);
|
|
141
|
+
if (!manager) return null;
|
|
142
|
+
const childBindings = manager.listBySessionKey(params.childSessionKey.trim());
|
|
143
|
+
if (childBindings.length === 0) return null;
|
|
144
|
+
const requesterConversation = resolveFeishuRequesterConversation({
|
|
145
|
+
accountId: manager.accountId,
|
|
146
|
+
to: params.requesterOrigin?.to,
|
|
147
|
+
threadId: params.requesterOrigin?.threadId,
|
|
148
|
+
requesterSessionKey: params.requesterSessionKey
|
|
149
|
+
});
|
|
150
|
+
if (requesterConversation) {
|
|
151
|
+
const matched = childBindings.find((entry) => entry.accountId === requesterConversation.accountId && entry.conversationId === requesterConversation.conversationId && normalizeOptionalString(entry.parentConversationId) === normalizeOptionalString(requesterConversation.parentConversationId));
|
|
152
|
+
if (matched) return matched;
|
|
153
|
+
}
|
|
154
|
+
return childBindings.length === 1 ? childBindings[0] : null;
|
|
155
|
+
}
|
|
156
|
+
async function handleFeishuSubagentSpawning(event, ctx) {
|
|
157
|
+
if (!event.threadRequested) return;
|
|
158
|
+
if (normalizeOptionalLowercaseString(event.requester?.channel) !== "feishu") return;
|
|
159
|
+
const manager = getFeishuThreadBindingManager(event.requester?.accountId);
|
|
160
|
+
if (!manager) return {
|
|
161
|
+
status: "error",
|
|
162
|
+
error: "Feishu current-conversation binding is unavailable because the Feishu account monitor is not active."
|
|
163
|
+
};
|
|
164
|
+
const conversation = resolveFeishuRequesterConversation({
|
|
165
|
+
accountId: event.requester?.accountId,
|
|
166
|
+
to: event.requester?.to,
|
|
167
|
+
threadId: event.requester?.threadId,
|
|
168
|
+
requesterSessionKey: ctx.requesterSessionKey
|
|
169
|
+
});
|
|
170
|
+
if (!conversation) return {
|
|
171
|
+
status: "error",
|
|
172
|
+
error: "Feishu current-conversation binding is only available in direct messages or topic conversations."
|
|
173
|
+
};
|
|
174
|
+
try {
|
|
175
|
+
if (!manager.bindConversation({
|
|
176
|
+
conversationId: conversation.conversationId,
|
|
177
|
+
parentConversationId: conversation.parentConversationId,
|
|
178
|
+
targetKind: "subagent",
|
|
179
|
+
targetSessionKey: event.childSessionKey,
|
|
180
|
+
metadata: {
|
|
181
|
+
agentId: event.agentId,
|
|
182
|
+
label: event.label,
|
|
183
|
+
boundBy: "system",
|
|
184
|
+
deliveryTo: event.requester?.to,
|
|
185
|
+
deliveryThreadId: event.requester?.threadId != null && event.requester.threadId !== "" ? String(event.requester.threadId) : void 0
|
|
186
|
+
}
|
|
187
|
+
})) return {
|
|
188
|
+
status: "error",
|
|
189
|
+
error: "Unable to bind this Feishu conversation to the spawned subagent session. Session mode is unavailable for this target."
|
|
190
|
+
};
|
|
191
|
+
return {
|
|
192
|
+
status: "ok",
|
|
193
|
+
threadBindingReady: true
|
|
194
|
+
};
|
|
195
|
+
} catch (err) {
|
|
196
|
+
return {
|
|
197
|
+
status: "error",
|
|
198
|
+
error: `Feishu conversation bind failed: ${summarizeError(err)}`
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
function handleFeishuSubagentDeliveryTarget(event) {
|
|
203
|
+
if (!event.expectsCompletionMessage) return;
|
|
204
|
+
if (normalizeOptionalLowercaseString(event.requesterOrigin?.channel) !== "feishu") return;
|
|
205
|
+
const binding = resolveMatchingChildBinding({
|
|
206
|
+
accountId: event.requesterOrigin?.accountId,
|
|
207
|
+
childSessionKey: event.childSessionKey,
|
|
208
|
+
requesterSessionKey: event.requesterSessionKey,
|
|
209
|
+
requesterOrigin: {
|
|
210
|
+
to: event.requesterOrigin?.to,
|
|
211
|
+
threadId: event.requesterOrigin?.threadId
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
if (!binding) return;
|
|
215
|
+
return { origin: resolveFeishuDeliveryOrigin({
|
|
216
|
+
conversationId: binding.conversationId,
|
|
217
|
+
parentConversationId: binding.parentConversationId,
|
|
218
|
+
accountId: binding.accountId,
|
|
219
|
+
deliveryTo: binding.deliveryTo,
|
|
220
|
+
deliveryThreadId: binding.deliveryThreadId
|
|
221
|
+
}) };
|
|
222
|
+
}
|
|
223
|
+
function handleFeishuSubagentEnded(event) {
|
|
224
|
+
getFeishuThreadBindingManager(event.accountId)?.unbindBySessionKey(event.targetSessionKey);
|
|
225
|
+
}
|
|
226
|
+
//#endregion
|
|
227
|
+
export { subagent_hooks_exports as i, handleFeishuSubagentEnded as n, handleFeishuSubagentSpawning as r, handleFeishuSubagentDeliveryTarget as t };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { n as handleFeishuSubagentEnded, r as handleFeishuSubagentSpawning, t as handleFeishuSubagentDeliveryTarget } from "./subagent-hooks-C3UhPVLV.js";
|
|
2
|
+
//#region extensions/feishu/subagent-hooks-api.ts
|
|
3
|
+
let feishuSubagentHooksPromise = null;
|
|
4
|
+
function loadFeishuSubagentHooksModule() {
|
|
5
|
+
feishuSubagentHooksPromise ??= import("./subagent-hooks-C3UhPVLV.js").then((n) => n.i);
|
|
6
|
+
return feishuSubagentHooksPromise;
|
|
7
|
+
}
|
|
8
|
+
function registerFeishuSubagentHooks(api) {
|
|
9
|
+
api.on("subagent_spawning", async (event, ctx) => {
|
|
10
|
+
const { handleFeishuSubagentSpawning } = await loadFeishuSubagentHooksModule();
|
|
11
|
+
return await handleFeishuSubagentSpawning(event, ctx);
|
|
12
|
+
});
|
|
13
|
+
api.on("subagent_delivery_target", async (event) => {
|
|
14
|
+
const { handleFeishuSubagentDeliveryTarget } = await loadFeishuSubagentHooksModule();
|
|
15
|
+
return handleFeishuSubagentDeliveryTarget(event);
|
|
16
|
+
});
|
|
17
|
+
api.on("subagent_ended", async (event) => {
|
|
18
|
+
const { handleFeishuSubagentEnded } = await loadFeishuSubagentHooksModule();
|
|
19
|
+
handleFeishuSubagentEnded(event);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { handleFeishuSubagentDeliveryTarget, handleFeishuSubagentEnded, handleFeishuSubagentSpawning, registerFeishuSubagentHooks };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
|
2
|
+
//#region extensions/feishu/src/targets.ts
|
|
3
|
+
const CHAT_ID_PREFIX = "oc_";
|
|
4
|
+
const OPEN_ID_PREFIX = "ou_";
|
|
5
|
+
const USER_ID_REGEX = /^[a-zA-Z0-9_-]+$/;
|
|
6
|
+
function stripProviderPrefix(raw) {
|
|
7
|
+
return raw.replace(/^(feishu|lark):/i, "").trim();
|
|
8
|
+
}
|
|
9
|
+
function detectIdType(id) {
|
|
10
|
+
const trimmed = id.trim();
|
|
11
|
+
if (trimmed.startsWith(CHAT_ID_PREFIX)) return "chat_id";
|
|
12
|
+
if (trimmed.startsWith(OPEN_ID_PREFIX)) return "open_id";
|
|
13
|
+
if (USER_ID_REGEX.test(trimmed)) return "user_id";
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
function normalizeFeishuTarget(raw) {
|
|
17
|
+
const trimmed = raw.trim();
|
|
18
|
+
if (!trimmed) return null;
|
|
19
|
+
const withoutProvider = stripProviderPrefix(trimmed);
|
|
20
|
+
const lowered = normalizeLowercaseStringOrEmpty(withoutProvider);
|
|
21
|
+
if (lowered.startsWith("chat:")) return withoutProvider.slice(5).trim() || null;
|
|
22
|
+
if (lowered.startsWith("group:")) return withoutProvider.slice(6).trim() || null;
|
|
23
|
+
if (lowered.startsWith("channel:")) return withoutProvider.slice(8).trim() || null;
|
|
24
|
+
if (lowered.startsWith("user:")) return withoutProvider.slice(5).trim() || null;
|
|
25
|
+
if (lowered.startsWith("dm:")) return withoutProvider.slice(3).trim() || null;
|
|
26
|
+
if (lowered.startsWith("open_id:")) return withoutProvider.slice(8).trim() || null;
|
|
27
|
+
return withoutProvider;
|
|
28
|
+
}
|
|
29
|
+
function resolveReceiveIdType(id) {
|
|
30
|
+
const trimmed = id.trim();
|
|
31
|
+
const lowered = normalizeLowercaseStringOrEmpty(trimmed);
|
|
32
|
+
if (lowered.startsWith("chat:") || lowered.startsWith("group:") || lowered.startsWith("channel:")) return "chat_id";
|
|
33
|
+
if (lowered.startsWith("open_id:")) return "open_id";
|
|
34
|
+
if (lowered.startsWith("user:") || lowered.startsWith("dm:")) return trimmed.replace(/^(user|dm):/i, "").trim().startsWith(OPEN_ID_PREFIX) ? "open_id" : "user_id";
|
|
35
|
+
if (trimmed.startsWith(CHAT_ID_PREFIX)) return "chat_id";
|
|
36
|
+
if (trimmed.startsWith(OPEN_ID_PREFIX)) return "open_id";
|
|
37
|
+
return "user_id";
|
|
38
|
+
}
|
|
39
|
+
function looksLikeFeishuId(raw) {
|
|
40
|
+
const trimmed = stripProviderPrefix(raw.trim());
|
|
41
|
+
if (!trimmed) return false;
|
|
42
|
+
if (/^(chat|group|channel|user|dm|open_id):/i.test(trimmed)) return true;
|
|
43
|
+
if (trimmed.startsWith(CHAT_ID_PREFIX)) return true;
|
|
44
|
+
if (trimmed.startsWith(OPEN_ID_PREFIX)) return true;
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { resolveReceiveIdType as i, looksLikeFeishuId as n, normalizeFeishuTarget as r, detectIdType as t };
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
|
2
|
+
import { registerSessionBindingAdapter, resolveThreadBindingConversationIdFromBindingId, resolveThreadBindingIdleTimeoutMsForChannel, resolveThreadBindingMaxAgeMsForChannel, unregisterSessionBindingAdapter } from "openclaw/plugin-sdk/conversation-runtime";
|
|
3
|
+
import { normalizeAccountId, resolveAgentIdFromSessionKey } from "openclaw/plugin-sdk/routing";
|
|
4
|
+
//#region extensions/feishu/src/thread-bindings.ts
|
|
5
|
+
const FEISHU_THREAD_BINDINGS_STATE_KEY = Symbol.for("openclaw.feishuThreadBindingsState");
|
|
6
|
+
let state;
|
|
7
|
+
function getState() {
|
|
8
|
+
if (!state) {
|
|
9
|
+
const globalStore = globalThis;
|
|
10
|
+
state = globalStore[FEISHU_THREAD_BINDINGS_STATE_KEY] ?? {
|
|
11
|
+
managersByAccountId: /* @__PURE__ */ new Map(),
|
|
12
|
+
bindingsByAccountConversation: /* @__PURE__ */ new Map()
|
|
13
|
+
};
|
|
14
|
+
globalStore[FEISHU_THREAD_BINDINGS_STATE_KEY] = state;
|
|
15
|
+
}
|
|
16
|
+
return state;
|
|
17
|
+
}
|
|
18
|
+
function resolveBindingKey(params) {
|
|
19
|
+
return `${params.accountId}:${params.conversationId}`;
|
|
20
|
+
}
|
|
21
|
+
function toSessionBindingTargetKind(raw) {
|
|
22
|
+
return raw === "subagent" ? "subagent" : "session";
|
|
23
|
+
}
|
|
24
|
+
function toFeishuTargetKind(raw) {
|
|
25
|
+
return raw === "subagent" ? "subagent" : "acp";
|
|
26
|
+
}
|
|
27
|
+
function toSessionBindingRecord(record, defaults) {
|
|
28
|
+
const idleExpiresAt = defaults.idleTimeoutMs > 0 ? record.lastActivityAt + defaults.idleTimeoutMs : void 0;
|
|
29
|
+
const maxAgeExpiresAt = defaults.maxAgeMs > 0 ? record.boundAt + defaults.maxAgeMs : void 0;
|
|
30
|
+
const expiresAt = idleExpiresAt != null && maxAgeExpiresAt != null ? Math.min(idleExpiresAt, maxAgeExpiresAt) : idleExpiresAt ?? maxAgeExpiresAt;
|
|
31
|
+
return {
|
|
32
|
+
bindingId: resolveBindingKey({
|
|
33
|
+
accountId: record.accountId,
|
|
34
|
+
conversationId: record.conversationId
|
|
35
|
+
}),
|
|
36
|
+
targetSessionKey: record.targetSessionKey,
|
|
37
|
+
targetKind: toSessionBindingTargetKind(record.targetKind),
|
|
38
|
+
conversation: {
|
|
39
|
+
channel: "feishu",
|
|
40
|
+
accountId: record.accountId,
|
|
41
|
+
conversationId: record.conversationId,
|
|
42
|
+
parentConversationId: record.parentConversationId
|
|
43
|
+
},
|
|
44
|
+
status: "active",
|
|
45
|
+
boundAt: record.boundAt,
|
|
46
|
+
expiresAt,
|
|
47
|
+
metadata: {
|
|
48
|
+
agentId: record.agentId,
|
|
49
|
+
label: record.label,
|
|
50
|
+
boundBy: record.boundBy,
|
|
51
|
+
deliveryTo: record.deliveryTo,
|
|
52
|
+
deliveryThreadId: record.deliveryThreadId,
|
|
53
|
+
lastActivityAt: record.lastActivityAt,
|
|
54
|
+
idleTimeoutMs: defaults.idleTimeoutMs,
|
|
55
|
+
maxAgeMs: defaults.maxAgeMs
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function createFeishuThreadBindingManager(params) {
|
|
60
|
+
const accountId = normalizeAccountId(params.accountId);
|
|
61
|
+
const existing = getState().managersByAccountId.get(accountId);
|
|
62
|
+
if (existing) return existing;
|
|
63
|
+
const idleTimeoutMs = resolveThreadBindingIdleTimeoutMsForChannel({
|
|
64
|
+
cfg: params.cfg,
|
|
65
|
+
channel: "feishu",
|
|
66
|
+
accountId
|
|
67
|
+
});
|
|
68
|
+
const maxAgeMs = resolveThreadBindingMaxAgeMsForChannel({
|
|
69
|
+
cfg: params.cfg,
|
|
70
|
+
channel: "feishu",
|
|
71
|
+
accountId
|
|
72
|
+
});
|
|
73
|
+
const manager = {
|
|
74
|
+
accountId,
|
|
75
|
+
getByConversationId: (conversationId) => getState().bindingsByAccountConversation.get(resolveBindingKey({
|
|
76
|
+
accountId,
|
|
77
|
+
conversationId
|
|
78
|
+
})),
|
|
79
|
+
listBySessionKey: (targetSessionKey) => [...getState().bindingsByAccountConversation.values()].filter((record) => record.accountId === accountId && record.targetSessionKey === targetSessionKey),
|
|
80
|
+
bindConversation: ({ conversationId, parentConversationId, targetKind, targetSessionKey, metadata }) => {
|
|
81
|
+
const normalizedConversationId = conversationId.trim();
|
|
82
|
+
const normalizedTargetSessionKey = targetSessionKey.trim();
|
|
83
|
+
if (!normalizedConversationId || !normalizedTargetSessionKey) return null;
|
|
84
|
+
const existing = getState().bindingsByAccountConversation.get(resolveBindingKey({
|
|
85
|
+
accountId,
|
|
86
|
+
conversationId: normalizedConversationId
|
|
87
|
+
}));
|
|
88
|
+
const now = Date.now();
|
|
89
|
+
const record = {
|
|
90
|
+
accountId,
|
|
91
|
+
conversationId: normalizedConversationId,
|
|
92
|
+
parentConversationId: normalizeOptionalString(parentConversationId) ?? existing?.parentConversationId,
|
|
93
|
+
deliveryTo: typeof metadata?.deliveryTo === "string" && metadata.deliveryTo.trim() ? metadata.deliveryTo.trim() : existing?.deliveryTo,
|
|
94
|
+
deliveryThreadId: typeof metadata?.deliveryThreadId === "string" && metadata.deliveryThreadId.trim() ? metadata.deliveryThreadId.trim() : existing?.deliveryThreadId,
|
|
95
|
+
targetKind: toFeishuTargetKind(targetKind),
|
|
96
|
+
targetSessionKey: normalizedTargetSessionKey,
|
|
97
|
+
agentId: typeof metadata?.agentId === "string" && metadata.agentId.trim() ? metadata.agentId.trim() : existing?.agentId ?? resolveAgentIdFromSessionKey(normalizedTargetSessionKey),
|
|
98
|
+
label: typeof metadata?.label === "string" && metadata.label.trim() ? metadata.label.trim() : existing?.label,
|
|
99
|
+
boundBy: typeof metadata?.boundBy === "string" && metadata.boundBy.trim() ? metadata.boundBy.trim() : existing?.boundBy,
|
|
100
|
+
boundAt: now,
|
|
101
|
+
lastActivityAt: now
|
|
102
|
+
};
|
|
103
|
+
getState().bindingsByAccountConversation.set(resolveBindingKey({
|
|
104
|
+
accountId,
|
|
105
|
+
conversationId: normalizedConversationId
|
|
106
|
+
}), record);
|
|
107
|
+
return record;
|
|
108
|
+
},
|
|
109
|
+
touchConversation: (conversationId, at = Date.now()) => {
|
|
110
|
+
const key = resolveBindingKey({
|
|
111
|
+
accountId,
|
|
112
|
+
conversationId
|
|
113
|
+
});
|
|
114
|
+
const existingRecord = getState().bindingsByAccountConversation.get(key);
|
|
115
|
+
if (!existingRecord) return null;
|
|
116
|
+
const updated = {
|
|
117
|
+
...existingRecord,
|
|
118
|
+
lastActivityAt: at
|
|
119
|
+
};
|
|
120
|
+
getState().bindingsByAccountConversation.set(key, updated);
|
|
121
|
+
return updated;
|
|
122
|
+
},
|
|
123
|
+
unbindConversation: (conversationId) => {
|
|
124
|
+
const key = resolveBindingKey({
|
|
125
|
+
accountId,
|
|
126
|
+
conversationId
|
|
127
|
+
});
|
|
128
|
+
const existingRecord = getState().bindingsByAccountConversation.get(key);
|
|
129
|
+
if (!existingRecord) return null;
|
|
130
|
+
getState().bindingsByAccountConversation.delete(key);
|
|
131
|
+
return existingRecord;
|
|
132
|
+
},
|
|
133
|
+
unbindBySessionKey: (targetSessionKey) => {
|
|
134
|
+
const removed = [];
|
|
135
|
+
for (const record of getState().bindingsByAccountConversation.values()) {
|
|
136
|
+
if (record.accountId !== accountId || record.targetSessionKey !== targetSessionKey) continue;
|
|
137
|
+
getState().bindingsByAccountConversation.delete(resolveBindingKey({
|
|
138
|
+
accountId,
|
|
139
|
+
conversationId: record.conversationId
|
|
140
|
+
}));
|
|
141
|
+
removed.push(record);
|
|
142
|
+
}
|
|
143
|
+
return removed;
|
|
144
|
+
},
|
|
145
|
+
stop: () => {
|
|
146
|
+
for (const key of getState().bindingsByAccountConversation.keys()) if (key.startsWith(`${accountId}:`)) getState().bindingsByAccountConversation.delete(key);
|
|
147
|
+
getState().managersByAccountId.delete(accountId);
|
|
148
|
+
unregisterSessionBindingAdapter({
|
|
149
|
+
channel: "feishu",
|
|
150
|
+
accountId,
|
|
151
|
+
adapter: sessionBindingAdapter
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
const sessionBindingAdapter = {
|
|
156
|
+
channel: "feishu",
|
|
157
|
+
accountId,
|
|
158
|
+
capabilities: { placements: ["current"] },
|
|
159
|
+
bind: async (input) => {
|
|
160
|
+
if (input.conversation.channel !== "feishu" || input.placement === "child") return null;
|
|
161
|
+
const bound = manager.bindConversation({
|
|
162
|
+
conversationId: input.conversation.conversationId,
|
|
163
|
+
parentConversationId: input.conversation.parentConversationId,
|
|
164
|
+
targetKind: input.targetKind,
|
|
165
|
+
targetSessionKey: input.targetSessionKey,
|
|
166
|
+
metadata: input.metadata
|
|
167
|
+
});
|
|
168
|
+
return bound ? toSessionBindingRecord(bound, {
|
|
169
|
+
idleTimeoutMs,
|
|
170
|
+
maxAgeMs
|
|
171
|
+
}) : null;
|
|
172
|
+
},
|
|
173
|
+
listBySession: (targetSessionKey) => manager.listBySessionKey(targetSessionKey).map((entry) => toSessionBindingRecord(entry, {
|
|
174
|
+
idleTimeoutMs,
|
|
175
|
+
maxAgeMs
|
|
176
|
+
})),
|
|
177
|
+
resolveByConversation: (ref) => {
|
|
178
|
+
if (ref.channel !== "feishu") return null;
|
|
179
|
+
const found = manager.getByConversationId(ref.conversationId);
|
|
180
|
+
return found ? toSessionBindingRecord(found, {
|
|
181
|
+
idleTimeoutMs,
|
|
182
|
+
maxAgeMs
|
|
183
|
+
}) : null;
|
|
184
|
+
},
|
|
185
|
+
touch: (bindingId, at) => {
|
|
186
|
+
const conversationId = resolveThreadBindingConversationIdFromBindingId({
|
|
187
|
+
accountId,
|
|
188
|
+
bindingId
|
|
189
|
+
});
|
|
190
|
+
if (conversationId) manager.touchConversation(conversationId, at);
|
|
191
|
+
},
|
|
192
|
+
unbind: async (input) => {
|
|
193
|
+
if (input.targetSessionKey?.trim()) return manager.unbindBySessionKey(input.targetSessionKey.trim()).map((entry) => toSessionBindingRecord(entry, {
|
|
194
|
+
idleTimeoutMs,
|
|
195
|
+
maxAgeMs
|
|
196
|
+
}));
|
|
197
|
+
const conversationId = resolveThreadBindingConversationIdFromBindingId({
|
|
198
|
+
accountId,
|
|
199
|
+
bindingId: input.bindingId
|
|
200
|
+
});
|
|
201
|
+
if (!conversationId) return [];
|
|
202
|
+
const removed = manager.unbindConversation(conversationId);
|
|
203
|
+
return removed ? [toSessionBindingRecord(removed, {
|
|
204
|
+
idleTimeoutMs,
|
|
205
|
+
maxAgeMs
|
|
206
|
+
})] : [];
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
registerSessionBindingAdapter(sessionBindingAdapter);
|
|
210
|
+
getState().managersByAccountId.set(accountId, manager);
|
|
211
|
+
return manager;
|
|
212
|
+
}
|
|
213
|
+
function getFeishuThreadBindingManager(accountId) {
|
|
214
|
+
return getState().managersByAccountId.get(normalizeAccountId(accountId)) ?? null;
|
|
215
|
+
}
|
|
216
|
+
const __testing = { resetFeishuThreadBindingsForTests() {
|
|
217
|
+
for (const manager of getState().managersByAccountId.values()) manager.stop();
|
|
218
|
+
getState().managersByAccountId.clear();
|
|
219
|
+
getState().bindingsByAccountConversation.clear();
|
|
220
|
+
} };
|
|
221
|
+
//#endregion
|
|
222
|
+
export { createFeishuThreadBindingManager as n, getFeishuThreadBindingManager as r, __testing as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/feishu",
|
|
3
|
-
"version": "2026.5.2",
|
|
3
|
+
"version": "2026.5.3-beta.2",
|
|
4
4
|
"description": "OpenClaw Feishu/Lark channel plugin (community maintained by @m1heng)",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"openclaw": "workspace:*"
|
|
17
17
|
},
|
|
18
18
|
"peerDependencies": {
|
|
19
|
-
"openclaw": ">=2026.5.2"
|
|
19
|
+
"openclaw": ">=2026.5.3-beta.2"
|
|
20
20
|
},
|
|
21
21
|
"peerDependenciesMeta": {
|
|
22
22
|
"openclaw": {
|
|
@@ -47,14 +47,23 @@
|
|
|
47
47
|
"minHostVersion": ">=2026.4.25"
|
|
48
48
|
},
|
|
49
49
|
"compat": {
|
|
50
|
-
"pluginApi": ">=2026.5.2"
|
|
50
|
+
"pluginApi": ">=2026.5.3-beta.2"
|
|
51
51
|
},
|
|
52
52
|
"build": {
|
|
53
|
-
"openclawVersion": "2026.5.2"
|
|
53
|
+
"openclawVersion": "2026.5.3-beta.2"
|
|
54
54
|
},
|
|
55
55
|
"release": {
|
|
56
56
|
"publishToClawHub": true,
|
|
57
57
|
"publishToNpm": true
|
|
58
|
-
}
|
|
59
|
-
|
|
58
|
+
},
|
|
59
|
+
"runtimeExtensions": [
|
|
60
|
+
"./dist/index.js"
|
|
61
|
+
],
|
|
62
|
+
"runtimeSetupEntry": "./dist/setup-entry.js"
|
|
63
|
+
},
|
|
64
|
+
"files": [
|
|
65
|
+
"dist/**",
|
|
66
|
+
"openclaw.plugin.json",
|
|
67
|
+
"skills/**"
|
|
68
|
+
]
|
|
60
69
|
}
|
package/api.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export { feishuPlugin } from "./src/channel.js";
|
|
2
|
-
export { registerFeishuDocTools } from "./src/docx.js";
|
|
3
|
-
export { registerFeishuChatTools } from "./src/chat.js";
|
|
4
|
-
export { registerFeishuWikiTools } from "./src/wiki.js";
|
|
5
|
-
export { registerFeishuDriveTools } from "./src/drive.js";
|
|
6
|
-
export { registerFeishuPermTools } from "./src/perm.js";
|
|
7
|
-
export { registerFeishuBitableTools } from "./src/bitable.js";
|
|
8
|
-
export {
|
|
9
|
-
handleFeishuSubagentDeliveryTarget,
|
|
10
|
-
handleFeishuSubagentEnded,
|
|
11
|
-
handleFeishuSubagentSpawning,
|
|
12
|
-
} from "./src/subagent-hooks.js";
|
|
13
|
-
export {
|
|
14
|
-
buildFeishuConversationId,
|
|
15
|
-
buildFeishuModelOverrideParentCandidates,
|
|
16
|
-
type FeishuGroupSessionScope,
|
|
17
|
-
parseFeishuConversationId,
|
|
18
|
-
parseFeishuDirectConversationId,
|
|
19
|
-
parseFeishuTargetId,
|
|
20
|
-
} from "./src/conversation-id.js";
|
|
21
|
-
export { feishuSetupAdapter, setFeishuNamedAccountEnabled } from "./src/setup-core.js";
|
|
22
|
-
export { feishuSetupWizard, runFeishuLogin } from "./src/setup-surface.js";
|
|
23
|
-
export {
|
|
24
|
-
__testing,
|
|
25
|
-
createFeishuThreadBindingManager,
|
|
26
|
-
getFeishuThreadBindingManager,
|
|
27
|
-
} from "./src/thread-bindings.js";
|
|
28
|
-
export { __testing as feishuThreadBindingTesting } from "./src/thread-bindings.js";
|
|
29
|
-
export { createClackPrompter } from "openclaw/plugin-sdk/setup-runtime";
|
|
30
|
-
|
|
31
|
-
export const feishuSessionBindingAdapterChannels = ["feishu"] as const;
|
package/channel-entry.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { defineBundledChannelEntry } from "openclaw/plugin-sdk/channel-entry-contract";
|
|
2
|
-
|
|
3
|
-
export default defineBundledChannelEntry({
|
|
4
|
-
id: "feishu",
|
|
5
|
-
name: "Feishu",
|
|
6
|
-
description: "Feishu/Lark channel plugin",
|
|
7
|
-
importMetaUrl: import.meta.url,
|
|
8
|
-
plugin: {
|
|
9
|
-
specifier: "./api.js",
|
|
10
|
-
exportName: "feishuPlugin",
|
|
11
|
-
},
|
|
12
|
-
secrets: {
|
|
13
|
-
specifier: "./secret-contract-api.js",
|
|
14
|
-
exportName: "channelSecrets",
|
|
15
|
-
},
|
|
16
|
-
runtime: {
|
|
17
|
-
specifier: "./runtime-api.js",
|
|
18
|
-
exportName: "setFeishuRuntime",
|
|
19
|
-
},
|
|
20
|
-
});
|
package/channel-plugin-api.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { feishuPlugin } from "./src/channel.js";
|