@teamclaw/feishu-agent 1.0.3 → 1.0.5
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/README.md +5 -2
- package/dist/cli.js +38 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,9 +5,10 @@ Feishu Agent is a TypeScript/Node.js middleware layer for Feishu (Lark) API inte
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- 📅 Calendar management (list calendars, events, create/delete events)
|
|
8
|
+
- ⚠️ **Automatic conflict detection** when creating events (uses FreeBusy API)
|
|
8
9
|
- ✅ Todo management via Bitable
|
|
9
10
|
- 👥 Contact management (list users, search by name/email)
|
|
10
|
-
- 🔐 OAuth 2.0 authentication
|
|
11
|
+
- 🔐 OAuth 2.0 authentication with auto token refresh
|
|
11
12
|
- 🚀 CLI interface with commander
|
|
12
13
|
|
|
13
14
|
## Installation
|
|
@@ -71,7 +72,7 @@ feishu_agent calendar list
|
|
|
71
72
|
# List events
|
|
72
73
|
feishu_agent calendar events
|
|
73
74
|
|
|
74
|
-
# Create event
|
|
75
|
+
# Create event (automatically checks for time conflicts)
|
|
75
76
|
feishu_agent calendar create --summary "Meeting" --start "2026-03-01 14:00" --end "2026-03-01 15:00"
|
|
76
77
|
|
|
77
78
|
# Create event with attendees
|
|
@@ -173,6 +174,8 @@ Global config is stored at `~/.feishu-agent/config.json`:
|
|
|
173
174
|
}
|
|
174
175
|
```
|
|
175
176
|
|
|
177
|
+
**Note:** User access tokens are automatically refreshed when expired. Just run `feishu_agent auth` again if the refresh token expires.
|
|
178
|
+
|
|
176
179
|
## License
|
|
177
180
|
|
|
178
181
|
MIT
|
package/dist/cli.js
CHANGED
|
@@ -2131,7 +2131,7 @@ var {
|
|
|
2131
2131
|
// src/cli/commands/setup.ts
|
|
2132
2132
|
import { createServer } from "node:http";
|
|
2133
2133
|
import { exec } from "node:child_process";
|
|
2134
|
-
import { writeFile
|
|
2134
|
+
import { writeFile } from "node:fs/promises";
|
|
2135
2135
|
|
|
2136
2136
|
// src/core/config.ts
|
|
2137
2137
|
import { homedir } from "node:os";
|
|
@@ -2231,11 +2231,11 @@ class AuthManager {
|
|
|
2231
2231
|
userToken = null;
|
|
2232
2232
|
constructor(config) {
|
|
2233
2233
|
this.config = config;
|
|
2234
|
-
if (config.userAccessToken) {
|
|
2234
|
+
if (config.userAccessToken && config.refreshToken) {
|
|
2235
2235
|
this.userToken = {
|
|
2236
2236
|
accessToken: config.userAccessToken,
|
|
2237
|
-
refreshToken: config.refreshToken
|
|
2238
|
-
expireTime:
|
|
2237
|
+
refreshToken: config.refreshToken,
|
|
2238
|
+
expireTime: 0
|
|
2239
2239
|
};
|
|
2240
2240
|
}
|
|
2241
2241
|
}
|
|
@@ -2317,7 +2317,7 @@ class AuthManager {
|
|
|
2317
2317
|
clearTimeout(timeoutId);
|
|
2318
2318
|
}
|
|
2319
2319
|
}
|
|
2320
|
-
async
|
|
2320
|
+
async refreshUserToken() {
|
|
2321
2321
|
if (!this.userToken?.refreshToken) {
|
|
2322
2322
|
throw new FeishuError("Refresh token not available", 401);
|
|
2323
2323
|
}
|
|
@@ -2636,15 +2636,11 @@ async function setupCommand() {
|
|
|
2636
2636
|
console.log(` User ID: ${user_id}`);
|
|
2637
2637
|
console.log(` Name: ${name}`);
|
|
2638
2638
|
console.log("");
|
|
2639
|
-
await
|
|
2640
|
-
await writeFile(".feishu_agent/config.json", JSON.stringify({
|
|
2641
|
-
appId,
|
|
2642
|
-
appSecret,
|
|
2639
|
+
await saveGlobalConfig({
|
|
2643
2640
|
userAccessToken: access_token,
|
|
2644
|
-
refreshToken: refresh_token
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
console.log(`Configuration saved to .feishu_agent/config.json
|
|
2641
|
+
refreshToken: refresh_token
|
|
2642
|
+
});
|
|
2643
|
+
console.log(`Configuration saved to ~/.feishu-agent/config.json
|
|
2648
2644
|
`);
|
|
2649
2645
|
console.log("Step 3: Feishu Bitable (\u591A\u7EF4\u8868\u683C)");
|
|
2650
2646
|
console.log("-".repeat(40));
|
|
@@ -3166,6 +3162,9 @@ class CalendarManager {
|
|
|
3166
3162
|
return res;
|
|
3167
3163
|
}
|
|
3168
3164
|
async createEvent(calendarId, event) {
|
|
3165
|
+
if (event.checkConflict !== false) {
|
|
3166
|
+
await this.checkTimeConflict(event.startTime, event.endTime);
|
|
3167
|
+
}
|
|
3169
3168
|
const body = {
|
|
3170
3169
|
summary: event.summary,
|
|
3171
3170
|
description: event.description,
|
|
@@ -3198,6 +3197,31 @@ class CalendarManager {
|
|
|
3198
3197
|
const res = await this.client.post("/open-apis/calendar/v4/freebusy/list", body, { user_id_type: userIdType }, true);
|
|
3199
3198
|
return res;
|
|
3200
3199
|
}
|
|
3200
|
+
async checkTimeConflict(startTime, endTime) {
|
|
3201
|
+
const currentUser = await this.client.getCurrentUser();
|
|
3202
|
+
if (!currentUser?.user_id) {
|
|
3203
|
+
return;
|
|
3204
|
+
}
|
|
3205
|
+
const timeMin = this.toRFC3339(startTime);
|
|
3206
|
+
const timeMax = this.toRFC3339(endTime);
|
|
3207
|
+
const freeBusy = await this.getUserFreeBusy(currentUser.user_id, timeMin, timeMax);
|
|
3208
|
+
if (freeBusy.freebusy_list && freeBusy.freebusy_list.length > 0) {
|
|
3209
|
+
const conflicts = freeBusy.freebusy_list.map((slot) => `${new Date(slot.start_time).toLocaleString()} - ${new Date(slot.end_time).toLocaleString()}`);
|
|
3210
|
+
throw new Error(`Time conflict detected. The following time slots are already busy:
|
|
3211
|
+
` + ` ${conflicts.join(`
|
|
3212
|
+
`)}`);
|
|
3213
|
+
}
|
|
3214
|
+
}
|
|
3215
|
+
toRFC3339(time) {
|
|
3216
|
+
if (time.timestamp) {
|
|
3217
|
+
const date = new Date(parseInt(time.timestamp) * 1000);
|
|
3218
|
+
return date.toISOString();
|
|
3219
|
+
}
|
|
3220
|
+
if (time.date) {
|
|
3221
|
+
return time.date;
|
|
3222
|
+
}
|
|
3223
|
+
return new Date().toISOString();
|
|
3224
|
+
}
|
|
3201
3225
|
async updateEvent(calendarId, eventId, updates) {
|
|
3202
3226
|
const body = {};
|
|
3203
3227
|
if (updates.summary !== undefined)
|
|
@@ -3727,7 +3751,7 @@ async function handleSearch(config, query) {
|
|
|
3727
3751
|
// package.json
|
|
3728
3752
|
var package_default = {
|
|
3729
3753
|
name: "@teamclaw/feishu-agent",
|
|
3730
|
-
version: "1.0.
|
|
3754
|
+
version: "1.0.5",
|
|
3731
3755
|
description: "Feishu Agent CLI for AI assistants",
|
|
3732
3756
|
type: "module",
|
|
3733
3757
|
private: false,
|