@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.
Files changed (2) hide show
  1. package/dist/main.mjs +59 -23
  2. 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 = typeof body.transcript_path === "string" ? body.transcript_path : typeof body.transcriptPath === "string" ? body.transcriptPath : void 0;
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
- if (!transcriptPath || !isTranscriptSanitizerEnabled()) {
7396
- res.json({ continue: true });
7397
- return;
7398
- }
7399
- try {
7400
- const result = await sanitizeClaudeTranscriptFile(transcriptPath);
7401
- res.json({
7402
- continue: true,
7403
- hookSpecificOutput: result.changed ? {
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(typeof body.transcript_path === "string" ? body.transcript_path : void 0);
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-lark/larkpal",
3
- "version": "0.1.78",
3
+ "version": "0.1.79",
4
4
  "description": "LarkPal - Lark/Feishu bot service",
5
5
  "type": "module",
6
6
  "main": "./dist/main.mjs",