@openclaw-cn/feishu 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/README.md +86 -0
  2. package/dist/index.d.ts +37 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +49 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/src/accounts.d.ts +33 -0
  7. package/dist/src/accounts.d.ts.map +1 -0
  8. package/dist/src/accounts.js +110 -0
  9. package/dist/src/accounts.js.map +1 -0
  10. package/dist/src/bitable.d.ts +211 -0
  11. package/dist/src/bitable.d.ts.map +1 -0
  12. package/dist/src/bitable.js +721 -0
  13. package/dist/src/bitable.js.map +1 -0
  14. package/dist/src/bot.d.ts +53 -0
  15. package/dist/src/bot.d.ts.map +1 -0
  16. package/dist/src/bot.js +853 -0
  17. package/dist/src/bot.js.map +1 -0
  18. package/dist/src/calendar-schema.d.ts +18 -0
  19. package/dist/src/calendar-schema.d.ts.map +1 -0
  20. package/dist/src/calendar-schema.js +52 -0
  21. package/dist/src/calendar-schema.js.map +1 -0
  22. package/dist/src/calendar.d.ts +441 -0
  23. package/dist/src/calendar.d.ts.map +1 -0
  24. package/dist/src/calendar.js +257 -0
  25. package/dist/src/calendar.js.map +1 -0
  26. package/dist/src/channel.d.ts +4 -0
  27. package/dist/src/channel.d.ts.map +1 -0
  28. package/dist/src/channel.js +331 -0
  29. package/dist/src/channel.js.map +1 -0
  30. package/dist/src/client.d.ts +35 -0
  31. package/dist/src/client.d.ts.map +1 -0
  32. package/dist/src/client.js +86 -0
  33. package/dist/src/client.js.map +1 -0
  34. package/dist/src/config-schema.d.ts +176 -0
  35. package/dist/src/config-schema.d.ts.map +1 -0
  36. package/dist/src/config-schema.js +56 -0
  37. package/dist/src/config-schema.js.map +1 -0
  38. package/dist/src/directory.d.ts +36 -0
  39. package/dist/src/directory.d.ts.map +1 -0
  40. package/dist/src/directory.js +129 -0
  41. package/dist/src/directory.js.map +1 -0
  42. package/dist/src/doc-schema.d.ts +37 -0
  43. package/dist/src/doc-schema.d.ts.map +1 -0
  44. package/dist/src/doc-schema.js +51 -0
  45. package/dist/src/doc-schema.js.map +1 -0
  46. package/dist/src/docx.d.ts +3 -0
  47. package/dist/src/docx.d.ts.map +1 -0
  48. package/dist/src/docx.js +608 -0
  49. package/dist/src/docx.js.map +1 -0
  50. package/dist/src/drive-schema.d.ts +24 -0
  51. package/dist/src/drive-schema.d.ts.map +1 -0
  52. package/dist/src/drive-schema.js +39 -0
  53. package/dist/src/drive-schema.js.map +1 -0
  54. package/dist/src/drive.d.ts +3 -0
  55. package/dist/src/drive.d.ts.map +1 -0
  56. package/dist/src/drive.js +181 -0
  57. package/dist/src/drive.js.map +1 -0
  58. package/dist/src/dynamic-agent.d.ts +19 -0
  59. package/dist/src/dynamic-agent.d.ts.map +1 -0
  60. package/dist/src/dynamic-agent.js +91 -0
  61. package/dist/src/dynamic-agent.js.map +1 -0
  62. package/dist/src/im-schema.d.ts +38 -0
  63. package/dist/src/im-schema.d.ts.map +1 -0
  64. package/dist/src/im-schema.js +73 -0
  65. package/dist/src/im-schema.js.map +1 -0
  66. package/dist/src/im.d.ts +70 -0
  67. package/dist/src/im.d.ts.map +1 -0
  68. package/dist/src/im.js +328 -0
  69. package/dist/src/im.js.map +1 -0
  70. package/dist/src/media.d.ts +99 -0
  71. package/dist/src/media.d.ts.map +1 -0
  72. package/dist/src/media.js +454 -0
  73. package/dist/src/media.js.map +1 -0
  74. package/dist/src/mention.d.ts +49 -0
  75. package/dist/src/mention.d.ts.map +1 -0
  76. package/dist/src/mention.js +99 -0
  77. package/dist/src/mention.js.map +1 -0
  78. package/dist/src/monitor.d.ts +16 -0
  79. package/dist/src/monitor.d.ts.map +1 -0
  80. package/dist/src/monitor.js +288 -0
  81. package/dist/src/monitor.js.map +1 -0
  82. package/dist/src/onboarding.d.ts +3 -0
  83. package/dist/src/onboarding.d.ts.map +1 -0
  84. package/dist/src/onboarding.js +119 -0
  85. package/dist/src/onboarding.js.map +1 -0
  86. package/dist/src/outbound.d.ts +3 -0
  87. package/dist/src/outbound.d.ts.map +1 -0
  88. package/dist/src/outbound.js +53 -0
  89. package/dist/src/outbound.js.map +1 -0
  90. package/dist/src/perm-schema.d.ts +21 -0
  91. package/dist/src/perm-schema.d.ts.map +1 -0
  92. package/dist/src/perm-schema.js +47 -0
  93. package/dist/src/perm-schema.js.map +1 -0
  94. package/dist/src/perm.d.ts +14 -0
  95. package/dist/src/perm.d.ts.map +1 -0
  96. package/dist/src/perm.js +106 -0
  97. package/dist/src/perm.js.map +1 -0
  98. package/dist/src/policy.d.ts +28 -0
  99. package/dist/src/policy.d.ts.map +1 -0
  100. package/dist/src/policy.js +61 -0
  101. package/dist/src/policy.js.map +1 -0
  102. package/dist/src/probe.d.ts +4 -0
  103. package/dist/src/probe.d.ts.map +1 -0
  104. package/dist/src/probe.js +41 -0
  105. package/dist/src/probe.js.map +1 -0
  106. package/dist/src/reactions.d.ts +66 -0
  107. package/dist/src/reactions.d.ts.map +1 -0
  108. package/dist/src/reactions.js +104 -0
  109. package/dist/src/reactions.js.map +1 -0
  110. package/dist/src/reply-dispatcher.d.ts +41 -0
  111. package/dist/src/reply-dispatcher.d.ts.map +1 -0
  112. package/dist/src/reply-dispatcher.js +249 -0
  113. package/dist/src/reply-dispatcher.js.map +1 -0
  114. package/dist/src/runtime.d.ts +4 -0
  115. package/dist/src/runtime.d.ts.map +1 -0
  116. package/dist/src/runtime.js +11 -0
  117. package/dist/src/runtime.js.map +1 -0
  118. package/dist/src/send.d.ts +76 -0
  119. package/dist/src/send.d.ts.map +1 -0
  120. package/dist/src/send.js +250 -0
  121. package/dist/src/send.js.map +1 -0
  122. package/dist/src/sheets-schema.d.ts +12 -0
  123. package/dist/src/sheets-schema.d.ts.map +1 -0
  124. package/dist/src/sheets-schema.js +35 -0
  125. package/dist/src/sheets-schema.js.map +1 -0
  126. package/dist/src/sheets.d.ts +45 -0
  127. package/dist/src/sheets.d.ts.map +1 -0
  128. package/dist/src/sheets.js +197 -0
  129. package/dist/src/sheets.js.map +1 -0
  130. package/dist/src/streaming-card.d.ts +29 -0
  131. package/dist/src/streaming-card.d.ts.map +1 -0
  132. package/dist/src/streaming-card.js +192 -0
  133. package/dist/src/streaming-card.js.map +1 -0
  134. package/dist/src/targets.d.ts +7 -0
  135. package/dist/src/targets.d.ts.map +1 -0
  136. package/dist/src/targets.js +70 -0
  137. package/dist/src/targets.js.map +1 -0
  138. package/dist/src/task-schema.d.ts +19 -0
  139. package/dist/src/task-schema.d.ts.map +1 -0
  140. package/dist/src/task-schema.js +54 -0
  141. package/dist/src/task-schema.js.map +1 -0
  142. package/dist/src/task.d.ts +1193 -0
  143. package/dist/src/task.d.ts.map +1 -0
  144. package/dist/src/task.js +274 -0
  145. package/dist/src/task.js.map +1 -0
  146. package/dist/src/tools-config.d.ts +12 -0
  147. package/dist/src/tools-config.d.ts.map +1 -0
  148. package/dist/src/tools-config.js +24 -0
  149. package/dist/src/tools-config.js.map +1 -0
  150. package/dist/src/types.d.ts +74 -0
  151. package/dist/src/types.d.ts.map +1 -0
  152. package/dist/src/types.js +2 -0
  153. package/dist/src/types.js.map +1 -0
  154. package/dist/src/typing.d.ts +22 -0
  155. package/dist/src/typing.d.ts.map +1 -0
  156. package/dist/src/typing.js +60 -0
  157. package/dist/src/typing.js.map +1 -0
  158. package/dist/src/wiki-schema.d.ts +34 -0
  159. package/dist/src/wiki-schema.d.ts.map +1 -0
  160. package/dist/src/wiki-schema.js +43 -0
  161. package/dist/src/wiki-schema.js.map +1 -0
  162. package/dist/src/wiki.d.ts +3 -0
  163. package/dist/src/wiki.d.ts.map +1 -0
  164. package/dist/src/wiki.js +176 -0
  165. package/dist/src/wiki.js.map +1 -0
  166. package/openclaw.plugin.json +9 -0
  167. package/package.json +79 -0
@@ -0,0 +1,35 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ import { stringEnum } from "openclaw/plugin-sdk";
3
+ // ============ Sheets Tool Schema ============
4
+ const SHEETS_ACTIONS = [
5
+ "get_meta",
6
+ "read_range",
7
+ "write_range",
8
+ "append",
9
+ "insert_rows",
10
+ "add_sheet",
11
+ "list_sheets",
12
+ ];
13
+ export const FeishuSheetsSchema = Type.Object({
14
+ action: stringEnum(SHEETS_ACTIONS, { description: "操作类型" }),
15
+ // --- 共用 ---
16
+ spreadsheet_token: Type.String({
17
+ description: "电子表格 token (从 URL 或 Drive 获取)",
18
+ }),
19
+ // --- read_range / write_range / append ---
20
+ range: Type.Optional(Type.String({
21
+ description: "[read_range/write_range/append] 范围。格式: SheetId!A1:C10 或 SheetId!A:C。SheetId 可通过 list_sheets 获取",
22
+ })),
23
+ // --- write_range / append ---
24
+ values: Type.Optional(Type.Array(Type.Array(Type.Any(), { description: "行数据" }), {
25
+ description: "[write_range/append] 二维数组,每个子数组是一行",
26
+ })),
27
+ // --- insert_rows ---
28
+ sheet_id: Type.Optional(Type.String({ description: "[insert_rows/add_sheet] Sheet ID" })),
29
+ start_index: Type.Optional(Type.Number({ description: "[insert_rows] 插入位置(行索引,从 0 开始)" })),
30
+ count: Type.Optional(Type.Number({ description: "[insert_rows] 插入行数" })),
31
+ // --- add_sheet ---
32
+ title: Type.Optional(Type.String({ description: "[add_sheet] 新 Sheet 的标题" })),
33
+ index: Type.Optional(Type.Number({ description: "[add_sheet] 新 Sheet 的位置索引" })),
34
+ });
35
+ //# sourceMappingURL=sheets-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheets-schema.js","sourceRoot":"","sources":["../../src/sheets-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,+CAA+C;AAE/C,MAAM,cAAc,GAAG;IACrB,UAAU;IACV,YAAY;IACZ,aAAa;IACb,QAAQ;IACR,aAAa;IACb,WAAW;IACX,aAAa;CACL,CAAC;AAEX,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC;IAC5C,MAAM,EAAE,UAAU,CAAC,cAAc,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;IAC3D,aAAa;IACb,iBAAiB,EAAE,IAAI,CAAC,MAAM,CAAC;QAC7B,WAAW,EAAE,+BAA+B;KAC7C,CAAC;IACF,4CAA4C;IAC5C,KAAK,EAAE,IAAI,CAAC,QAAQ,CAClB,IAAI,CAAC,MAAM,CAAC;QACV,WAAW,EACT,gGAAgG;KACnG,CAAC,CACH;IACD,+BAA+B;IAC/B,MAAM,EAAE,IAAI,CAAC,QAAQ,CACnB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE;QACzD,WAAW,EAAE,oCAAoC;KAClD,CAAC,CACH;IACD,sBAAsB;IACtB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,kCAAkC,EAAE,CAAC,CAAC;IACzF,WAAW,EAAE,IAAI,CAAC,QAAQ,CACxB,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,gCAAgC,EAAE,CAAC,CAC/D;IACD,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAC,CAAC;IACxE,oBAAoB;IACpB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC,CAAC;IAC7E,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,2BAA2B,EAAE,CAAC,CAAC;CAChF,CAAC,CAAC"}
@@ -0,0 +1,45 @@
1
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
2
+ import { createFeishuClient } from "./client.js";
3
+ /** Get spreadsheet metadata */
4
+ export declare function getSpreadsheetMeta(client: ReturnType<typeof createFeishuClient>, spreadsheetToken: string): Promise<{
5
+ spreadsheet: {
6
+ title?: string | undefined;
7
+ owner_id?: string | undefined;
8
+ token?: string | undefined;
9
+ url?: string | undefined;
10
+ };
11
+ }>;
12
+ /** List all sheets in a spreadsheet */
13
+ export declare function listSheets(client: ReturnType<typeof createFeishuClient>, spreadsheetToken: string): Promise<{
14
+ sheets: any;
15
+ }>;
16
+ /** Read a range from a sheet */
17
+ export declare function readRange(client: ReturnType<typeof createFeishuClient>, spreadsheetToken: string, range: string): Promise<{
18
+ values: any;
19
+ range: any;
20
+ }>;
21
+ /** Write values to a range */
22
+ export declare function writeRange(client: ReturnType<typeof createFeishuClient>, spreadsheetToken: string, range: string, values: unknown[][]): Promise<{
23
+ updated_range: any;
24
+ updated_rows: any;
25
+ updated_columns: any;
26
+ updated_cells: any;
27
+ }>;
28
+ /** Append rows to a sheet */
29
+ export declare function appendData(client: ReturnType<typeof createFeishuClient>, spreadsheetToken: string, range: string, values: unknown[][]): Promise<{
30
+ appended_rows: number;
31
+ range: string;
32
+ }>;
33
+ /** Insert empty rows */
34
+ export declare function insertRows(client: ReturnType<typeof createFeishuClient>, spreadsheetToken: string, sheetId: string, startIndex: number, count: number): Promise<{
35
+ inserted: number;
36
+ start_index: number;
37
+ }>;
38
+ /** Add a new sheet to the spreadsheet */
39
+ export declare function addSheet(client: ReturnType<typeof createFeishuClient>, spreadsheetToken: string, title: string, index?: number): Promise<{
40
+ sheet_id: any;
41
+ title: any;
42
+ index: any;
43
+ }>;
44
+ export declare function registerFeishuSheetsTools(api: OpenClawPluginApi): void;
45
+ //# sourceMappingURL=sheets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheets.d.ts","sourceRoot":"","sources":["../../src/sheets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAejD,+BAA+B;AAC/B,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC7C,gBAAgB,EAAE,MAAM;;;;;;;GAazB;AAED,uCAAuC;AACvC,wBAAsB,UAAU,CAC9B,MAAM,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC7C,gBAAgB,EAAE,MAAM;;GAmBzB;AAED,gCAAgC;AAChC,wBAAsB,SAAS,CAC7B,MAAM,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC7C,gBAAgB,EAAE,MAAM,EACxB,KAAK,EAAE,MAAM;;;GAgBd;AAED,8BAA8B;AAC9B,wBAAsB,UAAU,CAC9B,MAAM,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC7C,gBAAgB,EAAE,MAAM,EACxB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,OAAO,EAAE,EAAE;;;;;GAiBpB;AAED,6BAA6B;AAC7B,wBAAsB,UAAU,CAC9B,MAAM,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC7C,gBAAgB,EAAE,MAAM,EACxB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,OAAO,EAAE,EAAE;;;GAepB;AAED,wBAAwB;AACxB,wBAAsB,UAAU,CAC9B,MAAM,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC7C,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM;;;GAwBd;AAED,yCAAyC;AACzC,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC7C,gBAAgB,EAAE,MAAM,EACxB,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM;;;;GAmBf;AAID,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,iBAAiB,QAmF/D"}
@@ -0,0 +1,197 @@
1
+ import { listEnabledFeishuAccounts } from "./accounts.js";
2
+ import { createFeishuClient } from "./client.js";
3
+ import { resolveToolsConfig } from "./tools-config.js";
4
+ import { FeishuSheetsSchema } from "./sheets-schema.js";
5
+ // ============ Helpers ============
6
+ function json(data) {
7
+ return {
8
+ content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
9
+ details: data,
10
+ };
11
+ }
12
+ // ============ Core Functions ============
13
+ /** Get spreadsheet metadata */
14
+ export async function getSpreadsheetMeta(client, spreadsheetToken) {
15
+ const res = await client.sheets.v3.spreadsheet.get({
16
+ path: { spreadsheet_token: spreadsheetToken },
17
+ // oxlint-disable-next-line typescript/no-explicit-any
18
+ });
19
+ if (res.code !== 0) {
20
+ throw new Error(res.msg);
21
+ }
22
+ return {
23
+ spreadsheet: res.data?.spreadsheet,
24
+ };
25
+ }
26
+ /** List all sheets in a spreadsheet */
27
+ export async function listSheets(client, spreadsheetToken) {
28
+ const res = await client.sheets.v3.spreadsheetSheet.list({
29
+ path: { spreadsheet_token: spreadsheetToken },
30
+ // oxlint-disable-next-line typescript/no-explicit-any
31
+ });
32
+ if (res.code !== 0) {
33
+ throw new Error(res.msg);
34
+ }
35
+ return {
36
+ sheets: (res.data?.items ?? []).map((s) => ({
37
+ sheet_id: s.sheet_id,
38
+ title: s.title,
39
+ index: s.index,
40
+ row_count: s.grid_properties?.row_count,
41
+ column_count: s.grid_properties?.column_count,
42
+ })),
43
+ };
44
+ }
45
+ /** Read a range from a sheet */
46
+ export async function readRange(client, spreadsheetToken, range) {
47
+ const res = await client.sheets.v3.spreadsheetSheetRange.read({
48
+ path: { spreadsheet_token: spreadsheetToken, range },
49
+ // oxlint-disable-next-line typescript/no-explicit-any
50
+ });
51
+ // Fallback: try v2 API if v3 fails
52
+ if (res.code !== 0) {
53
+ throw new Error(res.msg);
54
+ }
55
+ return {
56
+ values: res.data?.valueRange?.values ?? res.data?.values ?? [],
57
+ range: res.data?.valueRange?.range ?? range,
58
+ };
59
+ }
60
+ /** Write values to a range */
61
+ export async function writeRange(client, spreadsheetToken, range, values) {
62
+ const res = await client.sheets.v3.spreadsheetSheetRange.write({
63
+ path: { spreadsheet_token: spreadsheetToken, range },
64
+ data: { values },
65
+ // oxlint-disable-next-line typescript/no-explicit-any
66
+ });
67
+ if (res.code !== 0) {
68
+ throw new Error(res.msg);
69
+ }
70
+ return {
71
+ updated_range: res.data?.updatedRange ?? range,
72
+ updated_rows: res.data?.updatedRows ?? values.length,
73
+ updated_columns: res.data?.updatedColumns,
74
+ updated_cells: res.data?.updatedCells,
75
+ };
76
+ }
77
+ /** Append rows to a sheet */
78
+ export async function appendData(client, spreadsheetToken, range, values) {
79
+ const res = await client.sheets.v3.spreadsheetSheetRange.write({
80
+ path: { spreadsheet_token: spreadsheetToken, range },
81
+ data: { values },
82
+ // oxlint-disable-next-line typescript/no-explicit-any
83
+ });
84
+ if (res.code !== 0) {
85
+ throw new Error(res.msg);
86
+ }
87
+ return {
88
+ appended_rows: values.length,
89
+ range,
90
+ };
91
+ }
92
+ /** Insert empty rows */
93
+ export async function insertRows(client, spreadsheetToken, sheetId, startIndex, count) {
94
+ const res = await client.sheets.v3.spreadsheetSheet.patch({
95
+ path: { spreadsheet_token: spreadsheetToken, sheet_id: sheetId },
96
+ data: {
97
+ insert_range: {
98
+ dimension: {
99
+ sheet_id: sheetId,
100
+ major_dimension: "ROWS",
101
+ start_index: startIndex,
102
+ end_index: startIndex + count,
103
+ },
104
+ },
105
+ },
106
+ // oxlint-disable-next-line typescript/no-explicit-any
107
+ });
108
+ if (res.code !== 0) {
109
+ throw new Error(res.msg);
110
+ }
111
+ return {
112
+ inserted: count,
113
+ start_index: startIndex,
114
+ };
115
+ }
116
+ /** Add a new sheet to the spreadsheet */
117
+ export async function addSheet(client, spreadsheetToken, title, index) {
118
+ const res = await client.sheets.v3.spreadsheetSheet.create({
119
+ path: { spreadsheet_token: spreadsheetToken },
120
+ data: {
121
+ title,
122
+ ...(index !== undefined && { index }),
123
+ },
124
+ // oxlint-disable-next-line typescript/no-explicit-any
125
+ });
126
+ if (res.code !== 0) {
127
+ throw new Error(res.msg);
128
+ }
129
+ return {
130
+ sheet_id: res.data?.sheet?.sheet_id,
131
+ title: res.data?.sheet?.title,
132
+ index: res.data?.sheet?.index,
133
+ };
134
+ }
135
+ // ============ Tool Registration ============
136
+ export function registerFeishuSheetsTools(api) {
137
+ if (!api.config) {
138
+ api.logger.debug?.("feishu_sheets: No config available, skipping");
139
+ return;
140
+ }
141
+ const accounts = listEnabledFeishuAccounts(api.config);
142
+ if (accounts.length === 0) {
143
+ api.logger.debug?.("feishu_sheets: No Feishu accounts configured, skipping");
144
+ return;
145
+ }
146
+ const firstAccount = accounts[0];
147
+ const toolsCfg = resolveToolsConfig(firstAccount.config.tools);
148
+ if (!toolsCfg.sheets) {
149
+ api.logger.debug?.("feishu_sheets: Sheets tools disabled in config");
150
+ return;
151
+ }
152
+ const getClient = () => createFeishuClient(firstAccount);
153
+ api.registerTool({
154
+ name: "feishu_sheets",
155
+ label: "飞书 - 电子表格",
156
+ description: `飞书电子表格操作工具。支持以下操作:
157
+ - get_meta: 获取电子表格元信息
158
+ - list_sheets: 列出所有 Sheet 页
159
+ - read_range: 读取指定范围 (格式: SheetId!A1:C10)
160
+ - write_range: 写入指定范围
161
+ - append: 在指定范围追加数据
162
+ - insert_rows: 插入空行
163
+ - add_sheet: 新增 Sheet 页`,
164
+ parameters: FeishuSheetsSchema,
165
+ async execute(_toolCallId, params) {
166
+ const p = params;
167
+ const action = p.action;
168
+ const client = getClient();
169
+ const token = p.spreadsheet_token;
170
+ try {
171
+ switch (action) {
172
+ case "get_meta":
173
+ return json(await getSpreadsheetMeta(client, token));
174
+ case "list_sheets":
175
+ return json(await listSheets(client, token));
176
+ case "read_range":
177
+ return json(await readRange(client, token, p.range));
178
+ case "write_range":
179
+ return json(await writeRange(client, token, p.range, p.values));
180
+ case "append":
181
+ return json(await appendData(client, token, p.range, p.values));
182
+ case "insert_rows":
183
+ return json(await insertRows(client, token, p.sheet_id, p.start_index, p.count));
184
+ case "add_sheet":
185
+ return json(await addSheet(client, token, p.title, p.index));
186
+ default:
187
+ return json({ error: `Unknown action: ${action}` });
188
+ }
189
+ }
190
+ catch (err) {
191
+ return json({ error: err instanceof Error ? err.message : String(err) });
192
+ }
193
+ },
194
+ }, { name: "feishu_sheets" });
195
+ api.logger.info?.("feishu_sheets: Registered feishu_sheets tool (7 actions)");
196
+ }
197
+ //# sourceMappingURL=sheets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheets.js","sourceRoot":"","sources":["../../src/sheets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Feishu Streaming Card - Card Kit streaming API for real-time text output
3
+ */
4
+ import type { Client } from "@larksuiteoapi/node-sdk";
5
+ import type { FeishuDomain } from "./types.js";
6
+ type Credentials = {
7
+ appId: string;
8
+ appSecret: string;
9
+ domain?: FeishuDomain;
10
+ };
11
+ /** Streaming card session manager */
12
+ export declare class FeishuStreamingSession {
13
+ private client;
14
+ private creds;
15
+ private state;
16
+ private queue;
17
+ private closed;
18
+ private log?;
19
+ private lastUpdateTime;
20
+ private pendingText;
21
+ private updateThrottleMs;
22
+ constructor(client: Client, creds: Credentials, log?: (msg: string) => void);
23
+ start(receiveId: string, receiveIdType?: "open_id" | "user_id" | "union_id" | "email" | "chat_id"): Promise<void>;
24
+ update(text: string): Promise<void>;
25
+ close(finalText?: string): Promise<void>;
26
+ isActive(): boolean;
27
+ }
28
+ export {};
29
+ //# sourceMappingURL=streaming-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming-card.d.ts","sourceRoot":"","sources":["../../src/streaming-card.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,KAAK,WAAW,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,YAAY,CAAA;CAAE,CAAC;AAoD/E,qCAAqC;AACrC,qBAAa,sBAAsB;IACjC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,KAAK,CAA0B;IACvC,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,GAAG,CAAC,CAAwB;IACpC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,gBAAgB,CAAO;gBAEnB,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI;IAMrE,KAAK,CACT,SAAS,EAAE,MAAM,EACjB,aAAa,GAAE,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,SAAqB,GAClF,OAAO,CAAC,IAAI,CAAC;IAsDV,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuCnC,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoD9C,QAAQ,IAAI,OAAO;CAGpB"}
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Feishu Streaming Card - Card Kit streaming API for real-time text output
3
+ */
4
+ // Token cache (keyed by domain + appId)
5
+ const tokenCache = new Map();
6
+ function resolveApiBase(domain) {
7
+ if (domain === "lark") {
8
+ return "https://open.larksuite.com/open-apis";
9
+ }
10
+ if (domain && domain !== "feishu" && domain.startsWith("http")) {
11
+ return `${domain.replace(/\/+$/, "")}/open-apis`;
12
+ }
13
+ return "https://open.feishu.cn/open-apis";
14
+ }
15
+ async function getToken(creds) {
16
+ const key = `${creds.domain ?? "feishu"}|${creds.appId}`;
17
+ const cached = tokenCache.get(key);
18
+ if (cached && cached.expiresAt > Date.now() + 60000) {
19
+ return cached.token;
20
+ }
21
+ const res = await fetch(`${resolveApiBase(creds.domain)}/auth/v3/tenant_access_token/internal`, {
22
+ method: "POST",
23
+ headers: { "Content-Type": "application/json" },
24
+ body: JSON.stringify({ app_id: creds.appId, app_secret: creds.appSecret }),
25
+ });
26
+ const data = (await res.json());
27
+ if (data.code !== 0 || !data.tenant_access_token) {
28
+ throw new Error(`Token error: ${data.msg}`);
29
+ }
30
+ tokenCache.set(key, {
31
+ token: data.tenant_access_token,
32
+ expiresAt: Date.now() + (data.expire ?? 7200) * 1000,
33
+ });
34
+ return data.tenant_access_token;
35
+ }
36
+ function truncateSummary(text, max = 50) {
37
+ if (!text) {
38
+ return "";
39
+ }
40
+ const clean = text.replace(/\n/g, " ").trim();
41
+ return clean.length <= max ? clean : clean.slice(0, max - 3) + "...";
42
+ }
43
+ /** Streaming card session manager */
44
+ export class FeishuStreamingSession {
45
+ client;
46
+ creds;
47
+ state = null;
48
+ queue = Promise.resolve();
49
+ closed = false;
50
+ log;
51
+ lastUpdateTime = 0;
52
+ pendingText = null;
53
+ updateThrottleMs = 100; // Throttle updates to max 10/sec
54
+ constructor(client, creds, log) {
55
+ this.client = client;
56
+ this.creds = creds;
57
+ this.log = log;
58
+ }
59
+ async start(receiveId, receiveIdType = "chat_id") {
60
+ if (this.state) {
61
+ return;
62
+ }
63
+ const apiBase = resolveApiBase(this.creds.domain);
64
+ const cardJson = {
65
+ schema: "2.0",
66
+ config: {
67
+ streaming_mode: true,
68
+ summary: { content: "[Generating...]" },
69
+ streaming_config: { print_frequency_ms: { default: 50 }, print_step: { default: 2 } },
70
+ },
71
+ body: {
72
+ elements: [{ tag: "markdown", content: "⏳ Thinking...", element_id: "content" }],
73
+ },
74
+ };
75
+ // Create card entity
76
+ const createRes = await fetch(`${apiBase}/cardkit/v1/cards`, {
77
+ method: "POST",
78
+ headers: {
79
+ Authorization: `Bearer ${await getToken(this.creds)}`,
80
+ "Content-Type": "application/json",
81
+ },
82
+ body: JSON.stringify({ type: "card_json", data: JSON.stringify(cardJson) }),
83
+ });
84
+ const createData = (await createRes.json());
85
+ if (createData.code !== 0 || !createData.data?.card_id) {
86
+ throw new Error(`Create card failed: ${createData.msg}`);
87
+ }
88
+ const cardId = createData.data.card_id;
89
+ // Send card message
90
+ const sendRes = await this.client.im.message.create({
91
+ params: { receive_id_type: receiveIdType },
92
+ data: {
93
+ receive_id: receiveId,
94
+ msg_type: "interactive",
95
+ content: JSON.stringify({ type: "card", data: { card_id: cardId } }),
96
+ },
97
+ });
98
+ if (sendRes.code !== 0 || !sendRes.data?.message_id) {
99
+ throw new Error(`Send card failed: ${sendRes.msg}`);
100
+ }
101
+ this.state = { cardId, messageId: sendRes.data.message_id, sequence: 1, currentText: "" };
102
+ this.log?.(`Started streaming: cardId=${cardId}, messageId=${sendRes.data.message_id}`);
103
+ }
104
+ async update(text) {
105
+ // Critical: Check closed state immediately, before queue operations.
106
+ // This prevents updates queued before close() from executing after streaming is closed.
107
+ if (this.closed || !this.state) {
108
+ return;
109
+ }
110
+ // Throttle: skip if updated recently, but remember pending text
111
+ const now = Date.now();
112
+ if (now - this.lastUpdateTime < this.updateThrottleMs) {
113
+ this.pendingText = text;
114
+ // CRITICAL FIX: Don't return early - continue to queue to ensure all updates are sent
115
+ // The old early return caused partial updates to be lost when throttle was active
116
+ }
117
+ this.pendingText = null;
118
+ this.lastUpdateTime = now;
119
+ this.queue = this.queue.then(async () => {
120
+ if (!this.state || this.closed) {
121
+ return;
122
+ }
123
+ this.state.currentText = text;
124
+ this.state.sequence += 1;
125
+ const apiBase = resolveApiBase(this.creds.domain);
126
+ await fetch(`${apiBase}/cardkit/v1/cards/${this.state.cardId}/elements/content/content`, {
127
+ method: "PUT",
128
+ headers: {
129
+ Authorization: `Bearer ${await getToken(this.creds)}`,
130
+ "Content-Type": "application/json",
131
+ },
132
+ body: JSON.stringify({
133
+ content: text,
134
+ sequence: this.state.sequence,
135
+ uuid: `s_${this.state.cardId}_${this.state.sequence}`,
136
+ }),
137
+ }).catch((e) => this.log?.(`Update failed: ${String(e)}`));
138
+ });
139
+ await this.queue;
140
+ }
141
+ async close(finalText) {
142
+ if (!this.state || this.closed) {
143
+ return;
144
+ }
145
+ this.closed = true;
146
+ await this.queue;
147
+ // Use finalText if explicitly provided (even empty string to suppress pendingText fallback),
148
+ // otherwise fall back to pending throttled text or current text.
149
+ const text = finalText !== undefined ? finalText : (this.pendingText ?? this.state.currentText);
150
+ const apiBase = resolveApiBase(this.creds.domain);
151
+ // Send final content update if:
152
+ // - text differs from what's already displayed, AND
153
+ // - either text has content, OR text is "" (explicitly clearing the card for silent replies)
154
+ if (text !== this.state.currentText && (text || this.state.currentText)) {
155
+ this.state.sequence += 1;
156
+ await fetch(`${apiBase}/cardkit/v1/cards/${this.state.cardId}/elements/content/content`, {
157
+ method: "PUT",
158
+ headers: {
159
+ Authorization: `Bearer ${await getToken(this.creds)}`,
160
+ "Content-Type": "application/json",
161
+ },
162
+ body: JSON.stringify({
163
+ content: text,
164
+ sequence: this.state.sequence,
165
+ uuid: `s_${this.state.cardId}_${this.state.sequence}`,
166
+ }),
167
+ }).catch(() => { });
168
+ this.state.currentText = text;
169
+ }
170
+ // Close streaming mode
171
+ this.state.sequence += 1;
172
+ await fetch(`${apiBase}/cardkit/v1/cards/${this.state.cardId}/settings`, {
173
+ method: "PATCH",
174
+ headers: {
175
+ Authorization: `Bearer ${await getToken(this.creds)}`,
176
+ "Content-Type": "application/json; charset=utf-8",
177
+ },
178
+ body: JSON.stringify({
179
+ settings: JSON.stringify({
180
+ config: { streaming_mode: false, summary: { content: truncateSummary(text) } },
181
+ }),
182
+ sequence: this.state.sequence,
183
+ uuid: `c_${this.state.cardId}_${this.state.sequence}`,
184
+ }),
185
+ }).catch((e) => this.log?.(`Close failed: ${String(e)}`));
186
+ this.log?.(`Closed streaming: cardId=${this.state.cardId}`);
187
+ }
188
+ isActive() {
189
+ return this.state !== null && !this.closed;
190
+ }
191
+ }
192
+ //# sourceMappingURL=streaming-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming-card.js","sourceRoot":"","sources":["../../src/streaming-card.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,wCAAwC;AACxC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAgD,CAAC;AAE3E,SAAS,cAAc,CAAC,MAAqB;IAC3C,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,sCAAsC,CAAC;IAChD,CAAC;IACD,IAAI,MAAM,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/D,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC;IACnD,CAAC;IACD,OAAO,kCAAkC,CAAC;AAC5C,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,KAAkB;IACxC,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,MAAM,IAAI,QAAQ,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;IACzD,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,MAAM,IAAI,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;QACpD,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,uCAAuC,EAAE;QAC9F,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;KAC3E,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAK7B,CAAC;IACF,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9C,CAAC;IACD,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE;QAClB,KAAK,EAAE,IAAI,CAAC,mBAAmB;QAC/B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,IAAI;KACrD,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,mBAAmB,CAAC;AAClC,CAAC;AAED,SAAS,eAAe,CAAC,IAAY,EAAE,GAAG,GAAG,EAAE;IAC7C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,OAAO,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;AACvE,CAAC;AAED,qCAAqC;AACrC,MAAM,OAAO,sBAAsB;IACzB,MAAM,CAAS;IACf,KAAK,CAAc;IACnB,KAAK,GAAqB,IAAI,CAAC;IAC/B,KAAK,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IACzC,MAAM,GAAG,KAAK,CAAC;IACf,GAAG,CAAyB;IAC5B,cAAc,GAAG,CAAC,CAAC;IACnB,WAAW,GAAkB,IAAI,CAAC;IAClC,gBAAgB,GAAG,GAAG,CAAC,CAAC,iCAAiC;IAEjE,YAAY,MAAc,EAAE,KAAkB,EAAE,GAA2B;QACzE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,KAAK,CACT,SAAiB,EACjB,gBAA0E,SAAS;QAEnF,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAG;YACf,MAAM,EAAE,KAAK;YACb,MAAM,EAAE;gBACN,cAAc,EAAE,IAAI;gBACpB,OAAO,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE;gBACvC,gBAAgB,EAAE,EAAE,kBAAkB,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE;aACtF;YACD,IAAI,EAAE;gBACJ,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;aACjF;SACF,CAAC;QAEF,qBAAqB;QACrB,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,mBAAmB,EAAE;YAC3D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;gBACrD,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;SAC5E,CAAC,CAAC;QACH,MAAM,UAAU,GAAG,CAAC,MAAM,SAAS,CAAC,IAAI,EAAE,CAIzC,CAAC;QACF,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,uBAAuB,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC;QAC3D,CAAC;QACD,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;QAEvC,oBAAoB;QACpB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;YAClD,MAAM,EAAE,EAAE,eAAe,EAAE,aAAa,EAAE;YAC1C,IAAI,EAAE;gBACJ,UAAU,EAAE,SAAS;gBACrB,QAAQ,EAAE,aAAa;gBACvB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;aACrE;SACF,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,qBAAqB,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;QAC1F,IAAI,CAAC,GAAG,EAAE,CAAC,6BAA6B,MAAM,eAAe,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1F,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,qEAAqE;QACrE,wFAAwF;QACxF,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QACD,gEAAgE;QAChE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,GAAG,GAAG,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,sFAAsF;YACtF,kFAAkF;QACpF,CAAC;QACD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,cAAc,GAAG,GAAG,CAAC;QAE1B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACtC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC/B,OAAO;YACT,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;YAC9B,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC;YACzB,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAClD,MAAM,KAAK,CAAC,GAAG,OAAO,qBAAqB,IAAI,CAAC,KAAK,CAAC,MAAM,2BAA2B,EAAE;gBACvF,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;oBACrD,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,OAAO,EAAE,IAAI;oBACb,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ;oBAC7B,IAAI,EAAE,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;iBACtD,CAAC;aACH,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,kBAAkB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,SAAkB;QAC5B,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,MAAM,IAAI,CAAC,KAAK,CAAC;QAEjB,6FAA6F;QAC7F,iEAAiE;QACjE,MAAM,IAAI,GAAG,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAChG,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAElD,gCAAgC;QAChC,oDAAoD;QACpD,6FAA6F;QAC7F,IAAI,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;YACxE,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC;YACzB,MAAM,KAAK,CAAC,GAAG,OAAO,qBAAqB,IAAI,CAAC,KAAK,CAAC,MAAM,2BAA2B,EAAE;gBACvF,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;oBACrD,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,OAAO,EAAE,IAAI;oBACb,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ;oBAC7B,IAAI,EAAE,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;iBACtD,CAAC;aACH,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACnB,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;QAChC,CAAC;QAED,uBAAuB;QACvB,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC;QACzB,MAAM,KAAK,CAAC,GAAG,OAAO,qBAAqB,IAAI,CAAC,KAAK,CAAC,MAAM,WAAW,EAAE;YACvE,MAAM,EAAE,OAAO;YACf,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;gBACrD,cAAc,EAAE,iCAAiC;aAClD;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC;oBACvB,MAAM,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE;iBAC/E,CAAC;gBACF,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ;gBAC7B,IAAI,EAAE,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;aACtD,CAAC;SACH,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,iBAAiB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAE1D,IAAI,CAAC,GAAG,EAAE,CAAC,4BAA4B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAC7C,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import type { FeishuIdType } from "./types.js";
2
+ export declare function detectIdType(id: string): FeishuIdType | null;
3
+ export declare function normalizeFeishuTarget(raw: string): string | null;
4
+ export declare function formatFeishuTarget(id: string, type?: FeishuIdType): string;
5
+ export declare function resolveReceiveIdType(id: string): "chat_id" | "open_id" | "user_id";
6
+ export declare function looksLikeFeishuId(raw: string): boolean;
7
+ //# sourceMappingURL=targets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"targets.d.ts","sourceRoot":"","sources":["../../src/targets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM/C,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAY5D;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkBhE;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,MAAM,CAS1E;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CASlF;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAetD"}
@@ -0,0 +1,70 @@
1
+ const CHAT_ID_PREFIX = "oc_";
2
+ const OPEN_ID_PREFIX = "ou_";
3
+ const USER_ID_REGEX = /^[a-zA-Z0-9_-]+$/;
4
+ export function detectIdType(id) {
5
+ const trimmed = id.trim();
6
+ if (trimmed.startsWith(CHAT_ID_PREFIX)) {
7
+ return "chat_id";
8
+ }
9
+ if (trimmed.startsWith(OPEN_ID_PREFIX)) {
10
+ return "open_id";
11
+ }
12
+ if (USER_ID_REGEX.test(trimmed)) {
13
+ return "user_id";
14
+ }
15
+ return null;
16
+ }
17
+ export function normalizeFeishuTarget(raw) {
18
+ const trimmed = raw.trim();
19
+ if (!trimmed) {
20
+ return null;
21
+ }
22
+ const lowered = trimmed.toLowerCase();
23
+ if (lowered.startsWith("chat:")) {
24
+ return trimmed.slice("chat:".length).trim() || null;
25
+ }
26
+ if (lowered.startsWith("user:")) {
27
+ return trimmed.slice("user:".length).trim() || null;
28
+ }
29
+ if (lowered.startsWith("open_id:")) {
30
+ return trimmed.slice("open_id:".length).trim() || null;
31
+ }
32
+ return trimmed;
33
+ }
34
+ export function formatFeishuTarget(id, type) {
35
+ const trimmed = id.trim();
36
+ if (type === "chat_id" || trimmed.startsWith(CHAT_ID_PREFIX)) {
37
+ return `chat:${trimmed}`;
38
+ }
39
+ if (type === "open_id" || trimmed.startsWith(OPEN_ID_PREFIX)) {
40
+ return `user:${trimmed}`;
41
+ }
42
+ return trimmed;
43
+ }
44
+ export function resolveReceiveIdType(id) {
45
+ const trimmed = id.trim();
46
+ if (trimmed.startsWith(CHAT_ID_PREFIX)) {
47
+ return "chat_id";
48
+ }
49
+ if (trimmed.startsWith(OPEN_ID_PREFIX)) {
50
+ return "open_id";
51
+ }
52
+ return "user_id";
53
+ }
54
+ export function looksLikeFeishuId(raw) {
55
+ const trimmed = raw.trim();
56
+ if (!trimmed) {
57
+ return false;
58
+ }
59
+ if (/^(chat|user|open_id):/i.test(trimmed)) {
60
+ return true;
61
+ }
62
+ if (trimmed.startsWith(CHAT_ID_PREFIX)) {
63
+ return true;
64
+ }
65
+ if (trimmed.startsWith(OPEN_ID_PREFIX)) {
66
+ return true;
67
+ }
68
+ return false;
69
+ }
70
+ //# sourceMappingURL=targets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"targets.js","sourceRoot":"","sources":["../../src/targets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export declare const FeishuTaskSchema: import("@sinclair/typebox").TObject<{
2
+ action: import("@sinclair/typebox").TUnsafe<"update" | "get" | "create" | "list" | "complete" | "add_members" | "add_reminder" | "add_comment">;
3
+ summary: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
4
+ description: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
5
+ due: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
6
+ members: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
7
+ id: import("@sinclair/typebox").TString;
8
+ role: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnsafe<"assignee" | "follower">>;
9
+ }>>>;
10
+ task_guid: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
11
+ member_ids: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
12
+ role: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnsafe<"assignee" | "follower">>;
13
+ relative_fire_minutes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
14
+ page_size: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
15
+ page_token: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
16
+ sender_open_id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
17
+ content: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
18
+ }>;
19
+ //# sourceMappingURL=task-schema.d.ts.map