@vibe-lark/larkpal 0.1.78 → 0.1.79
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/dist/main.mjs +59 -23
- package/package.json +1 -1
package/dist/main.mjs
CHANGED
|
@@ -7332,6 +7332,7 @@ function asObject(value) {
|
|
|
7332
7332
|
* 所有 hook 当前只做日志记录,不做复杂业务处理。
|
|
7333
7333
|
*/
|
|
7334
7334
|
const logger$5 = larkLogger("gateway/hooks");
|
|
7335
|
+
const DELAYED_SANITIZER_RETRY_MS = 1e3;
|
|
7335
7336
|
/**
|
|
7336
7337
|
* 创建 HTTP Hooks 路由
|
|
7337
7338
|
*/
|
|
@@ -7384,7 +7385,7 @@ function createHooksRouter() {
|
|
|
7384
7385
|
});
|
|
7385
7386
|
router.post("/post-tool-use", async (req, res) => {
|
|
7386
7387
|
const body = req.body;
|
|
7387
|
-
const transcriptPath =
|
|
7388
|
+
const transcriptPath = getTranscriptPath(body);
|
|
7388
7389
|
logger$5.info("hook received: post-tool-use", {
|
|
7389
7390
|
method: req.method,
|
|
7390
7391
|
url: req.originalUrl,
|
|
@@ -7392,36 +7393,28 @@ function createHooksRouter() {
|
|
|
7392
7393
|
toolName: body.tool_name,
|
|
7393
7394
|
transcriptPath
|
|
7394
7395
|
});
|
|
7395
|
-
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
|
|
7404
|
-
hookEventName: "PostToolUse",
|
|
7405
|
-
additionalContext: `LarkPal externalized ${result.sanitizedImageBlocks} image tool result(s) from the persisted Claude transcript to reduce future replay payload.`
|
|
7406
|
-
} : void 0
|
|
7407
|
-
});
|
|
7408
|
-
} catch (err) {
|
|
7409
|
-
logger$5.warn("post-tool-use transcript sanitizer failed", {
|
|
7410
|
-
transcriptPath,
|
|
7411
|
-
error: err instanceof Error ? err.message : String(err)
|
|
7412
|
-
});
|
|
7413
|
-
res.json({ continue: true });
|
|
7414
|
-
}
|
|
7396
|
+
const result = await sanitizeTranscriptFromHook("PostToolUse", transcriptPath);
|
|
7397
|
+
if (result?.changed === false) scheduleDelayedTranscriptSanitizer("PostToolUse", transcriptPath);
|
|
7398
|
+
res.json({
|
|
7399
|
+
continue: true,
|
|
7400
|
+
hookSpecificOutput: result?.changed ? {
|
|
7401
|
+
hookEventName: "PostToolUse",
|
|
7402
|
+
additionalContext: `LarkPal externalized ${result.sanitizedImageBlocks} image tool result(s) from the persisted Claude transcript to reduce future replay payload.`
|
|
7403
|
+
} : void 0
|
|
7404
|
+
});
|
|
7415
7405
|
});
|
|
7416
|
-
router.post("/session-end", (req, res) => {
|
|
7406
|
+
router.post("/session-end", async (req, res) => {
|
|
7417
7407
|
const body = req.body;
|
|
7408
|
+
const transcriptPath = getTranscriptPath(body);
|
|
7418
7409
|
logger$5.info("hook received: session-end", {
|
|
7419
7410
|
method: req.method,
|
|
7420
7411
|
url: req.originalUrl,
|
|
7421
7412
|
sessionId: body.session_id,
|
|
7413
|
+
transcriptPath,
|
|
7422
7414
|
body
|
|
7423
7415
|
});
|
|
7424
|
-
resetImageReadGuard(
|
|
7416
|
+
resetImageReadGuard(transcriptPath);
|
|
7417
|
+
if ((await sanitizeTranscriptFromHook("SessionEnd", transcriptPath))?.changed === false) scheduleDelayedTranscriptSanitizer("SessionEnd", transcriptPath);
|
|
7425
7418
|
res.json({ received: true });
|
|
7426
7419
|
});
|
|
7427
7420
|
router.post("/notification", (req, res) => {
|
|
@@ -7435,6 +7428,47 @@ function createHooksRouter() {
|
|
|
7435
7428
|
});
|
|
7436
7429
|
return router;
|
|
7437
7430
|
}
|
|
7431
|
+
function getTranscriptPath(body) {
|
|
7432
|
+
return typeof body.transcript_path === "string" ? body.transcript_path : typeof body.transcriptPath === "string" ? body.transcriptPath : void 0;
|
|
7433
|
+
}
|
|
7434
|
+
async function sanitizeTranscriptFromHook(hookEventName, transcriptPath) {
|
|
7435
|
+
if (!transcriptPath) {
|
|
7436
|
+
logger$5.info("transcript sanitizer skipped: no transcript path", { hookEventName });
|
|
7437
|
+
return;
|
|
7438
|
+
}
|
|
7439
|
+
if (!isTranscriptSanitizerEnabled()) {
|
|
7440
|
+
logger$5.info("transcript sanitizer skipped: disabled", {
|
|
7441
|
+
hookEventName,
|
|
7442
|
+
transcriptPath
|
|
7443
|
+
});
|
|
7444
|
+
return;
|
|
7445
|
+
}
|
|
7446
|
+
try {
|
|
7447
|
+
const result = await sanitizeClaudeTranscriptFile(transcriptPath);
|
|
7448
|
+
logger$5.info("transcript sanitizer completed", {
|
|
7449
|
+
hookEventName,
|
|
7450
|
+
transcriptPath,
|
|
7451
|
+
changed: result.changed,
|
|
7452
|
+
lines: result.lines,
|
|
7453
|
+
sanitizedImageBlocks: result.sanitizedImageBlocks,
|
|
7454
|
+
artifacts: result.artifacts
|
|
7455
|
+
});
|
|
7456
|
+
return result;
|
|
7457
|
+
} catch (err) {
|
|
7458
|
+
logger$5.warn("transcript sanitizer failed", {
|
|
7459
|
+
hookEventName,
|
|
7460
|
+
transcriptPath,
|
|
7461
|
+
error: err instanceof Error ? err.message : String(err)
|
|
7462
|
+
});
|
|
7463
|
+
return;
|
|
7464
|
+
}
|
|
7465
|
+
}
|
|
7466
|
+
function scheduleDelayedTranscriptSanitizer(hookEventName, transcriptPath) {
|
|
7467
|
+
if (!transcriptPath || !isTranscriptSanitizerEnabled()) return;
|
|
7468
|
+
setTimeout(() => {
|
|
7469
|
+
sanitizeTranscriptFromHook(`${hookEventName}:delayed`, transcriptPath);
|
|
7470
|
+
}, DELAYED_SANITIZER_RETRY_MS).unref();
|
|
7471
|
+
}
|
|
7438
7472
|
//#endregion
|
|
7439
7473
|
//#region src/memory/store.ts
|
|
7440
7474
|
const log$27 = larkLogger("memory/store");
|
|
@@ -20139,6 +20173,8 @@ async function main() {
|
|
|
20139
20173
|
logger.info("LarkPal 启动中...");
|
|
20140
20174
|
if (process.env.LARKPAL_HEADLESS === "1" || process.env.LARKPAL_HEADLESS === "true") {
|
|
20141
20175
|
logger.info("Headless 模式启动 — 跳过飞书凭证/preflight/WebSocket");
|
|
20176
|
+
await ensureDefaults();
|
|
20177
|
+
logger.info("Headless 默认配置检查完成");
|
|
20142
20178
|
await startHeadless();
|
|
20143
20179
|
return;
|
|
20144
20180
|
}
|