cc-lark 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (298) hide show
  1. package/.github/workflows/ci.yml +47 -0
  2. package/.github/workflows/release.yml +47 -0
  3. package/.github/workflows/sync-upstream.yml +127 -0
  4. package/.prettierrc.json +7 -0
  5. package/README.md +214 -0
  6. package/dist/core/api-error.d.ts +193 -0
  7. package/dist/core/api-error.d.ts.map +1 -0
  8. package/dist/core/api-error.js +263 -0
  9. package/dist/core/api-error.js.map +1 -0
  10. package/dist/core/auth-errors.d.ts +13 -0
  11. package/dist/core/auth-errors.d.ts.map +1 -0
  12. package/dist/core/auth-errors.js +14 -0
  13. package/dist/core/auth-errors.js.map +1 -0
  14. package/dist/core/config.d.ts +60 -0
  15. package/dist/core/config.d.ts.map +1 -0
  16. package/dist/core/config.js +115 -0
  17. package/dist/core/config.js.map +1 -0
  18. package/dist/core/device-flow.d.ts +80 -0
  19. package/dist/core/device-flow.d.ts.map +1 -0
  20. package/dist/core/device-flow.js +231 -0
  21. package/dist/core/device-flow.js.map +1 -0
  22. package/dist/core/index.d.ts +16 -0
  23. package/dist/core/index.d.ts.map +1 -0
  24. package/dist/core/index.js +16 -0
  25. package/dist/core/index.js.map +1 -0
  26. package/dist/core/lark-client.d.ts +136 -0
  27. package/dist/core/lark-client.d.ts.map +1 -0
  28. package/dist/core/lark-client.js +315 -0
  29. package/dist/core/lark-client.js.map +1 -0
  30. package/dist/core/token-store.d.ts +67 -0
  31. package/dist/core/token-store.d.ts.map +1 -0
  32. package/dist/core/token-store.js +215 -0
  33. package/dist/core/token-store.js.map +1 -0
  34. package/dist/core/types.d.ts +286 -0
  35. package/dist/core/types.d.ts.map +1 -0
  36. package/dist/core/types.js +11 -0
  37. package/dist/core/types.js.map +1 -0
  38. package/dist/core/uat-client.d.ts +64 -0
  39. package/dist/core/uat-client.d.ts.map +1 -0
  40. package/dist/core/uat-client.js +227 -0
  41. package/dist/core/uat-client.js.map +1 -0
  42. package/dist/core/version.d.ts +26 -0
  43. package/dist/core/version.d.ts.map +1 -0
  44. package/dist/core/version.js +50 -0
  45. package/dist/core/version.js.map +1 -0
  46. package/dist/index.d.ts +12 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +116 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/tools/bitable/app.d.ts +20 -0
  51. package/dist/tools/bitable/app.d.ts.map +1 -0
  52. package/dist/tools/bitable/app.js +301 -0
  53. package/dist/tools/bitable/app.js.map +1 -0
  54. package/dist/tools/bitable/field.d.ts +19 -0
  55. package/dist/tools/bitable/field.d.ts.map +1 -0
  56. package/dist/tools/bitable/field.js +315 -0
  57. package/dist/tools/bitable/field.js.map +1 -0
  58. package/dist/tools/bitable/index.d.ts +21 -0
  59. package/dist/tools/bitable/index.d.ts.map +1 -0
  60. package/dist/tools/bitable/index.js +39 -0
  61. package/dist/tools/bitable/index.js.map +1 -0
  62. package/dist/tools/bitable/record.d.ts +22 -0
  63. package/dist/tools/bitable/record.d.ts.map +1 -0
  64. package/dist/tools/bitable/record.js +434 -0
  65. package/dist/tools/bitable/record.js.map +1 -0
  66. package/dist/tools/bitable/table.d.ts +21 -0
  67. package/dist/tools/bitable/table.d.ts.map +1 -0
  68. package/dist/tools/bitable/table.js +361 -0
  69. package/dist/tools/bitable/table.js.map +1 -0
  70. package/dist/tools/calendar/calendar.d.ts +18 -0
  71. package/dist/tools/calendar/calendar.d.ts.map +1 -0
  72. package/dist/tools/calendar/calendar.js +192 -0
  73. package/dist/tools/calendar/calendar.js.map +1 -0
  74. package/dist/tools/calendar/event.d.ts +20 -0
  75. package/dist/tools/calendar/event.d.ts.map +1 -0
  76. package/dist/tools/calendar/event.js +465 -0
  77. package/dist/tools/calendar/event.js.map +1 -0
  78. package/dist/tools/calendar/index.d.ts +19 -0
  79. package/dist/tools/calendar/index.d.ts.map +1 -0
  80. package/dist/tools/calendar/index.js +37 -0
  81. package/dist/tools/calendar/index.js.map +1 -0
  82. package/dist/tools/chat/chat.d.ts +11 -0
  83. package/dist/tools/chat/chat.d.ts.map +1 -0
  84. package/dist/tools/chat/chat.js +106 -0
  85. package/dist/tools/chat/chat.js.map +1 -0
  86. package/dist/tools/chat/index.d.ts +11 -0
  87. package/dist/tools/chat/index.d.ts.map +1 -0
  88. package/dist/tools/chat/index.js +20 -0
  89. package/dist/tools/chat/index.js.map +1 -0
  90. package/dist/tools/chat/members.d.ts +9 -0
  91. package/dist/tools/chat/members.d.ts.map +1 -0
  92. package/dist/tools/chat/members.js +80 -0
  93. package/dist/tools/chat/members.js.map +1 -0
  94. package/dist/tools/common/get-user.d.ts +11 -0
  95. package/dist/tools/common/get-user.d.ts.map +1 -0
  96. package/dist/tools/common/get-user.js +112 -0
  97. package/dist/tools/common/get-user.js.map +1 -0
  98. package/dist/tools/common/index.d.ts +11 -0
  99. package/dist/tools/common/index.d.ts.map +1 -0
  100. package/dist/tools/common/index.js +20 -0
  101. package/dist/tools/common/index.js.map +1 -0
  102. package/dist/tools/common/search-user.d.ts +9 -0
  103. package/dist/tools/common/search-user.d.ts.map +1 -0
  104. package/dist/tools/common/search-user.js +88 -0
  105. package/dist/tools/common/search-user.js.map +1 -0
  106. package/dist/tools/doc/create.d.ts +17 -0
  107. package/dist/tools/doc/create.d.ts.map +1 -0
  108. package/dist/tools/doc/create.js +159 -0
  109. package/dist/tools/doc/create.js.map +1 -0
  110. package/dist/tools/doc/fetch.d.ts +17 -0
  111. package/dist/tools/doc/fetch.d.ts.map +1 -0
  112. package/dist/tools/doc/fetch.js +123 -0
  113. package/dist/tools/doc/fetch.js.map +1 -0
  114. package/dist/tools/doc/index.d.ts +21 -0
  115. package/dist/tools/doc/index.d.ts.map +1 -0
  116. package/dist/tools/doc/index.js +33 -0
  117. package/dist/tools/doc/index.js.map +1 -0
  118. package/dist/tools/doc/shared.d.ts +69 -0
  119. package/dist/tools/doc/shared.d.ts.map +1 -0
  120. package/dist/tools/doc/shared.js +172 -0
  121. package/dist/tools/doc/shared.js.map +1 -0
  122. package/dist/tools/doc/update.d.ts +25 -0
  123. package/dist/tools/doc/update.d.ts.map +1 -0
  124. package/dist/tools/doc/update.js +208 -0
  125. package/dist/tools/doc/update.js.map +1 -0
  126. package/dist/tools/drive/file.d.ts +13 -0
  127. package/dist/tools/drive/file.d.ts.map +1 -0
  128. package/dist/tools/drive/file.js +212 -0
  129. package/dist/tools/drive/file.js.map +1 -0
  130. package/dist/tools/drive/index.d.ts +12 -0
  131. package/dist/tools/drive/index.d.ts.map +1 -0
  132. package/dist/tools/drive/index.js +25 -0
  133. package/dist/tools/drive/index.js.map +1 -0
  134. package/dist/tools/im/format-messages.d.ts +99 -0
  135. package/dist/tools/im/format-messages.d.ts.map +1 -0
  136. package/dist/tools/im/format-messages.js +277 -0
  137. package/dist/tools/im/format-messages.js.map +1 -0
  138. package/dist/tools/im/helpers.d.ts +53 -0
  139. package/dist/tools/im/helpers.d.ts.map +1 -0
  140. package/dist/tools/im/helpers.js +85 -0
  141. package/dist/tools/im/helpers.js.map +1 -0
  142. package/dist/tools/im/index.d.ts +25 -0
  143. package/dist/tools/im/index.d.ts.map +1 -0
  144. package/dist/tools/im/index.js +44 -0
  145. package/dist/tools/im/index.js.map +1 -0
  146. package/dist/tools/im/message-read.d.ts +19 -0
  147. package/dist/tools/im/message-read.d.ts.map +1 -0
  148. package/dist/tools/im/message-read.js +526 -0
  149. package/dist/tools/im/message-read.js.map +1 -0
  150. package/dist/tools/im/message.d.ts +22 -0
  151. package/dist/tools/im/message.d.ts.map +1 -0
  152. package/dist/tools/im/message.js +233 -0
  153. package/dist/tools/im/message.js.map +1 -0
  154. package/dist/tools/im/resource.d.ts +19 -0
  155. package/dist/tools/im/resource.d.ts.map +1 -0
  156. package/dist/tools/im/resource.js +185 -0
  157. package/dist/tools/im/resource.js.map +1 -0
  158. package/dist/tools/im/time-utils.d.ts +70 -0
  159. package/dist/tools/im/time-utils.d.ts.map +1 -0
  160. package/dist/tools/im/time-utils.js +277 -0
  161. package/dist/tools/im/time-utils.js.map +1 -0
  162. package/dist/tools/index.d.ts +85 -0
  163. package/dist/tools/index.d.ts.map +1 -0
  164. package/dist/tools/index.js +135 -0
  165. package/dist/tools/index.js.map +1 -0
  166. package/dist/tools/oauth.d.ts +15 -0
  167. package/dist/tools/oauth.d.ts.map +1 -0
  168. package/dist/tools/oauth.js +379 -0
  169. package/dist/tools/oauth.js.map +1 -0
  170. package/dist/tools/search/doc-search.d.ts +9 -0
  171. package/dist/tools/search/doc-search.d.ts.map +1 -0
  172. package/dist/tools/search/doc-search.js +219 -0
  173. package/dist/tools/search/doc-search.js.map +1 -0
  174. package/dist/tools/search/index.d.ts +11 -0
  175. package/dist/tools/search/index.d.ts.map +1 -0
  176. package/dist/tools/search/index.js +18 -0
  177. package/dist/tools/search/index.js.map +1 -0
  178. package/dist/tools/sheets/index.d.ts +11 -0
  179. package/dist/tools/sheets/index.d.ts.map +1 -0
  180. package/dist/tools/sheets/index.js +18 -0
  181. package/dist/tools/sheets/index.js.map +1 -0
  182. package/dist/tools/sheets/sheet.d.ts +11 -0
  183. package/dist/tools/sheets/sheet.d.ts.map +1 -0
  184. package/dist/tools/sheets/sheet.js +332 -0
  185. package/dist/tools/sheets/sheet.js.map +1 -0
  186. package/dist/tools/task/index.d.ts +12 -0
  187. package/dist/tools/task/index.d.ts.map +1 -0
  188. package/dist/tools/task/index.js +30 -0
  189. package/dist/tools/task/index.js.map +1 -0
  190. package/dist/tools/task/task.d.ts +13 -0
  191. package/dist/tools/task/task.d.ts.map +1 -0
  192. package/dist/tools/task/task.js +225 -0
  193. package/dist/tools/task/task.js.map +1 -0
  194. package/dist/tools/task/tasklist.d.ts +13 -0
  195. package/dist/tools/task/tasklist.d.ts.map +1 -0
  196. package/dist/tools/task/tasklist.js +206 -0
  197. package/dist/tools/task/tasklist.js.map +1 -0
  198. package/dist/tools/wiki/index.d.ts +11 -0
  199. package/dist/tools/wiki/index.d.ts.map +1 -0
  200. package/dist/tools/wiki/index.js +20 -0
  201. package/dist/tools/wiki/index.js.map +1 -0
  202. package/dist/tools/wiki/node.d.ts +11 -0
  203. package/dist/tools/wiki/node.d.ts.map +1 -0
  204. package/dist/tools/wiki/node.js +112 -0
  205. package/dist/tools/wiki/node.js.map +1 -0
  206. package/dist/tools/wiki/space.d.ts +11 -0
  207. package/dist/tools/wiki/space.d.ts.map +1 -0
  208. package/dist/tools/wiki/space.js +125 -0
  209. package/dist/tools/wiki/space.js.map +1 -0
  210. package/dist/utils/index.d.ts +8 -0
  211. package/dist/utils/index.d.ts.map +1 -0
  212. package/dist/utils/index.js +8 -0
  213. package/dist/utils/index.js.map +1 -0
  214. package/dist/utils/logger.d.ts +36 -0
  215. package/dist/utils/logger.d.ts.map +1 -0
  216. package/dist/utils/logger.js +101 -0
  217. package/dist/utils/logger.js.map +1 -0
  218. package/eslint.config.js +13 -0
  219. package/package.json +54 -0
  220. package/skills/feishu-bitable/SKILL.md +248 -0
  221. package/skills/feishu-bitable/references/examples.md +813 -0
  222. package/skills/feishu-bitable/references/field-properties.md +763 -0
  223. package/skills/feishu-bitable/references/record-values.md +911 -0
  224. package/skills/feishu-calendar/SKILL.md +244 -0
  225. package/skills/feishu-channel-rules/SKILL.md +18 -0
  226. package/skills/feishu-channel-rules/references/markdown-syntax.md +138 -0
  227. package/skills/feishu-create-doc/SKILL.md +719 -0
  228. package/skills/feishu-fetch-doc/SKILL.md +93 -0
  229. package/skills/feishu-im-read/SKILL.md +163 -0
  230. package/skills/feishu-task/SKILL.md +293 -0
  231. package/skills/feishu-troubleshoot/SKILL.md +70 -0
  232. package/skills/feishu-update-doc/SKILL.md +285 -0
  233. package/src/core/api-error.ts +342 -0
  234. package/src/core/auth-errors.ts +27 -0
  235. package/src/core/config.ts +134 -0
  236. package/src/core/device-flow.ts +314 -0
  237. package/src/core/index.ts +16 -0
  238. package/src/core/lark-client.ts +391 -0
  239. package/src/core/token-store.ts +249 -0
  240. package/src/core/types.ts +302 -0
  241. package/src/core/uat-client.ts +298 -0
  242. package/src/core/version.ts +53 -0
  243. package/src/index.ts +138 -0
  244. package/src/tools/bitable/app.ts +390 -0
  245. package/src/tools/bitable/field.ts +406 -0
  246. package/src/tools/bitable/index.ts +43 -0
  247. package/src/tools/bitable/record.ts +559 -0
  248. package/src/tools/bitable/table.ts +472 -0
  249. package/src/tools/calendar/calendar.ts +254 -0
  250. package/src/tools/calendar/event.ts +606 -0
  251. package/src/tools/calendar/index.ts +41 -0
  252. package/src/tools/chat/chat.ts +127 -0
  253. package/src/tools/chat/index.ts +24 -0
  254. package/src/tools/chat/members.ts +93 -0
  255. package/src/tools/common/get-user.ts +127 -0
  256. package/src/tools/common/index.ts +24 -0
  257. package/src/tools/common/search-user.ts +99 -0
  258. package/src/tools/doc/create.ts +184 -0
  259. package/src/tools/doc/fetch.ts +149 -0
  260. package/src/tools/doc/index.ts +38 -0
  261. package/src/tools/doc/shared.ts +228 -0
  262. package/src/tools/doc/update.ts +240 -0
  263. package/src/tools/drive/file.ts +265 -0
  264. package/src/tools/drive/index.ts +29 -0
  265. package/src/tools/im/format-messages.ts +391 -0
  266. package/src/tools/im/helpers.ts +109 -0
  267. package/src/tools/im/index.ts +49 -0
  268. package/src/tools/im/message-read.ts +676 -0
  269. package/src/tools/im/message.ts +303 -0
  270. package/src/tools/im/resource.ts +225 -0
  271. package/src/tools/im/time-utils.ts +347 -0
  272. package/src/tools/index.ts +205 -0
  273. package/src/tools/oauth.ts +460 -0
  274. package/src/tools/search/doc-search.ts +250 -0
  275. package/src/tools/search/index.ts +22 -0
  276. package/src/tools/sheets/index.ts +22 -0
  277. package/src/tools/sheets/sheet.ts +382 -0
  278. package/src/tools/task/index.ts +34 -0
  279. package/src/tools/task/task.ts +265 -0
  280. package/src/tools/task/tasklist.ts +262 -0
  281. package/src/tools/wiki/index.ts +24 -0
  282. package/src/tools/wiki/node.ts +131 -0
  283. package/src/tools/wiki/space.ts +152 -0
  284. package/src/utils/index.ts +8 -0
  285. package/src/utils/logger.ts +132 -0
  286. package/tests/core/config.test.ts +238 -0
  287. package/tests/core/device-flow.test.ts +490 -0
  288. package/tests/core/lark-client.test.ts +378 -0
  289. package/tests/core/token-store.test.ts +438 -0
  290. package/tests/index.test.ts +360 -0
  291. package/tests/tools/doc/create.test.ts +224 -0
  292. package/tests/tools/doc/fetch.test.ts +182 -0
  293. package/tests/tools/doc/shared.test.ts +183 -0
  294. package/tests/tools/doc/update.test.ts +330 -0
  295. package/tests/tools/im/format-messages.test.ts +184 -0
  296. package/tests/tools/im/time-utils.test.ts +178 -0
  297. package/tests/utils/logger.test.ts +140 -0
  298. package/tsconfig.json +20 -0
@@ -0,0 +1,47 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master, develop]
6
+ pull_request:
7
+ branches: [main, master]
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+
13
+ strategy:
14
+ matrix:
15
+ node-version: [22.x]
16
+
17
+ steps:
18
+ - name: Checkout code
19
+ uses: actions/checkout@v4
20
+
21
+ - name: Setup Node.js ${{ matrix.node-version }}
22
+ uses: actions/setup-node@v4
23
+ with:
24
+ node-version: ${{ matrix.node-version }}
25
+ cache: 'npm'
26
+
27
+ - name: Install dependencies
28
+ run: npm ci
29
+
30
+ - name: Run linter
31
+ run: npm run lint
32
+
33
+ - name: Check formatting
34
+ run: npm run format:check
35
+
36
+ - name: Build
37
+ run: npm run build
38
+
39
+ - name: Run tests
40
+ run: npm test
41
+
42
+ - name: Upload coverage
43
+ uses: codecov/codecov-action@v4
44
+ if: matrix.node-version == '22.x'
45
+ with:
46
+ files: ./coverage/lcov.info
47
+ fail_ci_if_error: false
@@ -0,0 +1,47 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ permissions:
9
+ contents: write
10
+ id-token: write
11
+
12
+ jobs:
13
+ release:
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ - name: Checkout
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Setup Node.js
21
+ uses: actions/setup-node@v4
22
+ with:
23
+ node-version: '22.x'
24
+ registry-url: 'https://registry.npmjs.org'
25
+
26
+ - name: Install dependencies
27
+ run: npm ci
28
+
29
+ - name: Build
30
+ run: npm run build
31
+
32
+ - name: Run tests
33
+ run: npm test
34
+
35
+ - name: Publish to npm
36
+ run: npm publish --provenance --access public
37
+ env:
38
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
39
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
40
+
41
+ - name: Create GitHub Release
42
+ uses: softprops/action-gh-release@v2
43
+ with:
44
+ generate_release_notes: true
45
+ files: |
46
+ dist/**/*.js
47
+ dist/**/*.d.ts
@@ -0,0 +1,127 @@
1
+ name: Sync Upstream
2
+
3
+ on:
4
+ schedule:
5
+ # Run daily at 00:00 UTC
6
+ - cron: '0 0 * * *'
7
+ workflow_dispatch:
8
+ # Allow manual trigger
9
+
10
+ jobs:
11
+ sync:
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ - name: Checkout
16
+ uses: actions/checkout@v4
17
+ with:
18
+ fetch-depth: 0
19
+ token: ${{ secrets.GITHUB_TOKEN }}
20
+
21
+ - name: Setup Git
22
+ run: |
23
+ git config user.name 'github-actions[bot]'
24
+ git config user.email 'github-actions[bot]@users.noreply.github.com'
25
+
26
+ - name: Add upstream remote
27
+ run: |
28
+ git remote add upstream https://github.com/larksuite/openclaw-lark || true
29
+ git fetch upstream
30
+
31
+ - name: Check for changes in core
32
+ id: check-core
33
+ run: |
34
+ # Core directories/files that we sync from upstream
35
+ SYNC_PATHS=(
36
+ "src/core/lark-client.ts"
37
+ "src/core/device-flow.ts"
38
+ "src/core/token-store.ts"
39
+ "src/core/uat-client.ts"
40
+ "src/core/api-error.ts"
41
+ "src/core/auth-errors.ts"
42
+ "src/tools/oapi/im"
43
+ "src/tools/oapi/bitable"
44
+ "src/tools/oapi/calendar"
45
+ "src/tools/oapi/task"
46
+ "src/tools/oapi/drive"
47
+ "src/tools/oapi/wiki"
48
+ "src/tools/oapi/sheets"
49
+ "src/tools/oapi/search"
50
+ "src/tools/oapi/chat"
51
+ "src/tools/oapi/common"
52
+ "src/tools/mcp/doc"
53
+ "src/tools/oauth.ts"
54
+ "skills"
55
+ )
56
+
57
+ CHANGES_FOUND=false
58
+ for path in "${SYNC_PATHS[@]}"; do
59
+ if git diff --quiet HEAD "upstream/main" -- "$path" 2>/dev/null; then
60
+ echo "No changes in $path"
61
+ else
62
+ echo "Changes detected in $path"
63
+ CHANGES_FOUND=true
64
+ fi
65
+ done
66
+
67
+ echo "has_changes=$CHANGES_FOUND" >> $GITHUB_OUTPUT
68
+
69
+ - name: Create sync branch
70
+ if: steps.check-core.outputs.has_changes == 'true'
71
+ run: |
72
+ SYNC_BRANCH="sync-upstream-$(date +%Y%m%d-%H%M%S)"
73
+ echo "SYNC_BRANCH=$SYNC_BRANCH" >> $GITHUB_ENV
74
+ git checkout -b "$SYNC_BRANCH"
75
+
76
+ - name: Sync files from upstream
77
+ if: steps.check-core.outputs.has_changes == 'true'
78
+ run: |
79
+ # Sync core files (adapted for MCP Server architecture)
80
+ # Note: These files may need manual adaptation after sync
81
+
82
+ # Sync skills directory
83
+ git checkout upstream/main -- skills/ || true
84
+
85
+ # Note: src/core and src/tools need careful review
86
+ # as they have been adapted for MCP Server architecture
87
+ # The following files are synced but may need conflict resolution:
88
+ # - src/core/lark-client.ts
89
+ # - src/core/device-flow.ts
90
+ # - src/core/token-store.ts
91
+ # - src/tools/oapi/*
92
+
93
+ git add -A || true
94
+ git commit -m "chore: sync upstream changes from openclaw-lark" || echo "No changes to commit"
95
+
96
+ - name: Create Pull Request
97
+ if: steps.check-core.outputs.has_changes == 'true'
98
+ uses: peter-evans/create-pull-request@v6
99
+ with:
100
+ branch: ${{ env.SYNC_BRANCH }}
101
+ title: 'chore: sync upstream openclaw-lark changes'
102
+ body: |
103
+ ## Upstream Sync
104
+
105
+ This PR syncs changes from [openclaw-lark](https://github.com/larksuite/openclaw-lark).
106
+
107
+ ### Changed Areas
108
+ - Skills documentation
109
+ - Core modules (may need manual review)
110
+ - Tools (may need manual review)
111
+
112
+ **Note:** Please review the changes carefully before merging.
113
+ Some files may need manual adaptation for MCP Server architecture.
114
+
115
+ ### Checklist
116
+ - [ ] Review all changes
117
+ - [ ] Run tests locally: `npm test`
118
+ - [ ] Check for API changes that need adaptation
119
+ labels: |
120
+ upstream-sync
121
+ automated
122
+ draft: false
123
+
124
+ - name: No changes detected
125
+ if: steps.check-core.outputs.has_changes != 'true'
126
+ run: |
127
+ echo "No upstream changes detected. All synced!"
@@ -0,0 +1,7 @@
1
+ {
2
+ "semi": true,
3
+ "trailingComma": "es5",
4
+ "singleQuote": true,
5
+ "printWidth": 100,
6
+ "tabWidth": 2
7
+ }
package/README.md ADDED
@@ -0,0 +1,214 @@
1
+ # cc-lark
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
+ [![Node.js Version](https://img.shields.io/badge/node-%3E%3D22-blue.svg)](https://nodejs.org/)
5
+
6
+ Feishu/Lark MCP Server for Claude Code. Based on [openclaw-lark](https://github.com/larksuite/openclaw-lark).
7
+
8
+ 基于 [openclaw-lark](https://github.com/larksuite/openclaw-lark) 的 Claude Code MCP Server,让 Claude Code 能够操作飞书/Lark。
9
+
10
+ ## 功能特性
11
+
12
+ - 🔐 **OAuth 授权**: 设备流授权,安全获取用户令牌
13
+ - 💬 **即时通讯**: 读取和发送群聊、单聊消息
14
+ - 📄 **文档操作**: 创建、读取、更新飞书文档
15
+ - 📊 **多维表格**: 表格、字段、记录的增删改查
16
+ - 📅 **日历**: 日历和事件管理
17
+ - ✅ **任务**: 任务和任务列表管理
18
+ - 📁 **云盘**: 文件操作
19
+ - 📚 **Wiki**: 知识库空间管理
20
+ - 📋 **表格**: 电子表格操作
21
+ - 🔍 **搜索**: 文档搜索
22
+
23
+ ## 安装
24
+
25
+ ```bash
26
+ npm install cc-lark
27
+ ```
28
+
29
+ ## 快速开始
30
+
31
+ ### 1. 创建飞书应用
32
+
33
+ 1. 访问 [飞书开放平台](https://open.feishu.cn/)
34
+ 2. 创建企业自建应用
35
+ 3. 获取 `App ID` 和 `App Secret`
36
+ 4. 配置所需权限(参考下方权限配置)
37
+
38
+ ### 2. 配置环境变量
39
+
40
+ ```bash
41
+ export FEISHU_APP_ID="cli_xxxxxxxxxxxx"
42
+ export FEISHU_APP_SECRET="xxxxxxxxxxxxxxxxxxxx"
43
+ ```
44
+
45
+ ### 3. 在 Claude Code 中使用
46
+
47
+ 添加到 Claude Code 配置 (`~/.config/claude-code/mcp.json`):
48
+
49
+ ```json
50
+ {
51
+ "mcpServers": {
52
+ "feishu": {
53
+ "command": "npx",
54
+ "args": ["cc-lark"]
55
+ }
56
+ }
57
+ }
58
+ ```
59
+
60
+ ### 4. 授权
61
+
62
+ 首次使用时,Claude Code 会提示你进行飞书授权。按照提示访问授权链接完成授权即可。
63
+
64
+ ## 可用工具
65
+
66
+ ### IM 消息
67
+
68
+ | 工具 | 描述 |
69
+ |------|------|
70
+ | `feishu_im_send_message` | 发送消息到会话 |
71
+ | `feishu_im_reply_message` | 回复消息 |
72
+ | `feishu_im_get_messages` | 获取会话消息 |
73
+ | `feishu_im_get_thread_messages` | 获取话题消息 |
74
+ | `feishu_im_search_messages` | 搜索消息 |
75
+ | `feishu_im_fetch_resource` | 获取消息资源(图片、文件等) |
76
+
77
+ ### 文档
78
+
79
+ | 工具 | 描述 |
80
+ |------|------|
81
+ | `feishu_create_doc` | 创建文档 |
82
+ | `feishu_fetch_doc` | 获取文档内容 |
83
+ | `feishu_update_doc` | 更新文档 |
84
+
85
+ ### 多维表格
86
+
87
+ | 工具 | 描述 |
88
+ |------|------|
89
+ | `feishu_bitable_app` | 多维表格应用操作 |
90
+ | `feishu_bitable_table` | 数据表操作 |
91
+ | `feishu_bitable_record` | 记录操作 |
92
+ | `feishu_bitable_field` | 字段操作 |
93
+
94
+ ### 日历
95
+
96
+ | 工具 | 描述 |
97
+ |------|------|
98
+ | `feishu_calendar` | 日历操作 |
99
+ | `feishu_calendar_event` | 日历事件操作 |
100
+
101
+ ### 任务
102
+
103
+ | 工具 | 描述 |
104
+ |------|------|
105
+ | `feishu_task` | 任务操作 |
106
+ | `feishu_tasklist` | 任务列表操作 |
107
+
108
+ ### 其他
109
+
110
+ | 工具 | 描述 |
111
+ |------|------|
112
+ | `feishu_drive_file` | 云盘文件操作 |
113
+ | `feishu_wiki_space` | 知识库空间操作 |
114
+ | `feishu_wiki_node_list` | 知识库节点列表 |
115
+ | `feishu_wiki_node_get` | 获取知识库节点 |
116
+ | `feishu_sheet` | 电子表格操作 |
117
+ | `feishu_doc_search` | 文档搜索 |
118
+ | `feishu_chat_search` | 会话搜索 |
119
+ | `feishu_chat_get` | 获取会话 |
120
+ | `feishu_chat_members` | 会话成员管理 |
121
+ | `feishu_get_user` | 获取用户信息 |
122
+ | `feishu_search_user` | 搜索用户 |
123
+ | `feishu_oauth` | OAuth 授权管理 |
124
+
125
+ ## Skills 使用指南
126
+
127
+ cc-lark 包含以下 Skills 文档,帮助 Claude Code 更好地使用工具:
128
+
129
+ | Skill | 描述 |
130
+ |-------|------|
131
+ | `feishu-im-read` | IM 消息读取指南 |
132
+ | `feishu-create-doc` | 文档创建指南 |
133
+ | `feishu-fetch-doc` | 文档获取指南 |
134
+ | `feishu-update-doc` | 文档更新指南 |
135
+ | `feishu-bitable` | 多维表格操作指南 |
136
+ | `feishu-calendar` | 日历操作指南 |
137
+ | `feishu-task` | 任务操作指南 |
138
+ | `feishu-channel-rules` | 频道规则配置 |
139
+ | `feishu-troubleshoot` | 故障排查指南 |
140
+
141
+ ## 权限配置
142
+
143
+ 在飞书开放平台配置以下权限(根据需要选择):
144
+
145
+ ### IM 消息权限
146
+ - `im:message` - 获取与发送消息
147
+ - `im:message:readonly` - 获取消息(只读)
148
+ - `im:chat` - 获取群组信息
149
+ - `im:chat:readonly` - 获取群组信息(只读)
150
+
151
+ ### 文档权限
152
+ - `docs:doc` - 文档操作
153
+ - `docs:doc:readonly` - 文档读取(只读)
154
+ - `drive:drive` - 云盘操作
155
+ - `drive:drive:readonly` - 云盘读取(只读)
156
+
157
+ ### 多维表格权限
158
+ - `bitable:app` - 多维表格操作
159
+ - `bitable:app:readonly` - 多维表格读取(只读)
160
+
161
+ ### 日历权限
162
+ - `calendar:calendar` - 日历操作
163
+ - `calendar:calendar:readonly` - 日历读取(只读)
164
+
165
+ ### 任务权限
166
+ - `task:task` - 任务操作
167
+ - `task:task:readonly` - 任务读取(只读)
168
+
169
+ ## 开发
170
+
171
+ ### 构建项目
172
+
173
+ ```bash
174
+ npm run build
175
+ ```
176
+
177
+ ### 运行测试
178
+
179
+ ```bash
180
+ npm test
181
+ ```
182
+
183
+ ### 开发模式
184
+
185
+ ```bash
186
+ npm run dev
187
+ ```
188
+
189
+ ## 上游同步
190
+
191
+ 本项目自动同步 [openclaw-lark](https://github.com/larksuite/openclaw-lark) 的更新。
192
+
193
+ - 每日自动检测上游更新
194
+ - 有更新时自动创建 PR
195
+ - 请在合并前仔细审查变更
196
+
197
+ ## 与 openclaw-lark 的差异
198
+
199
+ | 方面 | openclaw-lark | cc-lark |
200
+ |------|---------------|---------|
201
+ | 运行环境 | OpenClaw 平台 | 独立 MCP Server |
202
+ | 入口 | OpenClawPluginApi | MCP Server |
203
+ | 频道功能 | 完整频道插件 | 仅工具调用 |
204
+ | 消息接收 | WebSocket/Webhook | 无(仅主动调用) |
205
+ | 工具命名 | feishu_* | feishu_*(保持一致) |
206
+ | Skills | 完整 | 复用上游 |
207
+
208
+ ## 许可证
209
+
210
+ MIT
211
+
212
+ ## 致谢
213
+
214
+ 本项目基于 [openclaw-lark](https://github.com/larksuite/openclaw-lark) 开发,感谢飞书团队的开源贡献。
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Shared Lark API error handling utilities.
6
+ *
7
+ * Provides unified error handling for two distinct error paths:
8
+ *
9
+ * 1. **Response-level errors** — The SDK returns a response object with a
10
+ * non-zero `code`. Handled by {@link assertLarkOk}.
11
+ *
12
+ * 2. **Thrown exceptions** — The SDK throws an Axios-style error (HTTP 4xx)
13
+ * whose properties include the Feishu error `code` and `msg`.
14
+ * Handled by {@link formatLarkError}.
15
+ *
16
+ * Adapted from openclaw-lark for MCP Server architecture.
17
+ */
18
+ /**
19
+ * Well-known Lark API error codes.
20
+ * @see https://open.feishu.cn/document/ukTMukTMukTM/ugTM5UjL4ETO14COxkTN/code
21
+ */
22
+ export declare const LARK_ERROR: {
23
+ /** Success */
24
+ readonly SUCCESS: 0;
25
+ /** Permission denied - app scope missing (tenant level) */
26
+ readonly APP_SCOPE_MISSING: 99991672;
27
+ /** User token scope insufficient */
28
+ readonly USER_SCOPE_INSUFFICIENT: 99991679;
29
+ /** Invalid access token */
30
+ readonly INVALID_ACCESS_TOKEN: 99991663;
31
+ /** Access token expired */
32
+ readonly ACCESS_TOKEN_EXPIRED: 99991664;
33
+ /** access_token invalid */
34
+ readonly TOKEN_INVALID: 99991668;
35
+ /** access_token expired */
36
+ readonly TOKEN_EXPIRED: 99991669;
37
+ /** refresh_token invalid */
38
+ readonly REFRESH_TOKEN_INVALID: 20003;
39
+ /** refresh_token expired */
40
+ readonly REFRESH_TOKEN_EXPIRED: 20004;
41
+ /** refresh_token missing */
42
+ readonly REFRESH_TOKEN_MISSING: 20024;
43
+ /** refresh_token revoked */
44
+ readonly REFRESH_TOKEN_REVOKED: 20063;
45
+ /** Message recalled */
46
+ readonly MESSAGE_RECALLED: 230011;
47
+ /** Message deleted */
48
+ readonly MESSAGE_DELETED: 231003;
49
+ };
50
+ /**
51
+ * Extract the Lark API code from a thrown error object.
52
+ *
53
+ * Supports three common structures:
54
+ * - `{ code }` — SDK direct mount
55
+ * - `{ data: { code } }` — Response body nested
56
+ * - `{ response: { data: { code } } }` — Axios style
57
+ */
58
+ export declare function extractLarkApiCode(err: unknown): number | undefined;
59
+ /**
60
+ * Assert that a Lark SDK response is successful (code === 0).
61
+ *
62
+ * @param res - Lark SDK response object
63
+ * @throws Error with the message from the response if code is non-zero
64
+ */
65
+ export declare function assertLarkOk(res: {
66
+ code?: number;
67
+ msg?: string;
68
+ }): void;
69
+ /**
70
+ * Extract a meaningful error message from a thrown Lark SDK / Axios error.
71
+ *
72
+ * The Lark SDK throws Axios errors whose object carries Feishu-specific
73
+ * fields (`code`, `msg`) alongside the standard `message`. For all errors
74
+ * we try `err.msg` first (the Feishu detail) and fall back to `err.message`
75
+ * (the generic Axios text).
76
+ */
77
+ export declare function formatLarkError(err: unknown): string;
78
+ /**
79
+ * Check if an error indicates missing app scope/permission.
80
+ */
81
+ export declare function isPermissionError(err: unknown): boolean;
82
+ /**
83
+ * Check if an error indicates an invalid or expired access token.
84
+ */
85
+ export declare function isTokenError(err: unknown): boolean;
86
+ /** Irrecoverable refresh_token error codes - require re-authorization */
87
+ export declare const REFRESH_TOKEN_IRRECOVERABLE: ReadonlySet<number>;
88
+ /** Message terminal error codes (recalled/deleted) - stop further operations */
89
+ export declare const MESSAGE_TERMINAL_CODES: ReadonlySet<number>;
90
+ /** access_token failure error codes - can retry with refresh */
91
+ export declare const TOKEN_RETRY_CODES: ReadonlySet<number>;
92
+ /** Scope error information */
93
+ export interface ScopeErrorInfo {
94
+ apiName: string;
95
+ scopes: string[];
96
+ /** Whether app scope has been verified */
97
+ appScopeVerified?: boolean;
98
+ /** Application ID for generating permission management links */
99
+ appId?: string;
100
+ }
101
+ /** OAuth authorization hint for client */
102
+ export interface AuthHint {
103
+ error: string;
104
+ api: string;
105
+ required_scope: string;
106
+ user_open_id: string;
107
+ message: string;
108
+ next_tool_call: {
109
+ tool: 'feishu_oauth';
110
+ params: {
111
+ action: 'authorize';
112
+ scope: string;
113
+ };
114
+ };
115
+ }
116
+ /** tryInvoke return type - discriminated union */
117
+ export type TryInvokeResult<T> = {
118
+ ok: true;
119
+ data: T;
120
+ } | {
121
+ ok: false;
122
+ error: string;
123
+ authHint: AuthHint;
124
+ } | {
125
+ ok: false;
126
+ error: string;
127
+ authHint?: undefined;
128
+ };
129
+ /**
130
+ * Thrown when no valid UAT exists and the user needs to (re-)authorize.
131
+ * Callers should catch this and trigger the OAuth flow.
132
+ */
133
+ export declare class NeedAuthorizationError extends Error {
134
+ readonly userOpenId: string;
135
+ constructor(userOpenId: string);
136
+ }
137
+ /**
138
+ * Thrown when the app lacks the application:application:self_manage permission.
139
+ *
140
+ * The administrator needs to enable this permission in the Lark Developer Console.
141
+ */
142
+ export declare class AppScopeCheckFailedError extends Error {
143
+ readonly appId?: string;
144
+ constructor(appId?: string);
145
+ }
146
+ /**
147
+ * Thrown when the app is missing required OAPI scopes.
148
+ *
149
+ * The administrator needs to enable permissions in the Lark Developer Console.
150
+ */
151
+ export declare class AppScopeMissingError extends Error {
152
+ readonly apiName: string;
153
+ /** Missing scopes that the app doesn't have */
154
+ readonly missingScopes: string[];
155
+ /** All required scopes (including enabled ones), for requesting user authorization after app permission setup */
156
+ readonly allRequiredScopes?: string[];
157
+ /** Application ID for generating permission management links */
158
+ readonly appId?: string;
159
+ readonly scopeNeedType?: 'one' | 'all';
160
+ /** Token type used when this error was triggered */
161
+ readonly tokenType?: 'user' | 'tenant';
162
+ constructor(info: ScopeErrorInfo, scopeNeedType?: 'one' | 'all', tokenType?: 'user' | 'tenant', allRequiredScopes?: string[]);
163
+ }
164
+ /**
165
+ * Thrown when user has not authorized or scope is insufficient.
166
+ *
167
+ * `requiredScopes` contains valid scopes from APP∩OAPI intersection,
168
+ * can be passed directly to OAuth authorize.
169
+ */
170
+ export declare class UserAuthRequiredError extends Error {
171
+ readonly userOpenId: string;
172
+ readonly apiName: string;
173
+ /** APP∩OAPI intersection scopes, pass to OAuth authorize */
174
+ readonly requiredScopes: string[];
175
+ /** Whether app scope was verified. false means requiredScopes may be inaccurate. */
176
+ readonly appScopeVerified: boolean;
177
+ /** Application ID for generating permission management links */
178
+ readonly appId?: string;
179
+ constructor(userOpenId: string, info: ScopeErrorInfo);
180
+ }
181
+ /**
182
+ * Thrown when server returns 99991679 - user token scope insufficient.
183
+ *
184
+ * Requires incremental authorization: start a new Device Flow with missing scopes.
185
+ */
186
+ export declare class UserScopeInsufficientError extends Error {
187
+ readonly userOpenId: string;
188
+ readonly apiName: string;
189
+ /** Missing scope list */
190
+ readonly missingScopes: string[];
191
+ constructor(userOpenId: string, info: ScopeErrorInfo);
192
+ }
193
+ //# sourceMappingURL=api-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-error.d.ts","sourceRoot":"","sources":["../../src/core/api-error.ts"],"names":[],"mappings":"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"}