lark-coding-assistant 0.2.1 → 0.2.2
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 +1 -1
- package/dist/daemon-entry.js +66 -19
- package/dist/daemon-entry.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
- codex、traex 与 claude 可混合运行,默认使用 codex;
|
|
10
10
|
- 支持多个命名 session,一个飞书账号可在 `/sessions` 卡片中直接切换或新建;
|
|
11
|
-
- 普通飞书消息默认发送到当前 active session
|
|
11
|
+
- 普通飞书消息默认发送到当前 active session;消息被 bridge 接收后会在原消息上显示处理中表情,下一条 bridge 通知发送前或等待满 10 分钟时自动移除;
|
|
12
12
|
- 支持 `/tail`、`/status`、`/stop`、远程处理审批与 Question,以及无法识别画面的手动遥控兜底;
|
|
13
13
|
- 本地终端保持 attach 时,飞书仍可操作同一个 TUI;
|
|
14
14
|
- 首次扫码后保存唯一 owner,后续通常无需绑定码;
|
package/dist/daemon-entry.js
CHANGED
|
@@ -2112,6 +2112,8 @@ var LarkGateway = class {
|
|
|
2112
2112
|
signer;
|
|
2113
2113
|
formActions = /* @__PURE__ */ new Map();
|
|
2114
2114
|
formActionsInFlight = /* @__PURE__ */ new Set();
|
|
2115
|
+
processingReactions = /* @__PURE__ */ new Map();
|
|
2116
|
+
processingGenerations = /* @__PURE__ */ new Map();
|
|
2115
2117
|
async handleDeferredCardAction(event, action) {
|
|
2116
2118
|
let initialResumePicker;
|
|
2117
2119
|
try {
|
|
@@ -2128,7 +2130,7 @@ var LarkGateway = class {
|
|
|
2128
2130
|
this.formActions.delete(event.messageId);
|
|
2129
2131
|
return;
|
|
2130
2132
|
}
|
|
2131
|
-
await this.
|
|
2133
|
+
await this.sendMessage(event.chatId, { text: `\u5361\u7247\u64CD\u4F5C\u672A\u5B8C\u6210\uFF1A${result2.content}` });
|
|
2132
2134
|
return;
|
|
2133
2135
|
}
|
|
2134
2136
|
if (result2.type === "session-created") {
|
|
@@ -2158,7 +2160,7 @@ var LarkGateway = class {
|
|
|
2158
2160
|
}
|
|
2159
2161
|
if (result2.type === "session-picker") {
|
|
2160
2162
|
if (action.kind === "session-start-error") {
|
|
2161
|
-
await this.
|
|
2163
|
+
await this.sendMessage(event.chatId, { card: sessionPickerCard(
|
|
2162
2164
|
event.chatId,
|
|
2163
2165
|
result2.sessions,
|
|
2164
2166
|
result2.activeSessionId,
|
|
@@ -2177,13 +2179,13 @@ var LarkGateway = class {
|
|
|
2177
2179
|
return;
|
|
2178
2180
|
}
|
|
2179
2181
|
if (result2.type === "session-create-form") {
|
|
2180
|
-
const sent = await this.
|
|
2182
|
+
const sent = await this.sendMessage(event.chatId, { card: sessionCreateCard() });
|
|
2181
2183
|
this.rememberSessionCreateFormAction(sent.messageId, event.chatId);
|
|
2182
2184
|
const sourceCard = action.kind === "session-create" && result2.sessions ? sessionPickerCard(event.chatId, result2.sessions, result2.activeSessionId, this.signer, void 0, false) : sessionCreateOpenedCard();
|
|
2183
2185
|
await this.updateCardAfterAction(event.messageId, sourceCard).catch(async (error) => {
|
|
2184
2186
|
const detail = cardErrorDetail(error);
|
|
2185
2187
|
console.error(`[lca] failed to retire session-create source card: message=${event.messageId} detail=${detail}`);
|
|
2186
|
-
await this.
|
|
2188
|
+
await this.sendMessage(event.chatId, {
|
|
2187
2189
|
text: "\u65B0\u5EFA\u8868\u5355\u5DF2\u53D1\u9001\uFF0C\u4F46\u539F\u5361\u7247\u72B6\u6001\u66F4\u65B0\u5931\u8D25\uFF1B\u8BF7\u4F7F\u7528\u6700\u65B0\u7684\u201C\u65B0\u5EFA Coding Session\u201D\u5361\u7247\u7EE7\u7EED\u64CD\u4F5C\u3002"
|
|
2188
2190
|
}).catch(() => void 0);
|
|
2189
2191
|
});
|
|
@@ -2216,7 +2218,7 @@ var LarkGateway = class {
|
|
|
2216
2218
|
}
|
|
2217
2219
|
if (action.kind === "session-create") this.formActions.delete(event.messageId);
|
|
2218
2220
|
console.error(`[lca] deferred card action failed: kind=${action.kind} action=${action.action} message=${event.messageId} detail=${detail}`);
|
|
2219
|
-
await this.
|
|
2221
|
+
await this.sendMessage(event.chatId, {
|
|
2220
2222
|
text: action.kind === "session-create" ? `\u65B0\u5EFA Session \u8868\u5355\u6253\u5F00\u5931\u8D25\uFF1A${detail}\u3002\u8BF7\u91CD\u65B0\u53D1\u9001 /sessions\uFF0C\u6216\u76F4\u63A5\u4F7F\u7528 /start \u547D\u4EE4\u3002` : `\u5361\u7247\u64CD\u4F5C\u540C\u6B65\u5931\u8D25\uFF1A${detail}`
|
|
2221
2223
|
}).catch(() => void 0);
|
|
2222
2224
|
}
|
|
@@ -2242,7 +2244,7 @@ var LarkGateway = class {
|
|
|
2242
2244
|
} catch (error) {
|
|
2243
2245
|
const detail = cardErrorDetail(error);
|
|
2244
2246
|
console.error(`[lca] failed to mark expired card: message=${event.messageId} detail=${detail}`);
|
|
2245
|
-
await this.
|
|
2247
|
+
await this.sendMessage(event.chatId, {
|
|
2246
2248
|
text: "\u5361\u7247\u6216\u6309\u94AE\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u5BF9\u5E94\u547D\u4EE4\u83B7\u53D6\u6700\u65B0\u5361\u7247\uFF1BSession \u76F8\u5173\u64CD\u4F5C\u53EF\u53D1\u9001 /sessions\u3002"
|
|
2247
2249
|
}).catch(() => void 0);
|
|
2248
2250
|
}
|
|
@@ -2250,17 +2252,37 @@ var LarkGateway = class {
|
|
|
2250
2252
|
connect() {
|
|
2251
2253
|
return this.channel.connect();
|
|
2252
2254
|
}
|
|
2253
|
-
disconnect() {
|
|
2254
|
-
|
|
2255
|
+
async disconnect() {
|
|
2256
|
+
const chats = /* @__PURE__ */ new Set([...this.processingGenerations.keys(), ...this.processingReactions.keys()]);
|
|
2257
|
+
await Promise.all([...chats].map((chatId) => this.clearProcessing(chatId)));
|
|
2258
|
+
await this.channel.disconnect();
|
|
2259
|
+
}
|
|
2260
|
+
async startProcessing(message) {
|
|
2261
|
+
await this.clearProcessing(message.chatId);
|
|
2262
|
+
const generation = this.processingGenerations.get(message.chatId) ?? 0;
|
|
2263
|
+
try {
|
|
2264
|
+
const reactionId = await this.channel.addReaction(message.messageId, "Typing");
|
|
2265
|
+
if (this.processingGenerations.get(message.chatId) !== generation) {
|
|
2266
|
+
await this.removeProcessingReaction(message.messageId, reactionId);
|
|
2267
|
+
return;
|
|
2268
|
+
}
|
|
2269
|
+
const timer = setTimeout(() => {
|
|
2270
|
+
void this.clearProcessing(message.chatId, generation);
|
|
2271
|
+
}, 10 * 6e4);
|
|
2272
|
+
timer.unref?.();
|
|
2273
|
+
this.processingReactions.set(message.chatId, { messageId: message.messageId, reactionId, timer, generation });
|
|
2274
|
+
} catch (error) {
|
|
2275
|
+
console.error(`[lca] failed to add processing reaction: chat=${message.chatId} message=${message.messageId} detail=${cardErrorDetail(error)}`);
|
|
2276
|
+
}
|
|
2255
2277
|
}
|
|
2256
2278
|
sendText(chatId, text) {
|
|
2257
|
-
return this.
|
|
2279
|
+
return this.sendMessage(chatId, { text });
|
|
2258
2280
|
}
|
|
2259
2281
|
sendMarkdown(chatId, markdown) {
|
|
2260
|
-
return this.
|
|
2282
|
+
return this.sendMessage(chatId, { markdown });
|
|
2261
2283
|
}
|
|
2262
2284
|
async sendChoice(chatId, paneId, screen, agent) {
|
|
2263
|
-
const result2 = await this.
|
|
2285
|
+
const result2 = await this.sendMessage(chatId, { card: choiceCard(chatId, paneId, screen, this.signer, agent) });
|
|
2264
2286
|
this.rememberFormActions(result2.messageId, chatId, paneId, screen, agent);
|
|
2265
2287
|
return result2;
|
|
2266
2288
|
}
|
|
@@ -2273,7 +2295,7 @@ var LarkGateway = class {
|
|
|
2273
2295
|
this.formActions.delete(messageId);
|
|
2274
2296
|
}
|
|
2275
2297
|
async sendManual(chatId, view2) {
|
|
2276
|
-
const result2 = await this.
|
|
2298
|
+
const result2 = await this.sendMessage(chatId, { card: manualControlCard(chatId, view2, this.signer) });
|
|
2277
2299
|
this.rememberManualFormActions(result2.messageId, chatId, view2);
|
|
2278
2300
|
return result2;
|
|
2279
2301
|
}
|
|
@@ -2332,27 +2354,51 @@ var LarkGateway = class {
|
|
|
2332
2354
|
}
|
|
2333
2355
|
}
|
|
2334
2356
|
sendStatus(chatId, status) {
|
|
2335
|
-
return this.
|
|
2357
|
+
return this.sendMessage(chatId, { card: statusCard(status) });
|
|
2336
2358
|
}
|
|
2337
2359
|
sendSessionPicker(chatId, sessions, activeSessionId) {
|
|
2338
|
-
return this.
|
|
2360
|
+
return this.sendMessage(chatId, { card: sessionPickerCard(chatId, sessions, activeSessionId, this.signer) });
|
|
2339
2361
|
}
|
|
2340
2362
|
sendResumePicker(chatId, session, picker) {
|
|
2341
|
-
return this.
|
|
2363
|
+
return this.sendMessage(chatId, { card: resumePickerCard(chatId, session, picker, this.signer) });
|
|
2342
2364
|
}
|
|
2343
2365
|
sendStartupConflict(chatId, request, owner) {
|
|
2344
|
-
return this.
|
|
2366
|
+
return this.sendMessage(chatId, { card: startupConflictCard(chatId, requestSession(request), owner, this.signer) });
|
|
2345
2367
|
}
|
|
2346
2368
|
async sendSessionCreate(chatId) {
|
|
2347
|
-
const result2 = await this.
|
|
2369
|
+
const result2 = await this.sendMessage(chatId, { card: sessionCreateCard() });
|
|
2348
2370
|
this.rememberSessionCreateFormAction(result2.messageId, chatId);
|
|
2349
2371
|
return result2;
|
|
2350
2372
|
}
|
|
2351
2373
|
sendSessionStartupFailure(chatId, failure) {
|
|
2352
|
-
return this.
|
|
2374
|
+
return this.sendMessage(chatId, { card: sessionStartupFailureCard(chatId, failure, this.signer) });
|
|
2353
2375
|
}
|
|
2354
2376
|
sendStopConfirmation(chatId, paneId, fingerprint, agent) {
|
|
2355
|
-
return this.
|
|
2377
|
+
return this.sendMessage(chatId, { card: stopCard(chatId, paneId, fingerprint, this.signer, agent) });
|
|
2378
|
+
}
|
|
2379
|
+
async sendMessage(chatId, input) {
|
|
2380
|
+
await this.clearProcessing(chatId);
|
|
2381
|
+
return this.channel.send(chatId, input);
|
|
2382
|
+
}
|
|
2383
|
+
async clearProcessing(chatId, expectedGeneration) {
|
|
2384
|
+
const currentGeneration = this.processingGenerations.get(chatId) ?? 0;
|
|
2385
|
+
if (expectedGeneration !== void 0 && currentGeneration !== expectedGeneration) return;
|
|
2386
|
+
this.processingGenerations.set(chatId, currentGeneration + 1);
|
|
2387
|
+
const pending = this.processingReactions.get(chatId);
|
|
2388
|
+
if (!pending) return;
|
|
2389
|
+
this.processingReactions.delete(chatId);
|
|
2390
|
+
clearTimeout(pending.timer);
|
|
2391
|
+
await this.removeProcessingReaction(pending.messageId, pending.reactionId);
|
|
2392
|
+
}
|
|
2393
|
+
async removeProcessingReaction(messageId, reactionId) {
|
|
2394
|
+
try {
|
|
2395
|
+
await this.channel.removeReaction(messageId, reactionId);
|
|
2396
|
+
} catch (error) {
|
|
2397
|
+
console.error(`[lca] failed to remove processing reaction by id: message=${messageId} detail=${cardErrorDetail(error)}`);
|
|
2398
|
+
await this.channel.removeReactionByEmoji(messageId, "Typing").catch((fallbackError) => {
|
|
2399
|
+
console.error(`[lca] failed to remove processing reaction by emoji: message=${messageId} detail=${cardErrorDetail(fallbackError)}`);
|
|
2400
|
+
});
|
|
2401
|
+
}
|
|
2356
2402
|
}
|
|
2357
2403
|
};
|
|
2358
2404
|
function requestSession(request) {
|
|
@@ -3178,6 +3224,7 @@ ${escapeFence2(output).slice(-6800)}
|
|
|
3178
3224
|
await this.gateway?.sendText(message.chatId, `\u5DF2\u5411 ${getAgentAdapter(session.agent).displayName} \u63D0\u4EA4\u8865\u5145\u5185\u5BB9\u3002`);
|
|
3179
3225
|
return;
|
|
3180
3226
|
}
|
|
3227
|
+
await this.gateway?.startProcessing(message);
|
|
3181
3228
|
await this.poll();
|
|
3182
3229
|
if (this.shouldQueueMessage()) {
|
|
3183
3230
|
if (this.pendingMessages.length >= 100) {
|