feishu-user-plugin 1.3.8 → 1.3.10
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/.claude-plugin/plugin.json +12 -2
- package/CHANGELOG.md +100 -12
- package/README.en.md +610 -0
- package/README.md +292 -532
- package/package.json +12 -5
- package/proto/lark.proto +10 -0
- package/scripts/explore-card-protobuf.js +144 -0
- package/scripts/explore-image-minimize.js +163 -0
- package/scripts/generate-og-image.js +39 -0
- package/scripts/generate-release-artifacts.js +318 -0
- package/scripts/probe-feishu-docx.js +203 -0
- package/scripts/sync-team-skills.sh +109 -7
- package/skills/feishu-user-plugin/SKILL.md +76 -4
- package/skills/feishu-user-plugin/references/CLAUDE.md +74 -54
- package/src/auth/credentials.js +36 -0
- package/src/cli.js +86 -45
- package/src/clients/user.js +15 -13
- package/src/events/cursor.js +103 -0
- package/src/events/event-buffer.js +8 -5
- package/src/events/event-log.js +151 -0
- package/src/events/index.js +8 -1
- package/src/events/lockfile.js +126 -0
- package/src/events/owner.js +73 -0
- package/src/events/ws-server.js +95 -25
- package/src/oauth.js +48 -7
- package/src/resolver.js +10 -0
- package/src/server.js +248 -29
- package/src/setup.js +99 -25
- package/src/test-all.js +12 -9
- package/src/test-events-cursor.js +56 -0
- package/src/test-events-lockfile.js +36 -0
- package/src/test-events-log.js +67 -0
- package/src/test-events-owner.js +64 -0
- package/src/test-fixtures/doc-blocks/sample-1.json +1256 -0
- package/src/test-read-doc-markdown.js +61 -0
- package/src/test-switch-profile.js +171 -0
- package/src/tools/diagnostics.js +10 -3
- package/src/tools/docs.js +93 -3
- package/src/tools/events.js +143 -33
- package/src/tools/messaging-bot.js +2 -3
- package/src/tools/messaging-user.js +23 -14
- package/src/tools/profile.js +12 -7
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
// src/tools/messaging-user.js — User-identity (cookie-based) messaging plus
|
|
2
|
-
// batch_send fan-out
|
|
2
|
+
// batch_send fan-out. send_card_as_user lives here (historical naming) but
|
|
3
|
+
// always routes through bot — user-identity card sending is server-side
|
|
4
|
+
// disabled in Feishu at the cookie auth tier.
|
|
3
5
|
//
|
|
4
|
-
// All send_*_as_user handlers route through ctx.getUserClient() (cookie identity)
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
6
|
+
// All send_*_as_user handlers route through ctx.getUserClient() (cookie identity)
|
|
7
|
+
// EXCEPT send_card_as_user which delegates to bot via ctx.getOfficialClient().
|
|
8
|
+
// The "as_user" suffix on the card tool is historical — v1.3.9 confirmed the
|
|
9
|
+
// cookie protobuf path for CARD is server-side disabled, brute-force exhausted.
|
|
8
10
|
|
|
9
11
|
const { text, sendResult, json } = require('./_registry');
|
|
10
12
|
|
|
@@ -115,12 +117,17 @@ const schemas = [
|
|
|
115
117
|
},
|
|
116
118
|
{
|
|
117
119
|
name: 'send_image_as_user',
|
|
118
|
-
description: '[User Identity] Send an image as the logged-in user. Requires image_key (
|
|
120
|
+
description: '[User Identity, v1.3.9] Send an image as the logged-in user (NOT bot). Requires image_key from a prior upload_image call. Cookie-protobuf wire format requires both imageKey + thumbnailKey — when no separate thumbnail is provided, plugin defaults thumbnailKey to imageKey (Feishu accepts this for messenger-uploaded images). Width/height/mime/size are optional metadata; Feishu auto-derives display sizing on its side.',
|
|
119
121
|
inputSchema: {
|
|
120
122
|
type: 'object',
|
|
121
123
|
properties: {
|
|
122
124
|
chat_id: { type: 'string', description: 'Target chat ID. Numeric preferred; oc_xxx is auto-resolved (v1.3.7 C1.4).' },
|
|
123
125
|
image_key: { type: 'string', description: 'Image key from upload (img_v2_xxx or img_v3_xxx)' },
|
|
126
|
+
thumbnail_key: { type: 'string', description: 'Optional separate thumbnail image key. Defaults to image_key when omitted.' },
|
|
127
|
+
width: { type: 'number', description: 'Optional image width in pixels.' },
|
|
128
|
+
height: { type: 'number', description: 'Optional image height in pixels.' },
|
|
129
|
+
mime: { type: 'string', description: 'Optional MIME type (e.g. "image/png").' },
|
|
130
|
+
size: { type: 'number', description: 'Optional file size in bytes.' },
|
|
124
131
|
root_id: { type: 'string', description: 'Thread root message ID (optional)' },
|
|
125
132
|
},
|
|
126
133
|
required: ['chat_id', 'image_key'],
|
|
@@ -160,13 +167,12 @@ const schemas = [
|
|
|
160
167
|
},
|
|
161
168
|
{
|
|
162
169
|
name: 'send_card_as_user',
|
|
163
|
-
description: '[v1.3.
|
|
170
|
+
description: '[v1.3.9+: bot-only] Send an interactive Feishu card to a chat via bot identity (Official API). User-identity cookie protobuf path is server-side disabled at the auth tier — confirmed by exhaustive brute-force in v1.3.9, see scripts/explore-card-protobuf.js. The "as_user" suffix is historical naming kept for backward compat; the tool always routes through bot. Pass `card` as a JSON object (Feishu card schema, see https://open.feishu.cn/cardkit).',
|
|
164
171
|
inputSchema: {
|
|
165
172
|
type: 'object',
|
|
166
173
|
properties: {
|
|
167
174
|
chat_id: { type: 'string', description: 'Target chat_id (oc_xxx) or open_id' },
|
|
168
175
|
card: { description: 'Feishu card JSON. See https://open.feishu.cn/cardkit for the schema; build cards visually then paste the resulting JSON here.' },
|
|
169
|
-
via: { type: 'string', enum: ['bot', 'user'], description: 'Identity to send as. Default "bot". "user" returns an explicit not-yet-implemented error in v1.3.6.' },
|
|
170
176
|
},
|
|
171
177
|
required: ['chat_id', 'card'],
|
|
172
178
|
},
|
|
@@ -264,7 +270,14 @@ const handlers = {
|
|
|
264
270
|
async send_image_as_user(args, ctx) {
|
|
265
271
|
const c = await ctx.getUserClient();
|
|
266
272
|
const chatId = await _resolveCookieChatId(args.chat_id, ctx);
|
|
267
|
-
const r = await c.sendImage(chatId, args.image_key, {
|
|
273
|
+
const r = await c.sendImage(chatId, args.image_key, {
|
|
274
|
+
rootId: args.root_id,
|
|
275
|
+
thumbnailKey: args.thumbnail_key,
|
|
276
|
+
width: args.width,
|
|
277
|
+
height: args.height,
|
|
278
|
+
mime: args.mime,
|
|
279
|
+
size: args.size,
|
|
280
|
+
});
|
|
268
281
|
return sendResult(r, `Image sent to ${args.chat_id}`);
|
|
269
282
|
},
|
|
270
283
|
async send_file_as_user(args, ctx) {
|
|
@@ -280,12 +293,8 @@ const handlers = {
|
|
|
280
293
|
return sendResult(r, `Post sent to ${args.chat_id}`);
|
|
281
294
|
},
|
|
282
295
|
async send_card_as_user(args, ctx) {
|
|
283
|
-
const via = args.via || 'bot';
|
|
284
|
-
if (via === 'user') {
|
|
285
|
-
return text('send_card_as_user via="user" is not implemented in v1.3.6 — user-identity card sending requires reverse-engineering the Feishu web protobuf and is scheduled for v1.3.7. Use via="bot" (default) for now.');
|
|
286
|
-
}
|
|
287
296
|
const r = await ctx.getOfficialClient().sendMessageAsBot(args.chat_id, 'interactive', args.card);
|
|
288
|
-
return text(`Card sent (
|
|
297
|
+
return text(`Card sent (bot): ${r.messageId}`);
|
|
289
298
|
},
|
|
290
299
|
};
|
|
291
300
|
|
package/src/tools/profile.js
CHANGED
|
@@ -1,24 +1,29 @@
|
|
|
1
|
-
// src/tools/profile.js — multi-account profile management
|
|
1
|
+
// src/tools/profile.js — multi-account profile management.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
3
|
+
// v1.3.9 SSOT: profiles live in ~/.feishu-user-plugin/credentials.json under
|
|
4
|
+
// `profiles[]`. Switching writes `active` field; cross-process MCP picks it up
|
|
5
|
+
// via dispatcher mtime hook (~10μs/call) within ms.
|
|
6
|
+
//
|
|
7
|
+
// Legacy LARK_PROFILES_JSON env still works as a back-compat fallback when
|
|
8
|
+
// credentials.json doesn't exist. New profiles should be added via
|
|
9
|
+
// `npx feishu-user-plugin setup --profile <name> --app-id ... --app-secret ... --cookie ...`,
|
|
10
|
+
// then optionally `npx feishu-user-plugin oauth --profile <name>` for UAT.
|
|
6
11
|
|
|
7
12
|
const { text, json } = require('./_registry');
|
|
8
13
|
|
|
9
14
|
const schemas = [
|
|
10
15
|
{
|
|
11
16
|
name: 'list_profiles',
|
|
12
|
-
description: '[Plugin] List all available identity profiles (
|
|
17
|
+
description: '[Plugin] List all available identity profiles (each profile has its own LARK_COOKIE / APP_ID / APP_SECRET / UAT). v1.3.9 SSOT: profiles live in ~/.feishu-user-plugin/credentials.json::profiles. Legacy fallback: LARK_PROFILES_JSON env var. Marks the currently active profile.',
|
|
13
18
|
inputSchema: { type: 'object', properties: {} },
|
|
14
19
|
},
|
|
15
20
|
{
|
|
16
21
|
name: 'switch_profile',
|
|
17
|
-
description: '[Plugin] Switch the active identity profile.
|
|
22
|
+
description: '[Plugin v1.3.9] Switch the active identity profile. Atomically writes credentials.json::active; cached clients in this process are invalidated; cross-process MCPs (Codex / another Claude Code) auto-sync via dispatcher mtime check on next tool call (~10μs). To add a new profile, run `npx feishu-user-plugin setup --profile <name> --app-id ... --app-secret ... --cookie ...` then `npx feishu-user-plugin oauth --profile <name>` for UAT.',
|
|
18
23
|
inputSchema: {
|
|
19
24
|
type: 'object',
|
|
20
25
|
properties: {
|
|
21
|
-
name: { type: 'string', description: 'Profile name. "default" for
|
|
26
|
+
name: { type: 'string', description: 'Profile name. Use "default" for the primary profile; other names come from credentials.json or LARK_PROFILES_JSON.' },
|
|
22
27
|
},
|
|
23
28
|
required: ['name'],
|
|
24
29
|
},
|