@openclaw/feishu 2026.9.8 → 2026.10.1-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/.setup/{channel-DV4hM2Uf.mjs → channel-CX62T71S.mjs} +146 -245
- package/dist/.setup/{channel.runtime-CXQcH5zZ.mjs → channel.runtime-COiaq-Rv.mjs} +6 -12
- package/dist/.setup/{chat-D8MlFAZi.mjs → chat-BdyvImsY.mjs} +6 -9
- package/dist/.setup/{client-BYG-_IZl.mjs → client-BsBVWJzN.mjs} +1 -1
- package/dist/.setup/{doctor-contract-3XC0vbIw.mjs → doctor-contract-B1B9ogdd.mjs} +212 -27
- package/dist/.setup/{monitor-D_rsHBZ6.mjs → monitor-7DvwUs4Y.mjs} +5 -6
- package/dist/.setup/{monitor.account-DvvY7i6k.mjs → monitor.account-7xVu7XWY.mjs} +190 -393
- package/dist/.setup/{probe-_ViqSi0j.mjs → probe-B9o7iey6.mjs} +13 -39
- package/dist/.setup/{reply-delivery-result-COAjaukc.mjs → reply-delivery-result-Bt-BWBEA.mjs} +151 -297
- package/dist/.setup/{setup-api-C4S5I3ac.mjs → setup-api-DmzX9S01.mjs} +1 -1
- package/dist/.setup/{subagent-hooks-BaFoMu8W.mjs → subagent-hooks-CUXg0pC-.mjs} +5 -11
- package/dist/.setup/{thread-bindings-EdLXPXzw.mjs → thread-bindings-jW2x5VuN.mjs} +23 -41
- package/dist/api.js +234 -297
- package/dist/channel-plugin-api.js +1 -1
- package/dist/doctor-contract-api.js +2 -2
- package/dist/session-binding-contract-api.js +1 -1
- package/dist/setup-api.js +1 -1
- package/dist/setup-entry.js +1 -1
- package/dist/subagent-hooks-api.js +1 -1
- package/node_modules/@openclaw/fs-safe/CHANGELOG.md +95 -0
- package/node_modules/@openclaw/fs-safe/README.md +70 -379
- package/node_modules/@openclaw/fs-safe/dist/absolute-path.js +35 -51
- package/node_modules/@openclaw/fs-safe/dist/advanced.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/advanced.js +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-input.js +2 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-parser.wasm +0 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-staging.d.ts +1 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-staging.js +9 -10
- package/node_modules/@openclaw/fs-safe/dist/archive.js +2 -5
- package/node_modules/@openclaw/fs-safe/dist/atomic-io.d.ts +51 -0
- package/node_modules/@openclaw/fs-safe/dist/atomic-io.js +242 -0
- package/node_modules/@openclaw/fs-safe/dist/config.d.ts +1 -1
- package/node_modules/@openclaw/fs-safe/dist/config.js +1 -1
- package/node_modules/@openclaw/fs-safe/dist/copy-file-input.d.ts +1 -1
- package/node_modules/@openclaw/fs-safe/dist/copy-file-input.js +2 -2
- package/node_modules/@openclaw/fs-safe/dist/copy-tree-portable.js +2 -0
- package/node_modules/@openclaw/fs-safe/dist/create.js +12 -5
- package/node_modules/@openclaw/fs-safe/dist/directory-guard.d.ts +11 -0
- package/node_modules/@openclaw/fs-safe/dist/directory-guard.js +4 -7
- package/node_modules/@openclaw/fs-safe/dist/entry-publication-types.d.ts +55 -0
- package/node_modules/@openclaw/fs-safe/dist/entry-publication-types.js +1 -0
- package/node_modules/@openclaw/fs-safe/dist/entry-publication.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/entry-publication.js +262 -0
- package/node_modules/@openclaw/fs-safe/dist/exclusive-create.d.ts +3 -0
- package/node_modules/@openclaw/fs-safe/dist/exclusive-create.js +22 -0
- package/node_modules/@openclaw/fs-safe/dist/file-cleanup.d.ts +1 -6
- package/node_modules/@openclaw/fs-safe/dist/file-cleanup.js +3 -6
- package/node_modules/@openclaw/fs-safe/dist/file-identity.js +3 -6
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-io.js +2 -2
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-mutation.js +9 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root.js +4 -6
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-stale-admission.js +1 -1
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync.js +8 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store-boundary.js +2 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store-sync-write.js +20 -18
- package/node_modules/@openclaw/fs-safe/dist/file-store.js +4 -10
- package/node_modules/@openclaw/fs-safe/dist/fs.d.ts +2 -10
- package/node_modules/@openclaw/fs-safe/dist/fs.js +2 -10
- package/node_modules/@openclaw/fs-safe/dist/guarded-mkdir.d.ts +3 -4
- package/node_modules/@openclaw/fs-safe/dist/guarded-mkdir.js +6 -18
- package/node_modules/@openclaw/fs-safe/dist/guest-dispatch-python.js +1 -1
- package/node_modules/@openclaw/fs-safe/dist/guest-native-python.js +0 -2
- package/node_modules/@openclaw/fs-safe/dist/guest.js +3 -9
- package/node_modules/@openclaw/fs-safe/dist/index.d.ts +1 -1
- package/node_modules/@openclaw/fs-safe/dist/index.js +1 -1
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-directory.js +1 -5
- package/node_modules/@openclaw/fs-safe/dist/json.js +19 -37
- package/node_modules/@openclaw/fs-safe/dist/move-path.js +2 -0
- package/node_modules/@openclaw/fs-safe/dist/mutation-authority.d.ts +1 -0
- package/node_modules/@openclaw/fs-safe/dist/mutation-authority.js +9 -1
- package/node_modules/@openclaw/fs-safe/dist/native-binding.d.ts +47 -2
- package/node_modules/@openclaw/fs-safe/dist/native-config.d.ts +1 -9
- package/node_modules/@openclaw/fs-safe/dist/native-config.js +6 -40
- package/node_modules/@openclaw/fs-safe/dist/native-parent-admission.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/native-parent-admission.js +5 -2
- package/node_modules/@openclaw/fs-safe/dist/native-pinned-write.js +11 -316
- package/node_modules/@openclaw/fs-safe/dist/native-policy-parent-windows.d.ts +7 -7
- package/node_modules/@openclaw/fs-safe/dist/native-policy-parent-windows.js +28 -175
- package/node_modules/@openclaw/fs-safe/dist/native-policy-parent.d.ts +15 -0
- package/node_modules/@openclaw/fs-safe/dist/native-policy-parent.js +418 -0
- package/node_modules/@openclaw/fs-safe/dist/native-rename-outcome.js +9 -4
- package/node_modules/@openclaw/fs-safe/dist/native-staged-file.js +17 -13
- package/node_modules/@openclaw/fs-safe/dist/native-staged-symlink.js +6 -24
- package/node_modules/@openclaw/fs-safe/dist/native.js +5 -1
- package/node_modules/@openclaw/fs-safe/dist/path-case.js +10 -9
- package/node_modules/@openclaw/fs-safe/dist/path-scope-lexical.js +4 -1
- package/node_modules/@openclaw/fs-safe/dist/path-segment-route.d.ts +1 -0
- package/node_modules/@openclaw/fs-safe/dist/path-segment-route.js +3 -0
- package/node_modules/@openclaw/fs-safe/dist/path.js +4 -1
- package/node_modules/@openclaw/fs-safe/dist/permissions-windows.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/pinned-mutation-admission.js +1 -3
- package/node_modules/@openclaw/fs-safe/dist/pinned-write-staged.js +2 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-write.js +9 -10
- package/node_modules/@openclaw/fs-safe/dist/private-producer-handoff.js +3 -6
- package/node_modules/@openclaw/fs-safe/dist/publish-copy-stage.js +2 -2
- package/node_modules/@openclaw/fs-safe/dist/publish-file.js +4 -3
- package/node_modules/@openclaw/fs-safe/dist/replace-file-buffer.d.ts +3 -4
- package/node_modules/@openclaw/fs-safe/dist/replace-file-buffer.js +18 -32
- package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-fallback.d.ts +5 -17
- package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-fallback.js +92 -230
- package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-source.d.ts +4 -15
- package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-source.js +22 -63
- package/node_modules/@openclaw/fs-safe/dist/replace-file-descriptor.d.ts +9 -34
- package/node_modules/@openclaw/fs-safe/dist/replace-file-descriptor.js +78 -83
- package/node_modules/@openclaw/fs-safe/dist/replace-file-destination.d.ts +18 -20
- package/node_modules/@openclaw/fs-safe/dist/replace-file-destination.js +64 -98
- package/node_modules/@openclaw/fs-safe/dist/replace-file-temp-owner.d.ts +16 -33
- package/node_modules/@openclaw/fs-safe/dist/replace-file-temp-owner.js +61 -200
- package/node_modules/@openclaw/fs-safe/dist/replace-file-types.d.ts +1 -6
- package/node_modules/@openclaw/fs-safe/dist/replace-file.js +76 -216
- package/node_modules/@openclaw/fs-safe/dist/root-boundary.js +14 -24
- package/node_modules/@openclaw/fs-safe/dist/root-context.d.ts +1 -4
- package/node_modules/@openclaw/fs-safe/dist/root-context.js +4 -19
- package/node_modules/@openclaw/fs-safe/dist/root-create-native.d.ts +52 -0
- package/node_modules/@openclaw/fs-safe/dist/root-create-native.js +350 -0
- package/node_modules/@openclaw/fs-safe/dist/root-directory-list-types.d.ts +35 -0
- package/node_modules/@openclaw/fs-safe/dist/root-directory-list-types.js +1 -0
- package/node_modules/@openclaw/fs-safe/dist/root-directory-list.d.ts +2 -27
- package/node_modules/@openclaw/fs-safe/dist/root-directory-list.js +31 -28
- package/node_modules/@openclaw/fs-safe/dist/root-directory.js +1 -4
- package/node_modules/@openclaw/fs-safe/dist/root-errors.js +34 -0
- package/node_modules/@openclaw/fs-safe/dist/root-file.js +9 -21
- package/node_modules/@openclaw/fs-safe/dist/root-impl.js +105 -37
- package/node_modules/@openclaw/fs-safe/dist/root-move-noreplace.d.ts +7 -2
- package/node_modules/@openclaw/fs-safe/dist/root-move-noreplace.js +67 -38
- package/node_modules/@openclaw/fs-safe/dist/root-observed-path.d.ts +1 -1
- package/node_modules/@openclaw/fs-safe/dist/root-observed-path.js +0 -2
- package/node_modules/@openclaw/fs-safe/dist/root-options.d.ts +2 -3
- package/node_modules/@openclaw/fs-safe/dist/root-path-existing.js +3 -1
- package/node_modules/@openclaw/fs-safe/dist/root-path-stat.js +68 -85
- package/node_modules/@openclaw/fs-safe/dist/root-path.js +6 -1
- package/node_modules/@openclaw/fs-safe/dist/root-paths-lexical.d.ts +4 -0
- package/node_modules/@openclaw/fs-safe/dist/root-paths-lexical.js +1 -1
- package/node_modules/@openclaw/fs-safe/dist/root-paths.js +4 -9
- package/node_modules/@openclaw/fs-safe/dist/root-remove-native.d.ts +4 -0
- package/node_modules/@openclaw/fs-safe/dist/root-remove-native.js +311 -0
- package/node_modules/@openclaw/fs-safe/dist/root-remove.d.ts +11 -0
- package/node_modules/@openclaw/fs-safe/dist/root-remove.js +3 -1
- package/node_modules/@openclaw/fs-safe/dist/root-walk.d.ts +2 -2
- package/node_modules/@openclaw/fs-safe/dist/root-walk.js +1 -3
- package/node_modules/@openclaw/fs-safe/dist/root-write-admission.d.ts +3 -3
- package/node_modules/@openclaw/fs-safe/dist/root-write-admission.js +8 -10
- package/node_modules/@openclaw/fs-safe/dist/safe-path-segment.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/safe-path-segment.js +0 -4
- package/node_modules/@openclaw/fs-safe/dist/secret-file.js +12 -9
- package/node_modules/@openclaw/fs-safe/dist/secure-temp-dir.d.ts +0 -2
- package/node_modules/@openclaw/fs-safe/dist/sibling-staged-file.js +2 -0
- package/node_modules/@openclaw/fs-safe/dist/sibling-temp.js +7 -4
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-acquire.js +13 -6
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.d.ts +0 -3
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.js +5 -23
- package/node_modules/@openclaw/fs-safe/dist/staged-file-settlement.d.ts +2 -1
- package/node_modules/@openclaw/fs-safe/dist/staged-file-settlement.js +11 -6
- package/node_modules/@openclaw/fs-safe/dist/temp-cleanup.js +1 -8
- package/node_modules/@openclaw/fs-safe/dist/temp-workspace-child-admission.d.ts +1 -1
- package/node_modules/@openclaw/fs-safe/dist/temp-workspace-child-admission.js +2 -9
- package/node_modules/@openclaw/fs-safe/dist/text-atomic.d.ts +1 -6
- package/node_modules/@openclaw/fs-safe/dist/trash.js +6 -2
- package/node_modules/@openclaw/fs-safe/dist/walk.js +100 -46
- package/node_modules/@openclaw/fs-safe/dist/watch-hints.d.ts +7 -0
- package/node_modules/@openclaw/fs-safe/dist/watch-hints.js +235 -19
- package/node_modules/@openclaw/fs-safe/dist/watch-native.d.ts +21 -2
- package/node_modules/@openclaw/fs-safe/dist/watch-native.js +21 -3
- package/node_modules/@openclaw/fs-safe/dist/watch-rescan.d.ts +6 -0
- package/node_modules/@openclaw/fs-safe/dist/watch-rescan.js +111 -0
- package/node_modules/@openclaw/fs-safe/dist/watch-scan.d.ts +13 -0
- package/node_modules/@openclaw/fs-safe/dist/watch-scan.js +27 -4
- package/node_modules/@openclaw/fs-safe/dist/watch-stream.js +2 -0
- package/node_modules/@openclaw/fs-safe/dist/watch.js +131 -40
- package/node_modules/@openclaw/fs-safe/dist/windows-path-alias.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-path-alias.js +24 -6
- package/node_modules/@openclaw/fs-safe/dist/windows-path-syntax.d.ts +13 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-path-syntax.js +51 -0
- package/node_modules/@openclaw/fs-safe/docs/advanced.md +4 -0
- package/node_modules/@openclaw/fs-safe/docs/atomic.md +4 -1
- package/node_modules/@openclaw/fs-safe/docs/config.md +6 -14
- package/node_modules/@openclaw/fs-safe/docs/contributing.md +4 -14
- package/node_modules/@openclaw/fs-safe/docs/durability.md +6 -29
- package/node_modules/@openclaw/fs-safe/docs/entry-publication.md +146 -0
- package/node_modules/@openclaw/fs-safe/docs/errors.md +16 -0
- package/node_modules/@openclaw/fs-safe/docs/file-store.md +28 -5
- package/node_modules/@openclaw/fs-safe/docs/index.md +2 -31
- package/node_modules/@openclaw/fs-safe/docs/install.md +10 -31
- package/node_modules/@openclaw/fs-safe/docs/json.md +1 -1
- package/node_modules/@openclaw/fs-safe/docs/local-roots.md +0 -1
- package/node_modules/@openclaw/fs-safe/docs/migrating-to-0.5.md +12 -12
- package/node_modules/@openclaw/fs-safe/docs/native-helper.md +35 -96
- package/node_modules/@openclaw/fs-safe/docs/native.md +22 -20
- package/node_modules/@openclaw/fs-safe/docs/path.md +1 -1
- package/node_modules/@openclaw/fs-safe/docs/permissions.md +1 -2
- package/node_modules/@openclaw/fs-safe/docs/public-api.md +1 -2
- package/node_modules/@openclaw/fs-safe/docs/reading.md +1 -2
- package/node_modules/@openclaw/fs-safe/docs/root.md +26 -184
- package/node_modules/@openclaw/fs-safe/docs/secret-file.md +1 -1
- package/node_modules/@openclaw/fs-safe/docs/security-model.md +115 -3
- package/node_modules/@openclaw/fs-safe/docs/store.md +2 -2
- package/node_modules/@openclaw/fs-safe/docs/temp.md +29 -65
- package/node_modules/@openclaw/fs-safe/docs/testing.md +90 -58
- package/node_modules/@openclaw/fs-safe/docs/types.md +3 -16
- package/node_modules/@openclaw/fs-safe/docs/walk.md +33 -5
- package/node_modules/@openclaw/fs-safe/docs/watch.md +96 -14
- package/node_modules/@openclaw/fs-safe/docs/writing.md +172 -16
- package/node_modules/@openclaw/fs-safe/package.json +10 -10
- package/node_modules/@openclaw/fs-safe-darwin-arm64/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-darwin-arm64/package.json +1 -1
- package/node_modules/@openclaw/fs-safe-darwin-x64/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-darwin-x64/package.json +1 -1
- package/node_modules/@openclaw/fs-safe-linux-arm64-gnu/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-linux-arm64-gnu/package.json +1 -1
- package/node_modules/@openclaw/fs-safe-linux-arm64-musl/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-linux-arm64-musl/package.json +1 -1
- package/node_modules/@openclaw/fs-safe-linux-x64-gnu/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-linux-x64-gnu/package.json +1 -1
- package/node_modules/@openclaw/fs-safe-linux-x64-musl/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-linux-x64-musl/package.json +1 -1
- package/node_modules/@openclaw/fs-safe-win32-x64-msvc/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-win32-x64-msvc/package.json +1 -1
- package/package.json +5 -5
- package/skills/feishu-wiki/SKILL.md +1 -1
- package/dist/.setup/accounts-wRqItHug.mjs +0 -206
- package/node_modules/@openclaw/fs-safe/dist/watch-alias.d.ts +0 -6
- package/node_modules/@openclaw/fs-safe/dist/watch-alias.js +0 -88
- package/node_modules/@openclaw/fs-safe/docs/mutation-policy-proof.md +0 -69
- package/node_modules/@openclaw/fs-safe/docs/private-file-store.md +0 -68
- package/node_modules/@openclaw/fs-safe/docs/test-hooks.md +0 -110
package/dist/api.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as buildFeishuModelOverrideParentCandidates, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./.setup/conversation-id-C1ofUfU8.mjs";
|
|
2
|
-
import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./.setup/channel-
|
|
3
|
-
import { J as feishuExternalToolResult, K as registerFeishuDriveTools, Q as assertFeishuApiSuccess, X as createFeishuToolClient, Y as unknownToolActionResult, Z as resolveFeishuToolAccount, dt as chunkFeishuMarkdown, mt as parseFeishuMarkdown, q as registerFeishuTool } from "./.setup/reply-delivery-result-
|
|
2
|
+
import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./.setup/channel-CX62T71S.mjs";
|
|
3
|
+
import { J as feishuExternalToolResult, K as registerFeishuDriveTools, Q as assertFeishuApiSuccess, X as createFeishuToolClient, Y as unknownToolActionResult, Z as resolveFeishuToolAccount, dt as chunkFeishuMarkdown, gt as visitFeishuMarkdown, mt as parseFeishuMarkdown, q as registerFeishuTool } from "./.setup/reply-delivery-result-Bt-BWBEA.mjs";
|
|
4
4
|
import { t as getFeishuRuntime } from "./.setup/runtime-C5JxBWZp.mjs";
|
|
5
|
-
import { f as resolveConfiguredHttpTimeoutMs, r as createFeishuClient } from "./.setup/client-
|
|
6
|
-
import { o as registerFeishuChatTools } from "./.setup/chat-
|
|
7
|
-
import { n as getFeishuThreadBindingManager, t as createFeishuThreadBindingManager } from "./.setup/thread-bindings-
|
|
8
|
-
import { n as handleFeishuSubagentEnded, t as handleFeishuSubagentDeliveryTarget } from "./.setup/subagent-hooks-
|
|
5
|
+
import { f as resolveConfiguredHttpTimeoutMs, r as createFeishuClient } from "./.setup/client-BsBVWJzN.mjs";
|
|
6
|
+
import { o as registerFeishuChatTools } from "./.setup/chat-BdyvImsY.mjs";
|
|
7
|
+
import { n as getFeishuThreadBindingManager, t as createFeishuThreadBindingManager } from "./.setup/thread-bindings-jW2x5VuN.mjs";
|
|
8
|
+
import { n as handleFeishuSubagentEnded, t as handleFeishuSubagentDeliveryTarget } from "./.setup/subagent-hooks-CUXg0pC-.mjs";
|
|
9
9
|
import { optionalPositiveIntegerSchema } from "openclaw/plugin-sdk/channel-actions";
|
|
10
10
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
11
11
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, readStringValue, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
@@ -192,14 +192,7 @@ function calculateAdaptiveColumnWidths(blocks, tableBlockId, getBlockMap) {
|
|
|
192
192
|
}
|
|
193
193
|
function getWeightedLength(text) {
|
|
194
194
|
let length = 0;
|
|
195
|
-
for (
|
|
196
|
-
const code = text.charCodeAt(index);
|
|
197
|
-
length += code > 255 ? 2 : 1;
|
|
198
|
-
if (code >= 55296 && code <= 56319) {
|
|
199
|
-
const next = text.charCodeAt(index + 1);
|
|
200
|
-
if (next >= 56320 && next <= 57343) index += 1;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
195
|
+
for (const character of text) length += character.charCodeAt(0) > 255 ? 2 : 1;
|
|
203
196
|
return length;
|
|
204
197
|
}
|
|
205
198
|
const maxLengths = Array.from({ length: column_size }, () => 0);
|
|
@@ -241,17 +234,12 @@ function cleanBlocksForDescendant(blocks) {
|
|
|
241
234
|
}
|
|
242
235
|
return blockMap;
|
|
243
236
|
};
|
|
244
|
-
const tableWidths = /* @__PURE__ */ new Map();
|
|
245
|
-
for (const block of blocks) if (block.block_type === 31 && block.block_id) {
|
|
246
|
-
const widths = calculateAdaptiveColumnWidths(blocks, block.block_id, getBlockMap);
|
|
247
|
-
tableWidths.set(block.block_id, widths);
|
|
248
|
-
}
|
|
249
237
|
return blocks.map((block) => {
|
|
250
238
|
const cleanBlock = { ...block };
|
|
251
239
|
delete cleanBlock.parent_id;
|
|
252
240
|
if (cleanBlock.block_type === 32 && typeof cleanBlock.children === "string") cleanBlock.children = [cleanBlock.children];
|
|
253
241
|
if (cleanBlock.block_type === 31 && cleanBlock.table) {
|
|
254
|
-
const adaptiveWidths = block.block_id ?
|
|
242
|
+
const adaptiveWidths = block.block_id ? calculateAdaptiveColumnWidths(blocks, block.block_id, getBlockMap) : void 0;
|
|
255
243
|
const { row_size, column_size } = cleanBlock.table.property || {};
|
|
256
244
|
cleanBlock.table = { property: {
|
|
257
245
|
row_size,
|
|
@@ -401,10 +389,7 @@ async function insertBlocksInBatches(client, docToken, blocks, firstLevelBlockId
|
|
|
401
389
|
allChildren.push(...children);
|
|
402
390
|
if (currentIndex !== -1) currentIndex += batch.firstLevelIds.length;
|
|
403
391
|
}
|
|
404
|
-
return
|
|
405
|
-
children: allChildren,
|
|
406
|
-
skipped: []
|
|
407
|
-
};
|
|
392
|
+
return allChildren;
|
|
408
393
|
}
|
|
409
394
|
//#endregion
|
|
410
395
|
//#region extensions/feishu/src/docx-color-text.ts
|
|
@@ -419,37 +404,36 @@ const COLORS = {
|
|
|
419
404
|
gray: 7
|
|
420
405
|
};
|
|
421
406
|
function parseColorMarkup(content) {
|
|
422
|
-
const
|
|
407
|
+
const elements = [];
|
|
423
408
|
const KNOWN = "(?:bg:[a-z]+|bold|red|orange|yellow|green|blue|purple|gr[ae]y)";
|
|
424
409
|
const tagPattern = new RegExp(`\\[(${KNOWN}(?:\\s+${KNOWN})*)\\](.*?)\\[\\/(?:[^\\]]+)\\]|([^[]+|\\[)`, "gis");
|
|
425
410
|
let match;
|
|
426
|
-
while ((match = tagPattern.exec(content)) !== null)
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
if (
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
411
|
+
while ((match = tagPattern.exec(content)) !== null) {
|
|
412
|
+
const text = match[3] ?? match[2];
|
|
413
|
+
if (!text) continue;
|
|
414
|
+
let textColor;
|
|
415
|
+
let bgColor;
|
|
416
|
+
let bold = false;
|
|
417
|
+
if (match[3] === void 0) {
|
|
418
|
+
for (const tag of normalizeLowercaseStringOrEmpty(match[1]).split(/\s+/)) if (tag.startsWith("bg:")) {
|
|
419
|
+
const color = tag.slice(3);
|
|
420
|
+
if (COLORS[color]) bgColor = COLORS[color];
|
|
421
|
+
} else if (tag === "bold") bold = true;
|
|
422
|
+
else if (COLORS[tag]) textColor = COLORS[tag];
|
|
423
|
+
}
|
|
424
|
+
elements.push({ text_run: {
|
|
425
|
+
content: text,
|
|
426
|
+
text_element_style: {
|
|
427
|
+
...textColor && { text_color: textColor },
|
|
428
|
+
...bgColor && { background_color: bgColor },
|
|
429
|
+
...bold && { bold: true }
|
|
430
|
+
}
|
|
431
|
+
} });
|
|
440
432
|
}
|
|
441
|
-
return
|
|
433
|
+
return elements;
|
|
442
434
|
}
|
|
443
435
|
async function updateColorText(client, docToken, blockId, content) {
|
|
444
|
-
const
|
|
445
|
-
const elements = segments.map((seg) => ({ text_run: {
|
|
446
|
-
content: seg.text,
|
|
447
|
-
text_element_style: {
|
|
448
|
-
...seg.textColor && { text_color: seg.textColor },
|
|
449
|
-
...seg.bgColor && { background_color: seg.bgColor },
|
|
450
|
-
...seg.bold && { bold: true }
|
|
451
|
-
}
|
|
452
|
-
} }));
|
|
436
|
+
const elements = parseColorMarkup(content);
|
|
453
437
|
const res = await client.docx.documentBlock.patch({
|
|
454
438
|
path: {
|
|
455
439
|
document_id: docToken,
|
|
@@ -460,7 +444,7 @@ async function updateColorText(client, docToken, blockId, content) {
|
|
|
460
444
|
assertFeishuApiSuccess(res);
|
|
461
445
|
return {
|
|
462
446
|
success: true,
|
|
463
|
-
segments:
|
|
447
|
+
segments: elements.length,
|
|
464
448
|
block: res.data?.block
|
|
465
449
|
};
|
|
466
450
|
}
|
|
@@ -472,19 +456,6 @@ const STABLE_LINE_CONTAINER_TYPES = /* @__PURE__ */ new Set([
|
|
|
472
456
|
"blockquote",
|
|
473
457
|
"code"
|
|
474
458
|
]);
|
|
475
|
-
function visitMarkdown(root, visitor) {
|
|
476
|
-
const pending = [root];
|
|
477
|
-
while (pending.length > 0) {
|
|
478
|
-
const node = pending.pop();
|
|
479
|
-
if (!node) continue;
|
|
480
|
-
visitor(node);
|
|
481
|
-
if (!node.children) continue;
|
|
482
|
-
for (let index = node.children.length - 1; index >= 0; index -= 1) {
|
|
483
|
-
const child = node.children[index];
|
|
484
|
-
if (child) pending.push(child);
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
459
|
function resolveRemoteImageUrl(value) {
|
|
489
460
|
if (!value) return;
|
|
490
461
|
try {
|
|
@@ -497,7 +468,7 @@ function resolveRemoteImageUrl(value) {
|
|
|
497
468
|
function collectMarkdownImages(root) {
|
|
498
469
|
const definitions = /* @__PURE__ */ new Map();
|
|
499
470
|
const imageNodes = [];
|
|
500
|
-
|
|
471
|
+
visitFeishuMarkdown(root, (node) => {
|
|
501
472
|
if (node.type === "definition" && node.identifier && node.url) {
|
|
502
473
|
if (!definitions.has(node.identifier)) definitions.set(node.identifier, node.url);
|
|
503
474
|
} else if (node.type === "image" || node.type === "imageReference") imageNodes.push(node);
|
|
@@ -580,13 +551,7 @@ function splitTableAtRow(source, root, target) {
|
|
|
580
551
|
if (chunks.every((chunk) => parseFeishuMarkdown(chunk).children?.[0]?.type === "table")) return chunks;
|
|
581
552
|
}
|
|
582
553
|
function isFencedCodeSource(source) {
|
|
583
|
-
|
|
584
|
-
const firstLine = source.slice(0, firstLineEnd === -1 ? source.length : firstLineEnd);
|
|
585
|
-
let indent = 0;
|
|
586
|
-
while (indent < firstLine.length && firstLine[indent] === " ") indent += 1;
|
|
587
|
-
if (indent > 3) return false;
|
|
588
|
-
const marker = firstLine.slice(indent);
|
|
589
|
-
return marker.startsWith("```") || marker.startsWith("~~~");
|
|
554
|
+
return /^ {0,3}(?:`{3}|~{3})/.test(source);
|
|
590
555
|
}
|
|
591
556
|
function createDocxMarkdownChunk(markdown) {
|
|
592
557
|
return {
|
|
@@ -930,7 +895,7 @@ async function editDoc(client, params, maxBytes, imageReadTimeoutMs, logger) {
|
|
|
930
895
|
}
|
|
931
896
|
const { orderedBlocks, rootIds } = normalizeConvertedBlockTree(blocks, firstLevelBlockIds);
|
|
932
897
|
logger?.info?.(`feishu_doc: Converted to ${blocks.length} blocks, inserting${target ? ` at index ${target.index}` : ""}...`);
|
|
933
|
-
const inserted = blocks.length > 1e3 ?
|
|
898
|
+
const inserted = blocks.length > 1e3 ? await insertBlocksInBatches(client, docToken, orderedBlocks, rootIds, logger, target?.parentBlockId, target?.index) : await insertDocxDescendants(client, docToken, cleanBlocksForDescendant(orderedBlocks), rootIds, target?.parentBlockId, target?.index);
|
|
934
899
|
const imagesProcessed = await processImages(client, docToken, images, inserted, maxBytes, imageReadTimeoutMs);
|
|
935
900
|
logger?.info?.(`feishu_doc: Done (${blocks.length} blocks, ${imagesProcessed} images)`);
|
|
936
901
|
return {
|
|
@@ -941,16 +906,7 @@ async function editDoc(client, params, maxBytes, imageReadTimeoutMs, logger) {
|
|
|
941
906
|
...params.action !== "write" ? { block_ids: inserted.map((b) => b.block_id) } : {}
|
|
942
907
|
};
|
|
943
908
|
}
|
|
944
|
-
async function uploadImageBlock(client,
|
|
945
|
-
const upload = await resolveDocxUploadInput({
|
|
946
|
-
url,
|
|
947
|
-
filePath,
|
|
948
|
-
image: imageInput,
|
|
949
|
-
maxBytes,
|
|
950
|
-
localRoots,
|
|
951
|
-
fileName: filename,
|
|
952
|
-
remoteReadTimeoutMs: imageReadTimeoutMs
|
|
953
|
-
});
|
|
909
|
+
async function uploadImageBlock(client, { doc_token: docToken, parent_block_id: parentBlockId, index }, upload) {
|
|
954
910
|
const insertRes = await client.docx.documentBlockChildren.create({
|
|
955
911
|
path: {
|
|
956
912
|
document_id: docToken,
|
|
@@ -985,15 +941,8 @@ async function uploadImageBlock(client, docToken, maxBytes, imageReadTimeoutMs,
|
|
|
985
941
|
size: upload.buffer.length
|
|
986
942
|
};
|
|
987
943
|
}
|
|
988
|
-
async function uploadFileBlock(client,
|
|
944
|
+
async function uploadFileBlock(client, { doc_token: docToken, parent_block_id: parentBlockId }, upload) {
|
|
989
945
|
const blockId = parentBlockId ?? docToken;
|
|
990
|
-
const upload = await resolveDocxUploadInput({
|
|
991
|
-
url,
|
|
992
|
-
filePath,
|
|
993
|
-
maxBytes,
|
|
994
|
-
localRoots,
|
|
995
|
-
fileName: filename
|
|
996
|
-
});
|
|
997
946
|
const converted = await convertMarkdown(client, "[file](https://example.com/placeholder)");
|
|
998
947
|
const { orderedBlocks } = normalizeConvertedBlockTree(converted.blocks, converted.firstLevelBlockIds);
|
|
999
948
|
const placeholderBlock = (await insertBlocks(client, docToken, orderedBlocks, blockId))[0];
|
|
@@ -1322,8 +1271,21 @@ function registerFeishuDocTools(api) {
|
|
|
1322
1271
|
case "create_table":
|
|
1323
1272
|
case "create_table_with_values": return feishuExternalToolResult(await createTable(client, p));
|
|
1324
1273
|
case "write_table_cells": return feishuExternalToolResult(await writeTableCells(client, p.doc_token, p.table_block_id, p.values));
|
|
1325
|
-
case "upload_image":
|
|
1326
|
-
case "upload_file":
|
|
1274
|
+
case "upload_image":
|
|
1275
|
+
case "upload_file": {
|
|
1276
|
+
const upload = await resolveDocxUploadInput({
|
|
1277
|
+
url: p.url,
|
|
1278
|
+
filePath: p.file_path,
|
|
1279
|
+
maxBytes: mediaMaxBytes,
|
|
1280
|
+
localRoots: mediaLocalRoots,
|
|
1281
|
+
fileName: p.filename,
|
|
1282
|
+
...p.action === "upload_image" ? {
|
|
1283
|
+
image: p.image,
|
|
1284
|
+
remoteReadTimeoutMs: imageReadTimeoutMs
|
|
1285
|
+
} : {}
|
|
1286
|
+
});
|
|
1287
|
+
return feishuExternalToolResult(await (p.action === "upload_image" ? uploadImageBlock(client, p, upload) : uploadFileBlock(client, p, upload)));
|
|
1288
|
+
}
|
|
1327
1289
|
case "color_text": return feishuExternalToolResult(await updateColorText(client, p.doc_token, p.block_id, p.content));
|
|
1328
1290
|
case "insert_table_row":
|
|
1329
1291
|
case "insert_table_column":
|
|
@@ -1432,114 +1394,6 @@ function readWikiPageSize(params) {
|
|
|
1432
1394
|
message: "page_size must be a positive integer between 1 and 50"
|
|
1433
1395
|
}) ?? WIKI_PAGE_SIZE;
|
|
1434
1396
|
}
|
|
1435
|
-
async function listSpaces(client, pageSize, pageToken) {
|
|
1436
|
-
const res = await client.wiki.space.list({ params: {
|
|
1437
|
-
page_size: pageSize,
|
|
1438
|
-
page_token: pageToken
|
|
1439
|
-
} });
|
|
1440
|
-
assertFeishuApiSuccess(res);
|
|
1441
|
-
const spaces = res.data?.items?.map((s) => ({
|
|
1442
|
-
space_id: s.space_id,
|
|
1443
|
-
name: s.name,
|
|
1444
|
-
description: s.description,
|
|
1445
|
-
visibility: s.visibility
|
|
1446
|
-
})) ?? [];
|
|
1447
|
-
return {
|
|
1448
|
-
spaces,
|
|
1449
|
-
has_more: res.data?.has_more ?? false,
|
|
1450
|
-
page_token: res.data?.page_token,
|
|
1451
|
-
...spaces.length === 0 && pageToken === void 0 && res.data?.has_more !== true && { hint: WIKI_ACCESS_HINT }
|
|
1452
|
-
};
|
|
1453
|
-
}
|
|
1454
|
-
async function listNodes(client, spaceId, parentNodeToken, pageSize, pageToken) {
|
|
1455
|
-
const res = await client.wiki.spaceNode.list({
|
|
1456
|
-
path: { space_id: spaceId },
|
|
1457
|
-
params: {
|
|
1458
|
-
parent_node_token: parentNodeToken,
|
|
1459
|
-
page_size: pageSize,
|
|
1460
|
-
page_token: pageToken
|
|
1461
|
-
}
|
|
1462
|
-
});
|
|
1463
|
-
assertFeishuApiSuccess(res);
|
|
1464
|
-
return {
|
|
1465
|
-
nodes: res.data?.items?.map((n) => ({
|
|
1466
|
-
node_token: n.node_token,
|
|
1467
|
-
obj_token: n.obj_token,
|
|
1468
|
-
obj_type: n.obj_type,
|
|
1469
|
-
title: n.title,
|
|
1470
|
-
has_child: n.has_child
|
|
1471
|
-
})) ?? [],
|
|
1472
|
-
has_more: res.data?.has_more ?? false,
|
|
1473
|
-
page_token: res.data?.page_token
|
|
1474
|
-
};
|
|
1475
|
-
}
|
|
1476
|
-
async function getNode(client, token) {
|
|
1477
|
-
const res = await client.wiki.space.getNode({ params: { token } });
|
|
1478
|
-
assertFeishuApiSuccess(res);
|
|
1479
|
-
const node = res.data?.node;
|
|
1480
|
-
return {
|
|
1481
|
-
node_token: node?.node_token,
|
|
1482
|
-
space_id: node?.space_id,
|
|
1483
|
-
obj_token: node?.obj_token,
|
|
1484
|
-
obj_type: node?.obj_type,
|
|
1485
|
-
title: node?.title,
|
|
1486
|
-
parent_node_token: node?.parent_node_token,
|
|
1487
|
-
has_child: node?.has_child,
|
|
1488
|
-
creator: node?.creator,
|
|
1489
|
-
create_time: node?.node_create_time
|
|
1490
|
-
};
|
|
1491
|
-
}
|
|
1492
|
-
async function createNode(client, spaceId, title, objType, parentNodeToken) {
|
|
1493
|
-
const res = await client.wiki.spaceNode.create({
|
|
1494
|
-
path: { space_id: spaceId },
|
|
1495
|
-
data: {
|
|
1496
|
-
obj_type: objType || "docx",
|
|
1497
|
-
node_type: "origin",
|
|
1498
|
-
title,
|
|
1499
|
-
parent_node_token: parentNodeToken
|
|
1500
|
-
}
|
|
1501
|
-
});
|
|
1502
|
-
assertFeishuApiSuccess(res);
|
|
1503
|
-
const node = res.data?.node;
|
|
1504
|
-
return {
|
|
1505
|
-
node_token: node?.node_token,
|
|
1506
|
-
obj_token: node?.obj_token,
|
|
1507
|
-
obj_type: node?.obj_type,
|
|
1508
|
-
title: node?.title
|
|
1509
|
-
};
|
|
1510
|
-
}
|
|
1511
|
-
async function moveNode(client, spaceId, nodeToken, targetSpaceId, targetParentToken) {
|
|
1512
|
-
const res = await client.wiki.spaceNode.move({
|
|
1513
|
-
path: {
|
|
1514
|
-
space_id: spaceId,
|
|
1515
|
-
node_token: nodeToken
|
|
1516
|
-
},
|
|
1517
|
-
data: {
|
|
1518
|
-
target_space_id: targetSpaceId || spaceId,
|
|
1519
|
-
target_parent_token: targetParentToken
|
|
1520
|
-
}
|
|
1521
|
-
});
|
|
1522
|
-
assertFeishuApiSuccess(res);
|
|
1523
|
-
return {
|
|
1524
|
-
success: true,
|
|
1525
|
-
node_token: res.data?.node?.node_token
|
|
1526
|
-
};
|
|
1527
|
-
}
|
|
1528
|
-
async function renameNode(client, spaceId, nodeToken, title) {
|
|
1529
|
-
const res = await client.wiki.spaceNode.updateTitle({
|
|
1530
|
-
path: {
|
|
1531
|
-
space_id: spaceId,
|
|
1532
|
-
node_token: nodeToken
|
|
1533
|
-
},
|
|
1534
|
-
data: { title }
|
|
1535
|
-
});
|
|
1536
|
-
assertFeishuApiSuccess(res);
|
|
1537
|
-
return {
|
|
1538
|
-
success: true,
|
|
1539
|
-
node_token: nodeToken,
|
|
1540
|
-
title
|
|
1541
|
-
};
|
|
1542
|
-
}
|
|
1543
1397
|
function registerFeishuWikiTools(api) {
|
|
1544
1398
|
registerFeishuTool(api, {
|
|
1545
1399
|
family: "wiki",
|
|
@@ -1560,27 +1414,123 @@ function registerFeishuWikiTools(api) {
|
|
|
1560
1414
|
}
|
|
1561
1415
|
});
|
|
1562
1416
|
switch (p.action) {
|
|
1563
|
-
case "spaces":
|
|
1417
|
+
case "spaces": {
|
|
1418
|
+
const pageToken = p.page_token;
|
|
1419
|
+
const res = await createClient().wiki.space.list({ params: {
|
|
1420
|
+
page_size: readWikiPageSize(p),
|
|
1421
|
+
page_token: pageToken
|
|
1422
|
+
} });
|
|
1423
|
+
assertFeishuApiSuccess(res);
|
|
1424
|
+
const spaces = res.data?.items?.map((s) => ({
|
|
1425
|
+
space_id: s.space_id,
|
|
1426
|
+
name: s.name,
|
|
1427
|
+
description: s.description,
|
|
1428
|
+
visibility: s.visibility
|
|
1429
|
+
})) ?? [];
|
|
1430
|
+
return feishuExternalToolResult({
|
|
1431
|
+
spaces,
|
|
1432
|
+
has_more: res.data?.has_more ?? false,
|
|
1433
|
+
page_token: res.data?.page_token,
|
|
1434
|
+
...spaces.length === 0 && pageToken === void 0 && res.data?.has_more !== true && { hint: WIKI_ACCESS_HINT }
|
|
1435
|
+
});
|
|
1436
|
+
}
|
|
1564
1437
|
case "nodes": {
|
|
1565
1438
|
const spaceId = requireWikiSpaceId(p.space_id, "space_id");
|
|
1566
|
-
|
|
1439
|
+
const res = await createClient().wiki.spaceNode.list({
|
|
1440
|
+
path: { space_id: spaceId },
|
|
1441
|
+
params: {
|
|
1442
|
+
parent_node_token: p.parent_node_token,
|
|
1443
|
+
page_size: readWikiPageSize(p),
|
|
1444
|
+
page_token: p.page_token
|
|
1445
|
+
}
|
|
1446
|
+
});
|
|
1447
|
+
assertFeishuApiSuccess(res);
|
|
1448
|
+
return feishuExternalToolResult({
|
|
1449
|
+
nodes: res.data?.items?.map((n) => ({
|
|
1450
|
+
node_token: n.node_token,
|
|
1451
|
+
obj_token: n.obj_token,
|
|
1452
|
+
obj_type: n.obj_type,
|
|
1453
|
+
title: n.title,
|
|
1454
|
+
has_child: n.has_child
|
|
1455
|
+
})) ?? [],
|
|
1456
|
+
has_more: res.data?.has_more ?? false,
|
|
1457
|
+
page_token: res.data?.page_token
|
|
1458
|
+
});
|
|
1459
|
+
}
|
|
1460
|
+
case "get": {
|
|
1461
|
+
const res = await createClient().wiki.space.getNode({ params: { token: p.token } });
|
|
1462
|
+
assertFeishuApiSuccess(res);
|
|
1463
|
+
const node = res.data?.node;
|
|
1464
|
+
return feishuExternalToolResult({
|
|
1465
|
+
node_token: node?.node_token,
|
|
1466
|
+
space_id: node?.space_id,
|
|
1467
|
+
obj_token: node?.obj_token,
|
|
1468
|
+
obj_type: node?.obj_type,
|
|
1469
|
+
title: node?.title,
|
|
1470
|
+
parent_node_token: node?.parent_node_token,
|
|
1471
|
+
has_child: node?.has_child,
|
|
1472
|
+
creator: node?.creator,
|
|
1473
|
+
create_time: node?.node_create_time
|
|
1474
|
+
});
|
|
1567
1475
|
}
|
|
1568
|
-
case "get": return feishuExternalToolResult(await getNode(createClient(), p.token));
|
|
1569
1476
|
case "search":
|
|
1570
1477
|
optionalWikiSpaceId(p.space_id, "space_id");
|
|
1571
1478
|
createClient();
|
|
1572
1479
|
return feishuExternalToolResult({ error: "Search is not available. Use feishu_wiki with action: 'nodes' to browse or action: 'get' to lookup by token." });
|
|
1573
1480
|
case "create": {
|
|
1574
1481
|
const spaceId = requireWikiSpaceId(p.space_id, "space_id");
|
|
1575
|
-
|
|
1482
|
+
const res = await createClient().wiki.spaceNode.create({
|
|
1483
|
+
path: { space_id: spaceId },
|
|
1484
|
+
data: {
|
|
1485
|
+
obj_type: p.obj_type || "docx",
|
|
1486
|
+
node_type: "origin",
|
|
1487
|
+
title: p.title,
|
|
1488
|
+
parent_node_token: p.parent_node_token
|
|
1489
|
+
}
|
|
1490
|
+
});
|
|
1491
|
+
assertFeishuApiSuccess(res);
|
|
1492
|
+
const node = res.data?.node;
|
|
1493
|
+
return feishuExternalToolResult({
|
|
1494
|
+
node_token: node?.node_token,
|
|
1495
|
+
obj_token: node?.obj_token,
|
|
1496
|
+
obj_type: node?.obj_type,
|
|
1497
|
+
title: node?.title
|
|
1498
|
+
});
|
|
1576
1499
|
}
|
|
1577
1500
|
case "move": {
|
|
1578
1501
|
const spaceId = requireWikiSpaceId(p.space_id, "space_id");
|
|
1579
|
-
|
|
1502
|
+
const res = await createClient().wiki.spaceNode.move({
|
|
1503
|
+
path: {
|
|
1504
|
+
space_id: spaceId,
|
|
1505
|
+
node_token: p.node_token
|
|
1506
|
+
},
|
|
1507
|
+
data: {
|
|
1508
|
+
target_space_id: optionalWikiSpaceId(p.target_space_id, "target_space_id") || spaceId,
|
|
1509
|
+
target_parent_token: p.target_parent_token
|
|
1510
|
+
}
|
|
1511
|
+
});
|
|
1512
|
+
assertFeishuApiSuccess(res);
|
|
1513
|
+
return feishuExternalToolResult({
|
|
1514
|
+
success: true,
|
|
1515
|
+
node_token: res.data?.node?.node_token
|
|
1516
|
+
});
|
|
1580
1517
|
}
|
|
1581
1518
|
case "rename": {
|
|
1582
1519
|
const spaceId = requireWikiSpaceId(p.space_id, "space_id");
|
|
1583
|
-
|
|
1520
|
+
const { node_token, title } = p;
|
|
1521
|
+
const res = await createClient().wiki.spaceNode.updateTitle({
|
|
1522
|
+
path: {
|
|
1523
|
+
space_id: spaceId,
|
|
1524
|
+
node_token
|
|
1525
|
+
},
|
|
1526
|
+
data: { title }
|
|
1527
|
+
});
|
|
1528
|
+
assertFeishuApiSuccess(res);
|
|
1529
|
+
return feishuExternalToolResult({
|
|
1530
|
+
success: true,
|
|
1531
|
+
node_token,
|
|
1532
|
+
title
|
|
1533
|
+
});
|
|
1584
1534
|
}
|
|
1585
1535
|
default: return unknownToolActionResult(p.action);
|
|
1586
1536
|
}
|
|
@@ -1637,52 +1587,6 @@ const FeishuPermSchema = Type.Union([
|
|
|
1637
1587
|
]);
|
|
1638
1588
|
//#endregion
|
|
1639
1589
|
//#region extensions/feishu/src/perm.ts
|
|
1640
|
-
async function listMembers(client, token, type) {
|
|
1641
|
-
const res = await client.drive.permissionMember.list({
|
|
1642
|
-
path: { token },
|
|
1643
|
-
params: { type }
|
|
1644
|
-
});
|
|
1645
|
-
assertFeishuApiSuccess(res);
|
|
1646
|
-
return { members: res.data?.items?.map((m) => ({
|
|
1647
|
-
member_type: m.member_type,
|
|
1648
|
-
member_id: m.member_id,
|
|
1649
|
-
perm: m.perm,
|
|
1650
|
-
name: m.name
|
|
1651
|
-
})) ?? [] };
|
|
1652
|
-
}
|
|
1653
|
-
async function addMember(client, { token, type, member_type, member_id, perm }) {
|
|
1654
|
-
const res = await client.drive.permissionMember.create({
|
|
1655
|
-
path: { token },
|
|
1656
|
-
params: {
|
|
1657
|
-
type,
|
|
1658
|
-
need_notification: false
|
|
1659
|
-
},
|
|
1660
|
-
data: {
|
|
1661
|
-
member_type,
|
|
1662
|
-
member_id,
|
|
1663
|
-
perm
|
|
1664
|
-
}
|
|
1665
|
-
});
|
|
1666
|
-
assertFeishuApiSuccess(res);
|
|
1667
|
-
return {
|
|
1668
|
-
success: true,
|
|
1669
|
-
member: res.data?.member
|
|
1670
|
-
};
|
|
1671
|
-
}
|
|
1672
|
-
async function removeMember(client, { token, type, member_type, member_id }) {
|
|
1673
|
-
const res = await client.drive.permissionMember.delete({
|
|
1674
|
-
path: {
|
|
1675
|
-
token,
|
|
1676
|
-
member_id
|
|
1677
|
-
},
|
|
1678
|
-
params: {
|
|
1679
|
-
type,
|
|
1680
|
-
member_type
|
|
1681
|
-
}
|
|
1682
|
-
});
|
|
1683
|
-
assertFeishuApiSuccess(res);
|
|
1684
|
-
return { success: true };
|
|
1685
|
-
}
|
|
1686
1590
|
function registerFeishuPermTools(api) {
|
|
1687
1591
|
registerFeishuTool(api, {
|
|
1688
1592
|
family: "perm",
|
|
@@ -1703,9 +1607,54 @@ function registerFeishuPermTools(api) {
|
|
|
1703
1607
|
}
|
|
1704
1608
|
});
|
|
1705
1609
|
switch (p.action) {
|
|
1706
|
-
case "list":
|
|
1707
|
-
|
|
1708
|
-
|
|
1610
|
+
case "list": {
|
|
1611
|
+
const res = await client.drive.permissionMember.list({
|
|
1612
|
+
path: { token: p.token },
|
|
1613
|
+
params: { type: p.type }
|
|
1614
|
+
});
|
|
1615
|
+
assertFeishuApiSuccess(res);
|
|
1616
|
+
return feishuExternalToolResult({ members: res.data?.items?.map((m) => ({
|
|
1617
|
+
member_type: m.member_type,
|
|
1618
|
+
member_id: m.member_id,
|
|
1619
|
+
perm: m.perm,
|
|
1620
|
+
name: m.name
|
|
1621
|
+
})) ?? [] });
|
|
1622
|
+
}
|
|
1623
|
+
case "add": {
|
|
1624
|
+
const { token, type, member_type, member_id, perm } = p;
|
|
1625
|
+
const res = await client.drive.permissionMember.create({
|
|
1626
|
+
path: { token },
|
|
1627
|
+
params: {
|
|
1628
|
+
type,
|
|
1629
|
+
need_notification: false
|
|
1630
|
+
},
|
|
1631
|
+
data: {
|
|
1632
|
+
member_type,
|
|
1633
|
+
member_id,
|
|
1634
|
+
perm
|
|
1635
|
+
}
|
|
1636
|
+
});
|
|
1637
|
+
assertFeishuApiSuccess(res);
|
|
1638
|
+
return feishuExternalToolResult({
|
|
1639
|
+
success: true,
|
|
1640
|
+
member: res.data?.member
|
|
1641
|
+
});
|
|
1642
|
+
}
|
|
1643
|
+
case "remove": {
|
|
1644
|
+
const { token, type, member_type, member_id } = p;
|
|
1645
|
+
const res = await client.drive.permissionMember.delete({
|
|
1646
|
+
path: {
|
|
1647
|
+
token,
|
|
1648
|
+
member_id
|
|
1649
|
+
},
|
|
1650
|
+
params: {
|
|
1651
|
+
type,
|
|
1652
|
+
member_type
|
|
1653
|
+
}
|
|
1654
|
+
});
|
|
1655
|
+
assertFeishuApiSuccess(res);
|
|
1656
|
+
return feishuExternalToolResult({ success: true });
|
|
1657
|
+
}
|
|
1709
1658
|
default: return unknownToolActionResult(p.action);
|
|
1710
1659
|
}
|
|
1711
1660
|
};
|
|
@@ -1717,7 +1666,6 @@ function registerFeishuPermTools(api) {
|
|
|
1717
1666
|
function ensureLarkSuccess(res, api) {
|
|
1718
1667
|
if (res.code !== 0) throw new Error(`[${api}] code=${res.code ?? -1} message=${res.msg ?? "unknown error"}`);
|
|
1719
1668
|
}
|
|
1720
|
-
/** Field type ID to human-readable name */
|
|
1721
1669
|
const FIELD_TYPE_NAMES = {
|
|
1722
1670
|
1: "Text",
|
|
1723
1671
|
2: "Number",
|
|
@@ -1741,7 +1689,6 @@ const FIELD_TYPE_NAMES = {
|
|
|
1741
1689
|
1004: "ModifiedUser",
|
|
1742
1690
|
1005: "AutoNumber"
|
|
1743
1691
|
};
|
|
1744
|
-
/** Parse bitable URL and extract tokens */
|
|
1745
1692
|
function parseBitableUrl(url) {
|
|
1746
1693
|
try {
|
|
1747
1694
|
const u = new URL(url);
|
|
@@ -1757,7 +1704,6 @@ function parseBitableUrl(url) {
|
|
|
1757
1704
|
return null;
|
|
1758
1705
|
}
|
|
1759
1706
|
}
|
|
1760
|
-
/** Get app_token from wiki node_token */
|
|
1761
1707
|
async function getAppTokenFromWiki(client, nodeToken) {
|
|
1762
1708
|
const res = await client.wiki.space.getNode({ params: { token: nodeToken } });
|
|
1763
1709
|
ensureLarkSuccess(res, "wiki.space.getNode");
|
|
@@ -1766,7 +1712,6 @@ async function getAppTokenFromWiki(client, nodeToken) {
|
|
|
1766
1712
|
if (node.obj_type !== "bitable") throw new Error(`Node is not a bitable (type: ${node.obj_type})`);
|
|
1767
1713
|
return node.obj_token;
|
|
1768
1714
|
}
|
|
1769
|
-
/** Get bitable metadata from URL (handles both /base/ and /wiki/ URLs) */
|
|
1770
1715
|
async function getBitableMeta(client, url) {
|
|
1771
1716
|
const parsed = parseBitableUrl(url);
|
|
1772
1717
|
if (!parsed) throw new Error("Invalid URL format. Expected /base/XXX or /wiki/XXX URL");
|
|
@@ -1790,7 +1735,6 @@ async function getBitableMeta(client, url) {
|
|
|
1790
1735
|
hint: parsed.tableId ? `Use app_token="${appToken}" and table_id="${parsed.tableId}" for other bitable tools` : `Use app_token="${appToken}" for other bitable tools. Select a table_id from the tables list.`
|
|
1791
1736
|
};
|
|
1792
1737
|
}
|
|
1793
|
-
/** Default field types created for new Bitable tables (to be cleaned up) */
|
|
1794
1738
|
const DEFAULT_CLEANUP_FIELD_TYPES = /* @__PURE__ */ new Set([
|
|
1795
1739
|
3,
|
|
1796
1740
|
5,
|
|
@@ -1811,7 +1755,6 @@ function isPlaceholderBitableRecord(fields) {
|
|
|
1811
1755
|
if (!fields || typeof fields !== "object" || Array.isArray(fields)) return true;
|
|
1812
1756
|
return Object.values(fields).every(isDefaultEmptyBitableFieldValue);
|
|
1813
1757
|
}
|
|
1814
|
-
/** Clean up default placeholder rows and fields in a newly created Bitable table */
|
|
1815
1758
|
async function cleanupNewBitable(client, appToken, tableId, tableName, logger) {
|
|
1816
1759
|
let cleanedRows = 0;
|
|
1817
1760
|
let cleanedFields = 0;
|
|
@@ -1822,7 +1765,6 @@ async function cleanupNewBitable(client, appToken, tableId, tableName, logger) {
|
|
|
1822
1765
|
if (fieldsRes.code === 0 && fieldsRes.data?.items) {
|
|
1823
1766
|
const primaryField = fieldsRes.data.items.find((f) => f.is_primary);
|
|
1824
1767
|
if (primaryField?.field_id) try {
|
|
1825
|
-
const newFieldName = tableName.length <= 20 ? tableName : "Name";
|
|
1826
1768
|
ensureLarkSuccess(await client.bitable.appTableField.update({
|
|
1827
1769
|
path: {
|
|
1828
1770
|
app_token: appToken,
|
|
@@ -1830,7 +1772,7 @@ async function cleanupNewBitable(client, appToken, tableId, tableName, logger) {
|
|
|
1830
1772
|
field_id: primaryField.field_id
|
|
1831
1773
|
},
|
|
1832
1774
|
data: {
|
|
1833
|
-
field_name:
|
|
1775
|
+
field_name: tableName.length <= 20 ? tableName : "Name",
|
|
1834
1776
|
type: 1
|
|
1835
1777
|
}
|
|
1836
1778
|
}), "bitable.appTableField.update");
|
|
@@ -1929,8 +1871,7 @@ const ListFieldsSchema = Type.Object({
|
|
|
1929
1871
|
table_id: Type.String({ description: "Table ID (from URL: ?table=YYY)" })
|
|
1930
1872
|
});
|
|
1931
1873
|
const ListRecordsSchema = Type.Object({
|
|
1932
|
-
|
|
1933
|
-
table_id: Type.String({ description: "Table ID (from URL: ?table=YYY)" }),
|
|
1874
|
+
...ListFieldsSchema.properties,
|
|
1934
1875
|
page_size: optionalPositiveIntegerSchema({
|
|
1935
1876
|
description: "Number of records per page (1-500, default 100)",
|
|
1936
1877
|
maximum: 500
|
|
@@ -1938,8 +1879,7 @@ const ListRecordsSchema = Type.Object({
|
|
|
1938
1879
|
page_token: Type.Optional(Type.String({ description: "Pagination token from previous response" }))
|
|
1939
1880
|
});
|
|
1940
1881
|
const GetRecordSchema = Type.Object({
|
|
1941
|
-
|
|
1942
|
-
table_id: Type.String({ description: "Table ID (from URL: ?table=YYY)" }),
|
|
1882
|
+
...ListFieldsSchema.properties,
|
|
1943
1883
|
record_id: Type.String({ description: "Record ID to retrieve" })
|
|
1944
1884
|
});
|
|
1945
1885
|
const BitableFieldValueSchema = Type.Unsafe({ type: [
|
|
@@ -1951,8 +1891,7 @@ const BitableFieldValueSchema = Type.Unsafe({ type: [
|
|
|
1951
1891
|
"null"
|
|
1952
1892
|
] });
|
|
1953
1893
|
const CreateRecordSchema = Type.Object({
|
|
1954
|
-
|
|
1955
|
-
table_id: Type.String({ description: "Table ID (from URL: ?table=YYY)" }),
|
|
1894
|
+
...ListFieldsSchema.properties,
|
|
1956
1895
|
fields: Type.Record(Type.String(), BitableFieldValueSchema, { description: BITABLE_RECORD_FIELDS_DESCRIPTION })
|
|
1957
1896
|
});
|
|
1958
1897
|
const CreateAppSchema = Type.Object({
|
|
@@ -1960,8 +1899,7 @@ const CreateAppSchema = Type.Object({
|
|
|
1960
1899
|
folder_token: Type.Optional(Type.String({ description: "Optional folder token to place the Bitable in a specific folder" }))
|
|
1961
1900
|
});
|
|
1962
1901
|
const CreateFieldSchema = Type.Object({
|
|
1963
|
-
|
|
1964
|
-
table_id: Type.String({ description: "Table ID (from URL: ?table=YYY)" }),
|
|
1902
|
+
...ListFieldsSchema.properties,
|
|
1965
1903
|
field_name: Type.String({ description: "Name for the new field" }),
|
|
1966
1904
|
field_type: Type.Number({
|
|
1967
1905
|
description: "Field type ID: 1=Text, 2=Number, 3=SingleSelect, 4=MultiSelect, 5=DateTime, 7=Checkbox, 11=User, 13=Phone, 15=URL, 17=Attachment, 18=SingleLink, 19=Lookup, 20=Formula, 21=DuplexLink, 22=Location, 23=GroupChat, 1001=CreatedTime, 1002=ModifiedTime, 1003=CreatedUser, 1004=ModifiedUser, 1005=AutoNumber",
|
|
@@ -1970,10 +1908,9 @@ const CreateFieldSchema = Type.Object({
|
|
|
1970
1908
|
property: Type.Optional(Type.Record(Type.String(), BitableFieldValueSchema, { description: "Field-specific properties (e.g., options for SingleSelect, format for Number)" }))
|
|
1971
1909
|
});
|
|
1972
1910
|
const UpdateRecordSchema = Type.Object({
|
|
1973
|
-
|
|
1974
|
-
table_id: Type.String({ description: "Table ID (from URL: ?table=YYY)" }),
|
|
1911
|
+
...ListFieldsSchema.properties,
|
|
1975
1912
|
record_id: Type.String({ description: "Record ID to update" }),
|
|
1976
|
-
fields:
|
|
1913
|
+
fields: CreateRecordSchema.properties.fields
|
|
1977
1914
|
});
|
|
1978
1915
|
function registerFeishuBitableTools(api) {
|
|
1979
1916
|
const registerBitableTool = (tool) => {
|
|
@@ -2013,10 +1950,10 @@ function registerFeishuBitableTools(api) {
|
|
|
2013
1950
|
description: "List all fields (columns) in a Bitable table with their types and properties",
|
|
2014
1951
|
parameters: ListFieldsSchema,
|
|
2015
1952
|
async execute({ params, client }) {
|
|
2016
|
-
const { app_token
|
|
1953
|
+
const { app_token, table_id } = params;
|
|
2017
1954
|
const res = await client.bitable.appTableField.list({ path: {
|
|
2018
|
-
app_token
|
|
2019
|
-
table_id
|
|
1955
|
+
app_token,
|
|
1956
|
+
table_id
|
|
2020
1957
|
} });
|
|
2021
1958
|
ensureLarkSuccess(res, "bitable.appTableField.list");
|
|
2022
1959
|
const fields = res.data?.items ?? [];
|
|
@@ -2039,19 +1976,19 @@ function registerFeishuBitableTools(api) {
|
|
|
2039
1976
|
description: "List records (rows) from a Bitable table with pagination support",
|
|
2040
1977
|
parameters: ListRecordsSchema,
|
|
2041
1978
|
async execute({ params, client }) {
|
|
2042
|
-
const { app_token
|
|
1979
|
+
const { app_token, table_id, page_token } = params;
|
|
2043
1980
|
const pageSize = readPositiveIntegerParam(params, "page_size", {
|
|
2044
1981
|
max: 500,
|
|
2045
1982
|
message: "page_size must be a positive integer between 1 and 500"
|
|
2046
1983
|
});
|
|
2047
1984
|
const res = await client.bitable.appTableRecord.list({
|
|
2048
1985
|
path: {
|
|
2049
|
-
app_token
|
|
2050
|
-
table_id
|
|
1986
|
+
app_token,
|
|
1987
|
+
table_id
|
|
2051
1988
|
},
|
|
2052
1989
|
params: {
|
|
2053
1990
|
page_size: pageSize ?? 100,
|
|
2054
|
-
...
|
|
1991
|
+
...page_token && { page_token }
|
|
2055
1992
|
}
|
|
2056
1993
|
});
|
|
2057
1994
|
ensureLarkSuccess(res, "bitable.appTableRecord.list");
|
|
@@ -2069,11 +2006,11 @@ function registerFeishuBitableTools(api) {
|
|
|
2069
2006
|
description: "Get a single record by ID from a Bitable table",
|
|
2070
2007
|
parameters: GetRecordSchema,
|
|
2071
2008
|
async execute({ params, client }) {
|
|
2072
|
-
const { app_token
|
|
2009
|
+
const { app_token, table_id, record_id } = params;
|
|
2073
2010
|
const res = await client.bitable.appTableRecord.get({ path: {
|
|
2074
|
-
app_token
|
|
2075
|
-
table_id
|
|
2076
|
-
record_id
|
|
2011
|
+
app_token,
|
|
2012
|
+
table_id,
|
|
2013
|
+
record_id
|
|
2077
2014
|
} });
|
|
2078
2015
|
ensureLarkSuccess(res, "bitable.appTableRecord.get");
|
|
2079
2016
|
return { record: res.data?.record };
|
|
@@ -2085,11 +2022,11 @@ function registerFeishuBitableTools(api) {
|
|
|
2085
2022
|
description: "Create a new record (row) in a Bitable table",
|
|
2086
2023
|
parameters: CreateRecordSchema,
|
|
2087
2024
|
async execute({ params, client }) {
|
|
2088
|
-
const { app_token
|
|
2025
|
+
const { app_token, table_id, fields } = params;
|
|
2089
2026
|
const res = await client.bitable.appTableRecord.create({
|
|
2090
2027
|
path: {
|
|
2091
|
-
app_token
|
|
2092
|
-
table_id
|
|
2028
|
+
app_token,
|
|
2029
|
+
table_id
|
|
2093
2030
|
},
|
|
2094
2031
|
data: { fields }
|
|
2095
2032
|
});
|
|
@@ -2103,12 +2040,12 @@ function registerFeishuBitableTools(api) {
|
|
|
2103
2040
|
description: "Update an existing record (row) in a Bitable table",
|
|
2104
2041
|
parameters: UpdateRecordSchema,
|
|
2105
2042
|
async execute({ params, client }) {
|
|
2106
|
-
const { app_token
|
|
2043
|
+
const { app_token, table_id, record_id, fields } = params;
|
|
2107
2044
|
const res = await client.bitable.appTableRecord.update({
|
|
2108
2045
|
path: {
|
|
2109
|
-
app_token
|
|
2110
|
-
table_id
|
|
2111
|
-
record_id
|
|
2046
|
+
app_token,
|
|
2047
|
+
table_id,
|
|
2048
|
+
record_id
|
|
2112
2049
|
},
|
|
2113
2050
|
data: { fields }
|
|
2114
2051
|
});
|
|
@@ -2131,15 +2068,15 @@ function registerFeishuBitableTools(api) {
|
|
|
2131
2068
|
description: "Create a new field (column) in a Bitable table",
|
|
2132
2069
|
parameters: CreateFieldSchema,
|
|
2133
2070
|
async execute({ params, client }) {
|
|
2134
|
-
const { app_token
|
|
2071
|
+
const { app_token, table_id, field_name, field_type, property } = params;
|
|
2135
2072
|
const res = await client.bitable.appTableField.create({
|
|
2136
2073
|
path: {
|
|
2137
|
-
app_token
|
|
2138
|
-
table_id
|
|
2074
|
+
app_token,
|
|
2075
|
+
table_id
|
|
2139
2076
|
},
|
|
2140
2077
|
data: {
|
|
2141
|
-
field_name
|
|
2142
|
-
type:
|
|
2078
|
+
field_name,
|
|
2079
|
+
type: field_type,
|
|
2143
2080
|
...property && { property }
|
|
2144
2081
|
}
|
|
2145
2082
|
});
|