feishu-user-plugin 1.3.6 → 1.3.7

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 (55) hide show
  1. package/.claude-plugin/plugin.json +2 -2
  2. package/CHANGELOG.md +22 -0
  3. package/README.md +55 -40
  4. package/package.json +10 -3
  5. package/scripts/check-tool-count.js +15 -0
  6. package/scripts/check-version.js +40 -0
  7. package/scripts/smoke.js +224 -0
  8. package/scripts/sync-claude-md.sh +12 -0
  9. package/scripts/sync-team-skills.sh +22 -0
  10. package/scripts/test-all-tools.js +158 -0
  11. package/skills/feishu-user-plugin/SKILL.md +5 -5
  12. package/skills/feishu-user-plugin/references/CLAUDE.md +138 -99
  13. package/skills/feishu-user-plugin/references/table.md +18 -9
  14. package/src/auth/credentials.js +350 -0
  15. package/src/cli.js +42 -13
  16. package/src/clients/official/base.js +424 -0
  17. package/src/clients/official/bitable.js +269 -0
  18. package/src/clients/official/calendar.js +176 -0
  19. package/src/clients/official/contacts.js +54 -0
  20. package/src/clients/official/docs.js +301 -0
  21. package/src/clients/official/drive.js +77 -0
  22. package/src/clients/official/groups.js +68 -0
  23. package/src/clients/official/im.js +414 -0
  24. package/src/clients/official/index.js +30 -0
  25. package/src/clients/official/okr.js +127 -0
  26. package/src/clients/official/tasks.js +142 -0
  27. package/src/clients/official/uploads.js +260 -0
  28. package/src/clients/official/wiki.js +207 -0
  29. package/src/{client.js → clients/user.js} +23 -17
  30. package/src/index.js +4 -1977
  31. package/src/logger.js +20 -0
  32. package/src/oauth.js +5 -1
  33. package/src/official.js +5 -1944
  34. package/src/prompts/_registry.js +69 -0
  35. package/src/prompts/index.js +54 -0
  36. package/src/server.js +242 -0
  37. package/src/test-all.js +2 -2
  38. package/src/test-comprehensive.js +3 -3
  39. package/src/test-send.js +1 -1
  40. package/src/tools/_registry.js +30 -0
  41. package/src/tools/bitable.js +246 -0
  42. package/src/tools/calendar.js +207 -0
  43. package/src/tools/contacts.js +66 -0
  44. package/src/tools/diagnostics.js +172 -0
  45. package/src/tools/docs.js +158 -0
  46. package/src/tools/drive.js +111 -0
  47. package/src/tools/groups.js +81 -0
  48. package/src/tools/im-read.js +259 -0
  49. package/src/tools/messaging-bot.js +151 -0
  50. package/src/tools/messaging-user.js +292 -0
  51. package/src/tools/okr.js +159 -0
  52. package/src/tools/profile.js +43 -0
  53. package/src/tools/tasks.js +168 -0
  54. package/src/tools/uploads.js +63 -0
  55. package/src/tools/wiki.js +191 -0
@@ -1,6 +1,6 @@
1
1
  const path = require('path');
2
2
  const protobuf = require('protobufjs');
3
- const { generateRequestId, generateCid, parseCookie, formatCookie, fetchWithTimeout } = require('./utils');
3
+ const { generateRequestId, generateCid, parseCookie, formatCookie, fetchWithTimeout } = require('../utils');
4
4
 
5
5
  const GATEWAY_URL = 'https://internal-api-lark-api.feishu.cn/im/gateway/';
6
6
  const CSRF_URL = 'https://internal-api-lark-api.feishu.cn/accounts/csrf';
@@ -34,7 +34,10 @@ class LarkUserClient {
34
34
  }
35
35
 
36
36
  async init() {
37
- this.proto = await protobuf.load(path.join(__dirname, '..', 'proto', 'lark.proto'));
37
+ // Path: clients/user.js ../../proto/lark.proto. Phase A refactor moved
38
+ // the file from src/client.js to src/clients/user.js but didn't deepen the
39
+ // relative path, so cookie init would ENOENT. Fixed here as part of B2.
40
+ this.proto = await protobuf.load(path.join(__dirname, '..', '..', 'proto', 'lark.proto'));
38
41
  await this._getCsrfToken();
39
42
  await this._getUserInfo();
40
43
  if (!this.userId) {
@@ -90,8 +93,10 @@ class LarkUserClient {
90
93
  this._heartbeatTimer = setInterval(async () => {
91
94
  try {
92
95
  await this._getCsrfToken();
93
- // Lazy require to avoid circular dependency at module load time
94
- const { persistToConfig } = require('./config');
96
+ // Lazy require to avoid circular dependency at module load time.
97
+ // auth/credentials writes to credentials.json (single source of truth)
98
+ // when it exists; falls back to legacy mcpServers persistence otherwise.
99
+ const { persistToConfig } = require('../auth/credentials');
95
100
  persistToConfig({ LARK_COOKIE: this.cookieStr });
96
101
  console.error('[feishu-user-plugin] Cookie heartbeat: session refreshed and persisted');
97
102
  } catch (e) {
@@ -195,7 +200,20 @@ class LarkUserClient {
195
200
  if (rootId) req.rootId = rootId;
196
201
  if (parentId) req.parentId = parentId;
197
202
  const { packet, ok } = await this._gateway(5, 'PutMessageRequest', req, '5.7.0');
198
- return { success: ok && (packet.status === 0 || packet.status == null), status: packet.status };
203
+ if (!ok) {
204
+ // The cookie protobuf gateway returns HTTP 400 when our wire format is
205
+ // missing required fields. Verified for IMAGE (v1.3.7 testing): the
206
+ // simple {imageKey} content payload is rejected — Feishu Web encodes
207
+ // images with extra metadata (image dimensions, mime type, etc.) that
208
+ // we don't have in proto/lark.proto. Reverse-engineering requires Chrome
209
+ // DevTools capture and is deferred to v1.3.8. Surface a clear error
210
+ // routing the user to send_message_as_bot, which works.
211
+ if (type === MsgType.IMAGE) {
212
+ throw new Error('send_image_as_user: Feishu cookie protobuf gateway rejected the IMAGE wire format (HTTP 400). User-identity image sends are not yet supported — wire format reverse-engineering is deferred to v1.3.8. Workaround: use send_message_as_bot(chat_id, msg_type="image", payload={image_key:"..."}).');
213
+ }
214
+ throw new Error(`_sendMsg: cookie protobuf gateway returned non-2xx for type=${type}. The wire format likely doesn't match what Feishu expects.`);
215
+ }
216
+ return { success: true, status: packet.status };
199
217
  }
200
218
 
201
219
  // --- Send Text Message ---
@@ -275,18 +293,6 @@ class LarkUserClient {
275
293
  return this._sendMsg(MsgType.FILE, chatId, { fileKey, fileName }, opts);
276
294
  }
277
295
 
278
- // --- Send Audio ---
279
-
280
- async sendAudio(chatId, audioKey, opts = {}) {
281
- return this._sendMsg(MsgType.AUDIO, chatId, { audioKey }, opts);
282
- }
283
-
284
- // --- Send Sticker ---
285
-
286
- async sendSticker(chatId, stickerId, stickerSetId, opts = {}) {
287
- return this._sendMsg(MsgType.STICKER, chatId, { stickerId, stickerSetId }, opts);
288
- }
289
-
290
296
  // --- Send Rich Text / POST ---
291
297
 
292
298
  async sendPost(chatId, title, paragraphs, opts = {}) {