feat:support feshu via websocket

This commit is contained in:
ie2718 2026-01-26 23:10:45 +08:00
parent b560bdeab6
commit bd23d04ce2
9 changed files with 409 additions and 475 deletions

View File

@ -1,12 +1,12 @@
--- ---
summary: "Feishu (Lark) bot support, capabilities, and configuration" summary: "Feishu (Lark) bot support, capabilities, and configuration"
read_when: read_when:
- Working on Feishu features or webhooks - Working on Feishu features
- Integrating with Chinese enterprise messaging - Integrating with Chinese enterprise messaging
--- ---
# Feishu (飞书/Lark) # Feishu (飞书/Lark)
Status: experimental. Supports direct messages and groups via Bot API. Status: experimental. Supports direct messages and groups via Bot API using WebSocket long connection.
## Plugin required ## Plugin required
Feishu ships as a plugin and is not bundled with the core install. Feishu ships as a plugin and is not bundled with the core install.
@ -23,7 +23,9 @@ Feishu ships as a plugin and is not bundled with the core install.
3) Set the credentials: 3) Set the credentials:
- Env: `FEISHU_APP_ID=...` and `FEISHU_APP_SECRET=...` - Env: `FEISHU_APP_ID=...` and `FEISHU_APP_SECRET=...`
- Or config: `channels.feishu.appId` and `channels.feishu.appSecret` - Or config: `channels.feishu.appId` and `channels.feishu.appSecret`
4) Configure event subscription in Feishu console with your webhook URL 4) Configure event subscription in Feishu console:
- Set subscription method to **"Long Connection"**
- Add `im.message.receive_v1` event
5) Restart the gateway (or finish onboarding) 5) Restart the gateway (or finish onboarding)
6) DM access is pairing by default; approve the pairing code on first contact 6) DM access is pairing by default; approve the pairing code on first contact
@ -35,8 +37,6 @@ Minimal config:
enabled: true, enabled: true,
appId: "cli_xxxxxxxxxx", appId: "cli_xxxxxxxxxx",
appSecret: "xxxxxxxxxxxxxxxxxxxxxxxx", appSecret: "xxxxxxxxxxxxxxxxxxxxxxxx",
verificationToken: "xxxxxxxxxxxxxxxxxxxxxxxx",
webhookPath: "/feishu/callback",
dmPolicy: "pairing" dmPolicy: "pairing"
} }
} }
@ -46,6 +46,7 @@ Minimal config:
## What it is ## What it is
Feishu (飞书) is an enterprise collaboration platform by ByteDance, also known as Lark internationally. Its Bot API allows the Gateway to run a bot for 1:1 conversations and group chats. Feishu (飞书) is an enterprise collaboration platform by ByteDance, also known as Lark internationally. Its Bot API allows the Gateway to run a bot for 1:1 conversations and group chats.
- A Feishu Bot API channel owned by the Gateway - A Feishu Bot API channel owned by the Gateway
- Uses WebSocket long connection for receiving events (no public IP needed)
- Deterministic routing: replies go back to Feishu; the model never chooses channels - Deterministic routing: replies go back to Feishu; the model never chooses channels
- DMs share the agent's main session - DMs share the agent's main session
- Groups require @mention by default - Groups require @mention by default
@ -70,11 +71,9 @@ Feishu (飞书) is an enterprise collaboration platform by ByteDance, also known
### 3) Configure event subscription ### 3) Configure event subscription
1) Go to "Events and Callbacks" page 1) Go to "Events and Callbacks" page
2) Choose "Request URL Mode" (webhook) 2) Set subscription method to **"Long Connection"** (WebSocket)
3) Enter your webhook URL: `https://your-gateway-host/feishu/callback` 3) Add event subscription: `im.message.receive_v1` (Receive messages)
4) Copy the **Verification Token** and optionally the **Encrypt Key** 4) Click Save
5) Add event subscription: `im.message.receive_v1` (Receive messages)
6) Click Save
### 4) Configure the token (env or config) ### 4) Configure the token (env or config)
Example: Example:
@ -86,9 +85,6 @@ Example:
enabled: true, enabled: true,
appId: "cli_xxxxxxxxxx", appId: "cli_xxxxxxxxxx",
appSecret: "xxxxxxxxxxxxxxxxxxxxxxxx", appSecret: "xxxxxxxxxxxxxxxxxxxxxxxx",
verificationToken: "xxxxxxxxxxxxxxxxxxxxxxxx",
encryptKey: "xxxxxxxxxxxxxxxxxxxxxxxx", // optional, for encrypted events
webhookPath: "/feishu/callback",
dmPolicy: "pairing" dmPolicy: "pairing"
} }
} }
@ -98,8 +94,6 @@ Example:
Env option (works for the default account only): Env option (works for the default account only):
- `FEISHU_APP_ID=cli_xxxxxxxxxx` - `FEISHU_APP_ID=cli_xxxxxxxxxx`
- `FEISHU_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxxxx` - `FEISHU_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxxxx`
- `FEISHU_VERIFICATION_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxx`
- `FEISHU_ENCRYPT_KEY=xxxxxxxxxxxxxxxxxxxxxxxx`
Multi-account support: use `channels.feishu.accounts` with per-account credentials and optional `name`. Multi-account support: use `channels.feishu.accounts` with per-account credentials and optional `name`.
@ -114,8 +108,8 @@ Restart the gateway. Feishu starts when credentials are resolved.
DM access defaults to pairing. Approve the code when the bot is first contacted. DM access defaults to pairing. Approve the code when the bot is first contacted.
## How it works (behavior) ## How it works (behavior)
- Inbound messages arrive via webhook (Feishu sends HTTP POST to your configured path) - The gateway establishes a WebSocket long connection to Feishu servers
- The gateway verifies the request using the verification token - Events are pushed directly through the WebSocket (no public IP needed)
- Messages are normalized into the shared channel envelope - Messages are normalized into the shared channel envelope
- Replies always route back to the same Feishu chat - Replies always route back to the same Feishu chat
- Long responses are chunked to 4000 characters (Feishu API limit) - Long responses are chunked to 4000 characters (Feishu API limit)
@ -123,7 +117,6 @@ DM access defaults to pairing. Approve the code when the bot is first contacted.
## Limits ## Limits
- Outbound text is chunked to 4000 characters (Feishu API limit) - Outbound text is chunked to 4000 characters (Feishu API limit)
- Media downloads/uploads are capped by `channels.feishu.mediaMaxMb` (default 20) - Media downloads/uploads are capped by `channels.feishu.mediaMaxMb` (default 20)
- Streaming is blocked by default due to webhook-based architecture
- Rate limits apply per the Feishu API documentation - Rate limits apply per the Feishu API documentation
## Access control (DMs) ## Access control (DMs)
@ -141,33 +134,33 @@ DM access defaults to pairing. Approve the code when the bot is first contacted.
- Configure allowed groups via `channels.feishu.groupAllowFrom` or `channels.feishu.groups` - Configure allowed groups via `channels.feishu.groupAllowFrom` or `channels.feishu.groups`
- Groups require @mention by default; configure per-group via `channels.feishu.groups.<chat_id>.requireMention` - Groups require @mention by default; configure per-group via `channels.feishu.groups.<chat_id>.requireMention`
## Webhook verification
Feishu uses two verification mechanisms:
1) **URL Verification**: When you first configure the webhook, Feishu sends a challenge request. The gateway responds automatically.
2) **Event Verification**: Each event includes a `token` field that must match your verification token.
Optional encryption:
- If you enable encryption in Feishu console, set `channels.feishu.encryptKey`
- Events are encrypted with AES-256-CBC; the gateway decrypts them automatically
## Supported message types ## Supported message types
- **Text messages**: Full support with 4000 character chunking - **Interactive cards**: Full markdown support via card messages (default for replies)
- **Image messages**: Logged but media upload requires image_key (planned) - **Text messages**: Plain text fallback
- **Image messages**: Requires image_key (pre-uploaded images)
- **Rich text (post)**: Planned support - **Rich text (post)**: Planned support
- **Interactive cards**: Planned support
### Markdown support
All outbound messages use Feishu interactive card format, which supports markdown syntax:
- **Bold**: `**text**`
- *Italic*: `*text*`
- ~~Strikethrough~~: `~~text~~`
- `Code`: `` `code` ``
- Links: `[text](url)`
- Lists and more
## Capabilities ## Capabilities
| Feature | Status | | Feature | Status |
|---------|--------| |---------|--------|
| Direct messages | Supported | | Direct messages | Supported |
| Groups | Supported | | Groups | Supported |
| Media (images) | Partial (text only for now) | | Markdown formatting | Supported (via card messages) |
| Media (images) | Partial (requires image_key) |
| Reactions | Not supported | | Reactions | Not supported |
| Threads | Not supported | | Threads | Not supported |
| Polls | Not supported | | Polls | Not supported |
| Native commands | Not supported | | Native commands | Not supported |
| Streaming | Blocked (webhook-based) | | Streaming | Blocked |
| Rich cards | Planned |
## Delivery targets (CLI/cron) ## Delivery targets (CLI/cron)
- Use an open_id, user_id, or chat_id as the target - Use an open_id, user_id, or chat_id as the target
@ -178,15 +171,14 @@ Optional encryption:
**Bot does not respond:** **Bot does not respond:**
- Check that the app credentials are valid: `clawdbot channels status --probe` - Check that the app credentials are valid: `clawdbot channels status --probe`
- Verify the webhook URL is correctly configured in Feishu console - Verify the event subscription is set to "Long Connection" mode in Feishu console
- Check that the verification token matches
- Verify the sender is approved (pairing or allowFrom) - Verify the sender is approved (pairing or allowFrom)
- Check gateway logs: `clawdbot logs --follow` - Check gateway logs: `clawdbot logs --follow`
**Webhook verification fails:** **WebSocket connection fails:**
- Ensure your gateway is publicly accessible at the configured webhook path - Ensure the gateway has network access to Feishu servers
- Check that `channels.feishu.verificationToken` matches the token in Feishu console - Check that the App ID and App Secret are correct
- If using encryption, verify `channels.feishu.encryptKey` is correct - Verify the app is published and active
**Permission errors:** **Permission errors:**
- Ensure the app has required permissions (`im:message`, `im:message.receive_v1`) - Ensure the app has required permissions (`im:message`, `im:message.receive_v1`)
@ -206,9 +198,6 @@ Provider options:
- `channels.feishu.appId`: App ID from Feishu Open Platform - `channels.feishu.appId`: App ID from Feishu Open Platform
- `channels.feishu.appSecret`: App Secret from Feishu Open Platform - `channels.feishu.appSecret`: App Secret from Feishu Open Platform
- `channels.feishu.appSecretFile`: read app secret from file path - `channels.feishu.appSecretFile`: read app secret from file path
- `channels.feishu.verificationToken`: verification token for webhook validation
- `channels.feishu.encryptKey`: encrypt key for event decryption (optional)
- `channels.feishu.webhookPath`: webhook path on the gateway HTTP server (default: /feishu/callback)
- `channels.feishu.dmPolicy`: `pairing | allowlist | open | disabled` (default: pairing) - `channels.feishu.dmPolicy`: `pairing | allowlist | open | disabled` (default: pairing)
- `channels.feishu.allowFrom`: DM allowlist (open_id or user_id). `open` requires `"*"` - `channels.feishu.allowFrom`: DM allowlist (open_id or user_id). `open` requires `"*"`
- `channels.feishu.groupPolicy`: `open | allowlist` (default: allowlist) - `channels.feishu.groupPolicy`: `open | allowlist` (default: allowlist)
@ -224,9 +213,6 @@ Multi-account options:
- `channels.feishu.accounts.<id>.enabled`: enable/disable account - `channels.feishu.accounts.<id>.enabled`: enable/disable account
- `channels.feishu.accounts.<id>.dmPolicy`: per-account DM policy - `channels.feishu.accounts.<id>.dmPolicy`: per-account DM policy
- `channels.feishu.accounts.<id>.allowFrom`: per-account allowlist - `channels.feishu.accounts.<id>.allowFrom`: per-account allowlist
- `channels.feishu.accounts.<id>.verificationToken`: per-account verification token
- `channels.feishu.accounts.<id>.encryptKey`: per-account encrypt key
- `channels.feishu.accounts.<id>.webhookPath`: per-account webhook path
## International users (Lark) ## International users (Lark)
For Lark (international version), use the same configuration. The API endpoints are compatible. For Lark (international version), use the same configuration. The API endpoints are compatible.

View File

@ -2,7 +2,6 @@ import type { ClawdbotPluginApi } from "clawdbot/plugin-sdk";
import { emptyPluginConfigSchema } from "clawdbot/plugin-sdk"; import { emptyPluginConfigSchema } from "clawdbot/plugin-sdk";
import { feishuDock, feishuPlugin } from "./src/channel.js"; import { feishuDock, feishuPlugin } from "./src/channel.js";
import { handleFeishuWebhookRequest } from "./src/monitor.js";
import { setFeishuRuntime } from "./src/runtime.js"; import { setFeishuRuntime } from "./src/runtime.js";
const plugin = { const plugin = {
@ -13,7 +12,7 @@ const plugin = {
register(api: ClawdbotPluginApi) { register(api: ClawdbotPluginApi) {
setFeishuRuntime(api.runtime); setFeishuRuntime(api.runtime);
api.registerChannel({ plugin: feishuPlugin, dock: feishuDock }); api.registerChannel({ plugin: feishuPlugin, dock: feishuDock });
api.registerHttpHandler(handleFeishuWebhookRequest); // WebSocket mode - no HTTP handler needed
}, },
}; };

View File

@ -27,6 +27,9 @@
"defaultChoice": "npm" "defaultChoice": "npm"
} }
}, },
"dependencies": {
"@larksuiteoapi/node-sdk": "^1.56.1"
},
"devDependencies": { "devDependencies": {
"clawdbot": "workspace:*" "clawdbot": "workspace:*"
}, },

View File

@ -3,8 +3,6 @@
* @see https://open.feishu.cn/document * @see https://open.feishu.cn/document
*/ */
import { createHash, createDecipheriv } from "node:crypto";
import type { import type {
FeishuApiResponse, FeishuApiResponse,
FeishuBotInfo, FeishuBotInfo,
@ -12,7 +10,6 @@ import type {
FeishuSendMessageParams, FeishuSendMessageParams,
FeishuSendMessageResponse, FeishuSendMessageResponse,
FeishuTokenResponse, FeishuTokenResponse,
FeishuWebhookPayload,
} from "./types.js"; } from "./types.js";
const FEISHU_API_BASE = "https://open.feishu.cn/open-apis"; const FEISHU_API_BASE = "https://open.feishu.cn/open-apis";
@ -214,74 +211,3 @@ export async function replyMessage(
fetch: options?.fetch, fetch: options?.fetch,
}); });
} }
// ─────────────────────────────────────────────────────────────────────────────
// Webhook Verification
// ─────────────────────────────────────────────────────────────────────────────
/**
* Decrypt an encrypted webhook payload using the encrypt key.
* Feishu uses AES-256-CBC with the key derived from SHA256 of the encrypt key.
*/
export function decryptWebhookPayload(encrypted: string, encryptKey: string): string {
// Derive key from encrypt key using SHA256
const key = createHash("sha256").update(encryptKey).digest();
// Decode base64
const ciphertext = Buffer.from(encrypted, "base64");
// First 16 bytes are the IV
const iv = ciphertext.subarray(0, 16);
const encryptedData = ciphertext.subarray(16);
// Decrypt using AES-256-CBC
const decipher = createDecipheriv("aes-256-cbc", key, iv);
let decrypted = decipher.update(encryptedData);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString("utf8");
}
/**
* Verify webhook signature using verification token.
*/
export function verifyWebhookToken(payload: FeishuWebhookPayload, verificationToken: string): boolean {
// For challenge verification, token is at top level
if (payload.token) {
return payload.token === verificationToken;
}
// For events, token is in header
if (payload.header?.token) {
return payload.header.token === verificationToken;
}
return false;
}
/**
* Parse webhook payload, decrypting if necessary.
*/
export function parseWebhookPayload(
rawBody: string,
encryptKey?: string,
): FeishuWebhookPayload | null {
try {
const parsed = JSON.parse(rawBody) as FeishuWebhookPayload;
// If encrypted, decrypt first
if (parsed.encrypt && encryptKey) {
const decrypted = decryptWebhookPayload(parsed.encrypt, encryptKey);
return JSON.parse(decrypted) as FeishuWebhookPayload;
}
return parsed;
} catch {
return null;
}
}
/**
* Build challenge response for URL verification.
*/
export function buildChallengeResponse(challenge: string): string {
return JSON.stringify({ challenge });
}

View File

@ -1,19 +1,21 @@
import type { IncomingMessage, ServerResponse } from "node:http"; /**
* WebSocket-based monitor for Feishu events using long connection mode.
* Uses the official @larksuiteoapi/node-sdk WSClient for receiving events
* via WebSocket - no public IP or webhook setup needed.
*
* @see https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/event-subscription-guide/long-connection-mode
*/
import * as Lark from "@larksuiteoapi/node-sdk";
import type { ClawdbotConfig, MarkdownTableMode } from "clawdbot/plugin-sdk"; import type { ClawdbotConfig, MarkdownTableMode } from "clawdbot/plugin-sdk";
import type { import type {
FeishuMessageEvent, FeishuMessageEvent,
FeishuReceiveIdType, FeishuReceiveIdType,
FeishuWebhookPayload,
ResolvedFeishuAccount, ResolvedFeishuAccount,
} from "./types.js"; } from "./types.js";
import { import { sendMessage } from "./api.js";
buildChallengeResponse,
parseWebhookPayload,
sendMessage,
verifyWebhookToken,
} from "./api.js";
import { getFeishuRuntime } from "./runtime.js"; import { getFeishuRuntime } from "./runtime.js";
export type FeishuRuntimeEnv = { export type FeishuRuntimeEnv = {
@ -26,7 +28,6 @@ export type FeishuMonitorOptions = {
config: ClawdbotConfig; config: ClawdbotConfig;
runtime: FeishuRuntimeEnv; runtime: FeishuRuntimeEnv;
abortSignal: AbortSignal; abortSignal: AbortSignal;
webhookPath?: string;
statusSink?: (patch: { lastInboundAt?: number; lastOutboundAt?: number }) => void; statusSink?: (patch: { lastInboundAt?: number; lastOutboundAt?: number }) => void;
}; };
@ -34,9 +35,29 @@ export type FeishuMonitorResult = {
stop: () => void; stop: () => void;
}; };
const FEISHU_TEXT_LIMIT = 4000; // Feishu card markdown content limit (slightly lower than text to account for JSON overhead)
const FEISHU_CARD_CONTENT_LIMIT = 3800;
const DEFAULT_MEDIA_MAX_MB = 20; const DEFAULT_MEDIA_MAX_MB = 20;
const DEFAULT_WEBHOOK_PATH = "/feishu/callback";
/**
* Build a Feishu interactive card with markdown content.
* Card messages support rich markdown formatting in Feishu.
*/
function buildMarkdownCard(content: string): string {
const card = {
config: {
wide_screen_mode: true,
enable_forward: true,
},
elements: [
{
tag: "markdown",
content,
},
],
};
return JSON.stringify(card);
}
type FeishuCoreRuntime = ReturnType<typeof getFeishuRuntime>; type FeishuCoreRuntime = ReturnType<typeof getFeishuRuntime>;
@ -46,11 +67,6 @@ function logVerbose(core: FeishuCoreRuntime, runtime: FeishuRuntimeEnv, message:
} }
} }
function logWebhookEvent(message: string): void {
// Use console to ensure visibility even when runtime isn't available.
console.warn(`[feishu] ${message}`);
}
type FeishuReplyTarget = { type FeishuReplyTarget = {
id: string; id: string;
type: FeishuReceiveIdType; type: FeishuReceiveIdType;
@ -73,218 +89,8 @@ function isSenderAllowed(senderId: string, allowFrom: string[]): boolean {
}); });
} }
async function readJsonBody(req: IncomingMessage, maxBytes: number) {
const chunks: Buffer[] = [];
let total = 0;
return await new Promise<{ ok: boolean; value?: string; error?: string }>((resolve) => {
req.on("data", (chunk: Buffer) => {
total += chunk.length;
if (total > maxBytes) {
resolve({ ok: false, error: "payload too large" });
req.destroy();
return;
}
chunks.push(chunk);
});
req.on("end", () => {
try {
const raw = Buffer.concat(chunks).toString("utf8");
if (!raw.trim()) {
resolve({ ok: false, error: "empty payload" });
return;
}
resolve({ ok: true, value: raw });
} catch (err) {
resolve({ ok: false, error: err instanceof Error ? err.message : String(err) });
}
});
req.on("error", (err) => {
resolve({ ok: false, error: err instanceof Error ? err.message : String(err) });
});
});
}
type WebhookTarget = {
account: ResolvedFeishuAccount;
config: ClawdbotConfig;
runtime: FeishuRuntimeEnv;
core: FeishuCoreRuntime;
path: string;
encryptKey: string;
verificationToken: string;
mediaMaxMb: number;
statusSink?: (patch: { lastInboundAt?: number; lastOutboundAt?: number }) => void;
};
const webhookTargets = new Map<string, WebhookTarget[]>();
function normalizeWebhookPath(raw: string): string {
const trimmed = raw.trim();
if (!trimmed) return "/feishu/callback";
const withSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
if (withSlash.length > 1 && withSlash.endsWith("/")) {
return withSlash.slice(0, -1);
}
return withSlash;
}
export function registerFeishuWebhookTarget(target: WebhookTarget): () => void {
const key = normalizeWebhookPath(target.path);
const normalizedTarget = { ...target, path: key };
const existing = webhookTargets.get(key) ?? [];
const next = [...existing, normalizedTarget];
webhookTargets.set(key, next);
return () => {
const updated = (webhookTargets.get(key) ?? []).filter(
(entry) => entry !== normalizedTarget,
);
if (updated.length > 0) {
webhookTargets.set(key, updated);
} else {
webhookTargets.delete(key);
}
};
}
/** /**
* Handle incoming Feishu webhook requests. * Process a message event from Feishu WebSocket.
*/
export async function handleFeishuWebhookRequest(
req: IncomingMessage,
res: ServerResponse,
): Promise<boolean> {
const url = new URL(req.url ?? "/", "http://localhost");
const path = normalizeWebhookPath(url.pathname);
const targets = webhookTargets.get(path);
if (!targets || targets.length === 0) {
if (path === DEFAULT_WEBHOOK_PATH || path.startsWith("/feishu/")) {
logWebhookEvent(
`webhook request received for ${path}, but no active Feishu accounts are registered`,
);
}
return false;
}
if (req.method !== "POST") {
res.statusCode = 405;
res.setHeader("Allow", "POST");
res.end("Method Not Allowed");
return true;
}
const body = await readJsonBody(req, 1024 * 1024);
if (!body.ok || !body.value) {
res.statusCode = body.error === "payload too large" ? 413 : 400;
res.end(body.error ?? "invalid payload");
return true;
}
let rawPayload: FeishuWebhookPayload | null = null;
try {
rawPayload = JSON.parse(body.value) as FeishuWebhookPayload;
} catch {
rawPayload = null;
}
const isEncryptedRequest = Boolean(rawPayload?.encrypt);
const rawEventType = rawPayload?.header?.event_type ?? rawPayload?.type ?? "unknown";
logWebhookEvent(
`webhook hit: path=${path} method=${req.method} targets=${targets.length} encrypted=${isEncryptedRequest} event=${rawEventType}`,
);
let sawTokenMismatch = false;
let sawEncryptedWithoutKey = false;
let sawDecryptFailure = false;
// Try each target to find one that can handle this request
for (const target of targets) {
const payload = parseWebhookPayload(body.value, target.encryptKey);
if (!payload) {
if (isEncryptedRequest && target.encryptKey) {
sawDecryptFailure = true;
target.runtime.error?.(
`[${target.account.accountId}] Feishu webhook decrypt failed. Check encryptKey.`,
);
}
continue;
}
if (payload.encrypt && !target.encryptKey) {
sawEncryptedWithoutKey = true;
target.runtime.error?.(
`[${target.account.accountId}] Feishu webhook is encrypted but encryptKey is not configured.`,
);
continue;
}
// Verify token if configured
if (target.verificationToken && !verifyWebhookToken(payload, target.verificationToken)) {
sawTokenMismatch = true;
target.runtime.error?.(
`[${target.account.accountId}] Feishu webhook token mismatch. Check verificationToken.`,
);
continue;
}
// Handle URL verification challenge
if (payload.type === "url_verification" && payload.challenge) {
res.statusCode = 200;
res.setHeader("Content-Type", "application/json");
res.end(buildChallengeResponse(payload.challenge));
return true;
}
// Handle message events
if (payload.header?.event_type === "im.message.receive_v1" && payload.event) {
target.statusSink?.({ lastInboundAt: Date.now() });
processMessageEvent(
payload.event as FeishuMessageEvent,
target.account,
target.config,
target.runtime,
target.core,
target.mediaMaxMb,
target.statusSink,
).catch((err) => {
target.runtime.error?.(`[${target.account.accountId}] Feishu webhook failed: ${String(err)}`);
});
res.statusCode = 200;
res.end("ok");
return true;
}
// Other event types - acknowledge but don't process
if (payload.header?.event_type) {
target.runtime.log?.(`[feishu] ignoring event type: ${payload.header.event_type}`);
res.statusCode = 200;
res.end("ok");
return true;
}
}
// No target could handle the request
if (sawEncryptedWithoutKey) {
res.statusCode = 400;
res.end("encrypt_key required");
return true;
}
if (sawDecryptFailure) {
res.statusCode = 400;
res.end("decrypt failed");
return true;
}
if (sawTokenMismatch) {
res.statusCode = 401;
res.end("unauthorized");
return true;
}
res.statusCode = 401;
res.end("unauthorized");
return true;
}
/**
* Process a message event from Feishu webhook.
*/ */
async function processMessageEvent( async function processMessageEvent(
event: FeishuMessageEvent, event: FeishuMessageEvent,
@ -543,18 +349,19 @@ async function deliverFeishuReply(params: {
const chunkMode = core.channel.text.resolveChunkMode(config, "feishu", account.accountId); const chunkMode = core.channel.text.resolveChunkMode(config, "feishu", account.accountId);
const chunks = core.channel.text.chunkMarkdownTextWithMode( const chunks = core.channel.text.chunkMarkdownTextWithMode(
text, text,
FEISHU_TEXT_LIMIT, FEISHU_CARD_CONTENT_LIMIT,
chunkMode, chunkMode,
); );
for (const chunk of chunks) { for (const chunk of chunks) {
try { try {
// Send as interactive card message with markdown support
await sendMessage( await sendMessage(
account.appId, account.appId,
account.appSecret, account.appSecret,
{ {
receive_id: receiveId, receive_id: receiveId,
msg_type: "text", msg_type: "interactive",
content: JSON.stringify({ text: chunk }), content: buildMarkdownCard(chunk),
}, },
receiveIdType, receiveIdType,
); );
@ -567,48 +374,70 @@ async function deliverFeishuReply(params: {
} }
/** /**
* Start monitoring Feishu webhook events. * Start monitoring Feishu events using WebSocket long connection.
*/ */
export async function monitorFeishuProvider( export async function monitorFeishuProvider(
options: FeishuMonitorOptions, options: FeishuMonitorOptions,
): Promise<FeishuMonitorResult> { ): Promise<FeishuMonitorResult> {
const { account, config, runtime, abortSignal, webhookPath, statusSink } = options; const { account, config, runtime, abortSignal, statusSink } = options;
const core = getFeishuRuntime(); const core = getFeishuRuntime();
const effectiveMediaMaxMb = account.config.mediaMaxMb ?? DEFAULT_MEDIA_MAX_MB; const effectiveMediaMaxMb = account.config.mediaMaxMb ?? DEFAULT_MEDIA_MAX_MB;
const path = normalizeWebhookPath(webhookPath ?? account.config.webhookPath ?? "/feishu/callback");
const encryptKey = account.config.encryptKey ?? process.env.FEISHU_ENCRYPT_KEY ?? "";
const verificationToken = account.config.verificationToken ?? process.env.FEISHU_VERIFICATION_TOKEN ?? "";
let stopped = false; let stopped = false;
const stopHandlers: Array<() => void> = []; let wsClient: Lark.WSClient | null = null;
const stop = () => { const stop = () => {
stopped = true; stopped = true;
for (const handler of stopHandlers) { if (wsClient) {
handler(); wsClient = null;
} }
}; };
// Register webhook target // Create WebSocket client for receiving events
const unregister = registerFeishuWebhookTarget({ wsClient = new Lark.WSClient({
account, appId: account.appId,
config, appSecret: account.appSecret,
runtime, domain: Lark.Domain.Feishu,
core, loggerLevel: Lark.LoggerLevel.warn,
path, });
encryptKey,
verificationToken, // Create event dispatcher with message handler
mediaMaxMb: effectiveMediaMaxMb, const eventDispatcher = new Lark.EventDispatcher({}).register({
statusSink, "im.message.receive_v1": async (data) => {
if (stopped) return;
statusSink?.({ lastInboundAt: Date.now() });
// Convert SDK event data to our internal type
const event: FeishuMessageEvent = {
sender: data.sender as FeishuMessageEvent["sender"],
message: data.message as FeishuMessageEvent["message"],
};
try {
await processMessageEvent(
event,
account,
config,
runtime,
core,
effectiveMediaMaxMb,
statusSink,
);
} catch (err) {
runtime.error?.(`[${account.accountId}] Feishu event handler failed: ${String(err)}`);
}
},
});
// Start WebSocket connection
wsClient.start({
eventDispatcher,
}); });
stopHandlers.push(unregister);
runtime.log?.( runtime.log?.(
`[feishu] webhook ready: path=${path} encrypted=${Boolean(encryptKey)} token=${Boolean( `[feishu] WebSocket connection started for account=${account.accountId}`,
verificationToken,
)}`,
); );
abortSignal.addEventListener("abort", stop, { once: true }); abortSignal.addEventListener("abort", stop, { once: true });

View File

@ -62,7 +62,28 @@ function inferReceiveIdType(target: string): FeishuReceiveIdType {
} }
/** /**
* Send a text message to a Feishu user or chat. * Build a Feishu interactive card with markdown content.
* Card messages support rich markdown formatting in Feishu.
*/
function buildMarkdownCard(content: string): string {
const card = {
config: {
wide_screen_mode: true,
enable_forward: true,
},
elements: [
{
tag: "markdown",
content,
},
],
};
return JSON.stringify(card);
}
/**
* Send a message to a Feishu user or chat.
* Uses interactive card format for markdown support.
*/ */
export async function sendMessageFeishu( export async function sendMessageFeishu(
to: string, to: string,
@ -81,8 +102,8 @@ export async function sendMessageFeishu(
const receiveIdType = options.receiveIdType ?? inferReceiveIdType(to); const receiveIdType = options.receiveIdType ?? inferReceiveIdType(to);
// Build message content // Build interactive card message content for markdown support
const content = JSON.stringify({ text }); const content = buildMarkdownCard(text);
try { try {
// If replying to a specific message // If replying to a specific message
@ -91,7 +112,7 @@ export async function sendMessageFeishu(
appId, appId,
appSecret, appSecret,
options.replyToMessageId, options.replyToMessageId,
{ msg_type: "text", content }, { msg_type: "interactive", content },
{ fetch: fetcher }, { fetch: fetcher },
); );
@ -101,11 +122,11 @@ export async function sendMessageFeishu(
return { ok: false, error: response.msg ?? "Failed to reply" }; return { ok: false, error: response.msg ?? "Failed to reply" };
} }
// Send new message // Send new message as interactive card
const response = await sendMessage( const response = await sendMessage(
appId, appId,
appSecret, appSecret,
{ receive_id: to.trim(), msg_type: "text", content }, { receive_id: to.trim(), msg_type: "interactive", content },
receiveIdType, receiveIdType,
{ fetch: fetcher }, { fetch: fetcher },
); );

View File

@ -10,12 +10,6 @@ export type FeishuAccountConfig = {
appSecret?: string; appSecret?: string;
/** Path to file containing the app secret. */ /** Path to file containing the app secret. */
appSecretFile?: string; appSecretFile?: string;
/** Encrypt key for event decryption (from Events and Callbacks page). */
encryptKey?: string;
/** Verification token for webhook validation. */
verificationToken?: string;
/** Webhook path for the gateway HTTP server (defaults to /feishu/callback). */
webhookPath?: string;
/** Direct message access policy (default: pairing). */ /** Direct message access policy (default: pairing). */
dmPolicy?: "pairing" | "allowlist" | "open" | "disabled"; dmPolicy?: "pairing" | "allowlist" | "open" | "disabled";
/** Allowlist for DM senders (Feishu open_id or user_id). */ /** Allowlist for DM senders (Feishu open_id or user_id). */
@ -124,39 +118,27 @@ export type FeishuMention = {
tenant_key?: string; tenant_key?: string;
}; };
/** Event header from webhook payload. */
export type FeishuEventHeader = {
event_id: string;
event_type: string;
create_time: string;
token: string;
app_id: string;
tenant_key: string;
};
/** Message receive event (im.message.receive_v1). */ /** Message receive event (im.message.receive_v1). */
export type FeishuMessageEvent = { export type FeishuMessageEvent = {
sender: FeishuSender; sender: FeishuSender;
message: FeishuMessageContent; message: FeishuMessageContent;
}; };
/** Webhook event payload. */ /** Feishu message type. */
export type FeishuWebhookPayload = { export type FeishuMessageType =
schema?: string; | "text"
header?: FeishuEventHeader; | "post"
event?: FeishuMessageEvent | Record<string, unknown>; | "image"
// URL verification challenge | "file"
challenge?: string; | "audio"
token?: string; | "media"
type?: string; | "sticker"
// Encrypted payload | "interactive"; // Card message with markdown support
encrypt?: string;
};
/** Send message request body. */ /** Send message request body. */
export type FeishuSendMessageParams = { export type FeishuSendMessageParams = {
receive_id: string; receive_id: string;
msg_type: "text" | "post" | "image" | "file" | "audio" | "media" | "sticker" | "interactive"; msg_type: FeishuMessageType;
content: string; // JSON string content: string; // JSON string
uuid?: string; uuid?: string;
}; };

View File

@ -9,6 +9,6 @@
] ]
}, },
"peerDependencies": { "peerDependencies": {
"clawdbot": ">=2026.1.24-3" "clawdbot": ">=2026.1.24"
} }
} }

316
pnpm-lock.yaml generated
View File

@ -306,6 +306,10 @@ importers:
extensions/feishu: extensions/feishu:
dependencies: dependencies:
'@larksuiteoapi/node-sdk':
specifier: ^1.56.1
version: 1.56.1
devDependencies:
clawdbot: clawdbot:
specifier: workspace:* specifier: workspace:*
version: link:../.. version: link:../..
@ -363,8 +367,8 @@ importers:
extensions/memory-core: extensions/memory-core:
dependencies: dependencies:
clawdbot: clawdbot:
specifier: workspace:* specifier: '>=2026.1.24'
version: link:../.. version: 2026.1.24(@types/express@5.0.6)(audio-decode@2.2.3)(devtools-protocol@0.0.1561482)(typescript@5.9.3)
extensions/memory-lancedb: extensions/memory-lancedb:
dependencies: dependencies:
@ -1074,105 +1078,89 @@ packages:
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-arm@1.2.4': '@img/sharp-libvips-linux-arm@1.2.4':
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-ppc64@1.2.4': '@img/sharp-libvips-linux-ppc64@1.2.4':
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-riscv64@1.2.4': '@img/sharp-libvips-linux-riscv64@1.2.4':
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-s390x@1.2.4': '@img/sharp-libvips-linux-s390x@1.2.4':
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-x64@1.2.4': '@img/sharp-libvips-linux-x64@1.2.4':
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-libvips-linuxmusl-arm64@1.2.4': '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl]
'@img/sharp-libvips-linuxmusl-x64@1.2.4': '@img/sharp-libvips-linuxmusl-x64@1.2.4':
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
'@img/sharp-linux-arm64@0.34.5': '@img/sharp-linux-arm64@0.34.5':
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-linux-arm@0.34.5': '@img/sharp-linux-arm@0.34.5':
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-linux-ppc64@0.34.5': '@img/sharp-linux-ppc64@0.34.5':
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-linux-riscv64@0.34.5': '@img/sharp-linux-riscv64@0.34.5':
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-linux-s390x@0.34.5': '@img/sharp-linux-s390x@0.34.5':
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-linux-x64@0.34.5': '@img/sharp-linux-x64@0.34.5':
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-linuxmusl-arm64@0.34.5': '@img/sharp-linuxmusl-arm64@0.34.5':
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl]
'@img/sharp-linuxmusl-x64@0.34.5': '@img/sharp-linuxmusl-x64@0.34.5':
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
'@img/sharp-wasm32@0.34.5': '@img/sharp-wasm32@0.34.5':
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
@ -1241,6 +1229,48 @@ packages:
'@kwsites/promise-deferred@1.1.1': '@kwsites/promise-deferred@1.1.1':
resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==}
'@lancedb/lancedb-darwin-arm64@0.23.0':
resolution: {integrity: sha512-8w0sMCNMwBv2kv5+fczGeSVlNOL+BOKChSsO4usM0hMw3PmxasONPctQBsESDuPS8lQ6/AKAQc2HT/ddd5Mg5w==}
engines: {node: '>= 18'}
cpu: [arm64]
os: [darwin]
'@lancedb/lancedb-linux-arm64-gnu@0.23.0':
resolution: {integrity: sha512-+xse2IspO7hbuHT4H62q8Ct00fTojnuBxXp1X1I3/27dDvW8E+/itFiJuTZ0YMaJc7nNr9qh9YFXZ9hZdEmReg==}
engines: {node: '>= 18'}
cpu: [arm64]
os: [linux]
'@lancedb/lancedb-linux-arm64-musl@0.23.0':
resolution: {integrity: sha512-c2UCtGoYjA3oDdw5y3RLK7J2th3rSjYBng+1I03vU9g092y8KATAJO/lV2AtyxSC+esSuyY1dMEaj8ADcXjZAA==}
engines: {node: '>= 18'}
cpu: [arm64]
os: [linux]
'@lancedb/lancedb-linux-x64-gnu@0.23.0':
resolution: {integrity: sha512-OPL7tK3JCTx43ZxvbVs+CljfCer0KrojANQbcJ2V4VAp6XBhKx1sBAlIVGuCrd93pA8UOUP3iHsM7aglPo6rCg==}
engines: {node: '>= 18'}
cpu: [x64]
os: [linux]
'@lancedb/lancedb-linux-x64-musl@0.23.0':
resolution: {integrity: sha512-1ZEoQDwOrKvwPyAG+95/r1NYqX8Ca5bRek8Vr62CzWCEmHd/pFeEGWZ5STrkh+Bt3GLdi2JOivFtRbmuBAJypQ==}
engines: {node: '>= 18'}
cpu: [x64]
os: [linux]
'@lancedb/lancedb-win32-arm64-msvc@0.23.0':
resolution: {integrity: sha512-OuD1mkrgXvijRlXdbx3LvfuorO04FD5qHegnTOWGXh1sIwwrvvhcJAvXUGBNLY4n/lsWvA+xTjtMwRjUitvPKg==}
engines: {node: '>= 18'}
cpu: [arm64]
os: [win32]
'@lancedb/lancedb-win32-x64-msvc@0.23.0':
resolution: {integrity: sha512-5ve1hvVtp8zWxSE9A+MOQaicXl2Rn0ZG/NUaMTjTD3/CQHPKFmtrqDnM5khoPICTj2O2b10F6mn4cUzl5PASgA==}
engines: {node: '>= 18'}
cpu: [x64]
os: [win32]
'@lancedb/lancedb@0.23.0': '@lancedb/lancedb@0.23.0':
resolution: {integrity: sha512-aYrIoEG24AC+wILCL57Ius/Y4yU+xFHDPKLvmjzzN4byAjzeIGF0TC86S5RBt4Ji+dxS7yIWV5Q/gE5/fybIFQ==} resolution: {integrity: sha512-aYrIoEG24AC+wILCL57Ius/Y4yU+xFHDPKLvmjzzN4byAjzeIGF0TC86S5RBt4Ji+dxS7yIWV5Q/gE5/fybIFQ==}
engines: {node: '>= 18'} engines: {node: '>= 18'}
@ -1249,6 +1279,9 @@ packages:
peerDependencies: peerDependencies:
apache-arrow: '>=15.0.0 <=18.1.0' apache-arrow: '>=15.0.0 <=18.1.0'
'@larksuiteoapi/node-sdk@1.56.1':
resolution: {integrity: sha512-/ixtyJnWOmcupKgDXz+6G6qTLMi3cNrR+LGOuq2PMwcJ6hhXTUJNyAF+ADY7ah9OoeDniGU/UJwMb2gqKdxwcA==}
'@line/bot-sdk@10.6.0': '@line/bot-sdk@10.6.0':
resolution: {integrity: sha512-4hSpglL/G/cW2JCcohaYz/BS0uOSJNV9IEYdMm0EiPEvDLayoI2hGq2D86uYPQFD2gvgkyhmzdShpWLG3P5r3w==} resolution: {integrity: sha512-4hSpglL/G/cW2JCcohaYz/BS0uOSJNV9IEYdMm0EiPEvDLayoI2hGq2D86uYPQFD2gvgkyhmzdShpWLG3P5r3w==}
engines: {node: '>=20'} engines: {node: '>=20'}
@ -1320,28 +1353,24 @@ packages:
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
'@mariozechner/clipboard-linux-riscv64-gnu@0.3.0': '@mariozechner/clipboard-linux-riscv64-gnu@0.3.0':
resolution: {integrity: sha512-4BC08CIaOXSSAGRZLEjqJmQfioED8ohAzwt0k2amZPEbH96YKoBNorq5EdwPf5VT+odS0DeyCwhwtxokRLZIvQ==} resolution: {integrity: sha512-4BC08CIaOXSSAGRZLEjqJmQfioED8ohAzwt0k2amZPEbH96YKoBNorq5EdwPf5VT+odS0DeyCwhwtxokRLZIvQ==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
libc: [glibc]
'@mariozechner/clipboard-linux-x64-gnu@0.3.0': '@mariozechner/clipboard-linux-x64-gnu@0.3.0':
resolution: {integrity: sha512-GpNY5Y9nOzr0Vt0Qi5U88qwe6piiIHk44kSMexl8ns90LluN5UTNYmyfi7Xq3/lmPZCpnB2xvBTYbsXCxnopIA==} resolution: {integrity: sha512-GpNY5Y9nOzr0Vt0Qi5U88qwe6piiIHk44kSMexl8ns90LluN5UTNYmyfi7Xq3/lmPZCpnB2xvBTYbsXCxnopIA==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@mariozechner/clipboard-linux-x64-musl@0.3.0': '@mariozechner/clipboard-linux-x64-musl@0.3.0':
resolution: {integrity: sha512-+PnR48/x9GMY5Kh8BLjzHMx6trOegMtxAuqTM9X/bhV3QuW6sLLd7nojDHSGj/ZueK6i0tcQxvOrgNLozVtNDA==} resolution: {integrity: sha512-+PnR48/x9GMY5Kh8BLjzHMx6trOegMtxAuqTM9X/bhV3QuW6sLLd7nojDHSGj/ZueK6i0tcQxvOrgNLozVtNDA==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
'@mariozechner/clipboard-win32-arm64-msvc@0.3.0': '@mariozechner/clipboard-win32-arm64-msvc@0.3.0':
resolution: {integrity: sha512-+dy2vZ1Ph4EYj0cotB+bVUVk/uKl2bh9LOp/zlnFqoCCYDN6sm+L0VyIOPPo3hjoEVdGpHe1MUxp3qG/OLwXgg==} resolution: {integrity: sha512-+dy2vZ1Ph4EYj0cotB+bVUVk/uKl2bh9LOp/zlnFqoCCYDN6sm+L0VyIOPPo3hjoEVdGpHe1MUxp3qG/OLwXgg==}
@ -1442,35 +1471,30 @@ packages:
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
'@napi-rs/canvas-linux-arm64-musl@0.1.88': '@napi-rs/canvas-linux-arm64-musl@0.1.88':
resolution: {integrity: sha512-kYyNrUsHLkoGHBc77u4Unh067GrfiCUMbGHC2+OTxbeWfZkPt2o32UOQkhnSswKd9Fko/wSqqGkY956bIUzruA==} resolution: {integrity: sha512-kYyNrUsHLkoGHBc77u4Unh067GrfiCUMbGHC2+OTxbeWfZkPt2o32UOQkhnSswKd9Fko/wSqqGkY956bIUzruA==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl]
'@napi-rs/canvas-linux-riscv64-gnu@0.1.88': '@napi-rs/canvas-linux-riscv64-gnu@0.1.88':
resolution: {integrity: sha512-HVuH7QgzB0yavYdNZDRyAsn/ejoXB0hn8twwFnOqUbCCdkV+REna7RXjSR7+PdfW0qMQ2YYWsLvVBT5iL/mGpw==} resolution: {integrity: sha512-HVuH7QgzB0yavYdNZDRyAsn/ejoXB0hn8twwFnOqUbCCdkV+REna7RXjSR7+PdfW0qMQ2YYWsLvVBT5iL/mGpw==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
libc: [glibc]
'@napi-rs/canvas-linux-x64-gnu@0.1.88': '@napi-rs/canvas-linux-x64-gnu@0.1.88':
resolution: {integrity: sha512-hvcvKIcPEQrvvJtJnwD35B3qk6umFJ8dFIr8bSymfrSMem0EQsfn1ztys8ETIFndTwdNWJKWluvxztA41ivsEw==} resolution: {integrity: sha512-hvcvKIcPEQrvvJtJnwD35B3qk6umFJ8dFIr8bSymfrSMem0EQsfn1ztys8ETIFndTwdNWJKWluvxztA41ivsEw==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@napi-rs/canvas-linux-x64-musl@0.1.88': '@napi-rs/canvas-linux-x64-musl@0.1.88':
resolution: {integrity: sha512-eSMpGYY2xnZSQ6UxYJ6plDboxq4KeJ4zT5HaVkUnbObNN6DlbJe0Mclh3wifAmquXfrlgTZt6zhHsUgz++AK6g==} resolution: {integrity: sha512-eSMpGYY2xnZSQ6UxYJ6plDboxq4KeJ4zT5HaVkUnbObNN6DlbJe0Mclh3wifAmquXfrlgTZt6zhHsUgz++AK6g==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
'@napi-rs/canvas-win32-arm64-msvc@0.1.88': '@napi-rs/canvas-win32-arm64-msvc@0.1.88':
resolution: {integrity: sha512-qcIFfEgHrchyYqRrxsCeTQgpJZ/GqHiqPcU/Fvw/ARVlQeDX1VyFH+X+0gCR2tca6UJrq96vnW+5o7buCq+erA==} resolution: {integrity: sha512-qcIFfEgHrchyYqRrxsCeTQgpJZ/GqHiqPcU/Fvw/ARVlQeDX1VyFH+X+0gCR2tca6UJrq96vnW+5o7buCq+erA==}
@ -1516,28 +1540,36 @@ packages:
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
cpu: [arm64, x64] cpu: [arm64, x64]
os: [linux] os: [linux]
libc: [glibc]
'@node-llama-cpp/linux-armv7l@3.15.0': '@node-llama-cpp/linux-armv7l@3.15.0':
resolution: {integrity: sha512-ZuZ3q6mejQnEP4o22la7zBv7jNR+IZfgItDm3KjAl04HUXTKJ43HpNwjnf9GyYYd+dEgtoX0MESvWz4RnGH8Jw==} resolution: {integrity: sha512-ZuZ3q6mejQnEP4o22la7zBv7jNR+IZfgItDm3KjAl04HUXTKJ43HpNwjnf9GyYYd+dEgtoX0MESvWz4RnGH8Jw==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
cpu: [arm, x64] cpu: [arm, x64]
os: [linux] os: [linux]
libc: [glibc]
'@node-llama-cpp/linux-x64-cuda-ext@3.15.0':
resolution: {integrity: sha512-wQwgSl7Qm8vH56oBt7IuWWDNNsDECkVMS000C92wl3PkbzjwZFiWzehwa+kF8Lr2BBMiCJNkI5nEabhYH3RN2Q==}
engines: {node: '>=20.0.0'}
cpu: [x64]
os: [linux]
'@node-llama-cpp/linux-x64-cuda@3.15.0':
resolution: {integrity: sha512-mDjyVulCTRYilm9Emm3lDMx7dbI1vzGqk28Pj28shartjERTUu8aUNDYOmVKNMLpUKS1akw7vy0lMF8t4qswxQ==}
engines: {node: '>=20.0.0'}
cpu: [x64]
os: [linux]
'@node-llama-cpp/linux-x64-vulkan@3.15.0': '@node-llama-cpp/linux-x64-vulkan@3.15.0':
resolution: {integrity: sha512-htVIthQKq/rr8v5e7NiVtcHsstqTBAAC50kUymmDMbrzAu6d/EHacCJpNbU57b1UUa1nKN5cBqr6Jr+QqEalMA==} resolution: {integrity: sha512-htVIthQKq/rr8v5e7NiVtcHsstqTBAAC50kUymmDMbrzAu6d/EHacCJpNbU57b1UUa1nKN5cBqr6Jr+QqEalMA==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@node-llama-cpp/linux-x64@3.15.0': '@node-llama-cpp/linux-x64@3.15.0':
resolution: {integrity: sha512-etUuTqSyNefRObqc5+JZviNTkuef2XEtHcQLaamEIWwjI1dj7nTD2YMZPBP7H3M3E55HSIY82vqCQ1bp6ZILiA==} resolution: {integrity: sha512-etUuTqSyNefRObqc5+JZviNTkuef2XEtHcQLaamEIWwjI1dj7nTD2YMZPBP7H3M3E55HSIY82vqCQ1bp6ZILiA==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@node-llama-cpp/mac-arm64-metal@3.15.0': '@node-llama-cpp/mac-arm64-metal@3.15.0':
resolution: {integrity: sha512-3Vkq6bpyQZaIzoaLLP7H2Tt8ty5BS0zxUY2pX0ox2S9P4fp8Au0CCJuUJF4V+EKi+/PTn70A6R1QCkRMfMQJig==} resolution: {integrity: sha512-3Vkq6bpyQZaIzoaLLP7H2Tt8ty5BS0zxUY2pX0ox2S9P4fp8Au0CCJuUJF4V+EKi+/PTn70A6R1QCkRMfMQJig==}
@ -1557,6 +1589,24 @@ packages:
cpu: [arm64, x64] cpu: [arm64, x64]
os: [win32] os: [win32]
'@node-llama-cpp/win-x64-cuda-ext@3.15.0':
resolution: {integrity: sha512-KQoNH9KsVtqGVXaRdPrnHPrg5w3KOM7CfynPmG1m16gmjmDSIspdPg/Dbg6DgHBfkdAzt+duRZEBk8Bg8KbDHw==}
engines: {node: '>=20.0.0'}
cpu: [x64]
os: [win32]
'@node-llama-cpp/win-x64-cuda@3.15.0':
resolution: {integrity: sha512-2Kyu1roDwXwFLaJgGZQISIXP9lCDZtJCx/DRcmrYRHcSUFCzo5ikOuAECyliSSQmRUAvvlRCuD+GrTcegbhojA==}
engines: {node: '>=20.0.0'}
cpu: [x64]
os: [win32]
'@node-llama-cpp/win-x64-vulkan@3.15.0':
resolution: {integrity: sha512-sH+K7lO49WrUvCCC3RPddCBrn2ZQwKCXKL90P/NZicMRgxTPFZEVSU2jXR/bu1K8B+4lNN+z5OEbjSYs7cKEcA==}
engines: {node: '>=20.0.0'}
cpu: [x64]
os: [win32]
'@node-llama-cpp/win-x64@3.15.0': '@node-llama-cpp/win-x64@3.15.0':
resolution: {integrity: sha512-gWhtc8l3HOry5guO46YfFohLQnF0NfL4On0GAO8E27JiYYxHO9nHSCfFif4+U03+FfHquZXL0znJ1qPVOiwOPw==} resolution: {integrity: sha512-gWhtc8l3HOry5guO46YfFohLQnF0NfL4On0GAO8E27JiYYxHO9nHSCfFif4+U03+FfHquZXL0znJ1qPVOiwOPw==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
@ -1867,25 +1917,21 @@ packages:
resolution: {integrity: sha512-GubkQeQT5d3B/Jx/IiR7NMkSmXrCZcVI0BPh1i7mpFi8HgD1hQ/LbhiBKAMsMqs5bbugdQOgBEl8bOhe8JhW1g==} resolution: {integrity: sha512-GubkQeQT5d3B/Jx/IiR7NMkSmXrCZcVI0BPh1i7mpFi8HgD1hQ/LbhiBKAMsMqs5bbugdQOgBEl8bOhe8JhW1g==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
'@oxfmt/linux-arm64-musl@0.26.0': '@oxfmt/linux-arm64-musl@0.26.0':
resolution: {integrity: sha512-OEypUwK69bFPj+aa3/LYCnlIUPgoOLu//WNcriwpnWNmt47808Ht7RJSg+MNK8a7pSZHpXJ5/E6CRK/OTwFdaQ==} resolution: {integrity: sha512-OEypUwK69bFPj+aa3/LYCnlIUPgoOLu//WNcriwpnWNmt47808Ht7RJSg+MNK8a7pSZHpXJ5/E6CRK/OTwFdaQ==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl]
'@oxfmt/linux-x64-gnu@0.26.0': '@oxfmt/linux-x64-gnu@0.26.0':
resolution: {integrity: sha512-xO6iEW2bC6ZHyOTPmPWrg/nM6xgzyRPaS84rATy6F8d79wz69LdRdJ3l/PXlkqhi7XoxhvX4ExysA0Nf10ZZEQ==} resolution: {integrity: sha512-xO6iEW2bC6ZHyOTPmPWrg/nM6xgzyRPaS84rATy6F8d79wz69LdRdJ3l/PXlkqhi7XoxhvX4ExysA0Nf10ZZEQ==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@oxfmt/linux-x64-musl@0.26.0': '@oxfmt/linux-x64-musl@0.26.0':
resolution: {integrity: sha512-Z3KuZFC+MIuAyFCXBHY71kCsdRq1ulbsbzTe71v+hrEv7zVBn6yzql+/AZcgfIaKzWO9OXNuz5WWLWDmVALwow==} resolution: {integrity: sha512-Z3KuZFC+MIuAyFCXBHY71kCsdRq1ulbsbzTe71v+hrEv7zVBn6yzql+/AZcgfIaKzWO9OXNuz5WWLWDmVALwow==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
'@oxfmt/win32-arm64@0.26.0': '@oxfmt/win32-arm64@0.26.0':
resolution: {integrity: sha512-3zRbqwVWK1mDhRhTknlQFpRFL9GhEB5GfU6U7wawnuEwpvi39q91kJ+SRJvJnhyPCARkjZBd1V8XnweN5IFd1g==} resolution: {integrity: sha512-3zRbqwVWK1mDhRhTknlQFpRFL9GhEB5GfU6U7wawnuEwpvi39q91kJ+SRJvJnhyPCARkjZBd1V8XnweN5IFd1g==}
@ -1941,25 +1987,21 @@ packages:
resolution: {integrity: sha512-Fow7H84Bs8XxuaK1yfSEWBC8HI7rfEQB9eR2A0J61un1WgCas7jNrt1HbT6+p6KmUH2bhR+r/RDu/6JFAvvj4g==} resolution: {integrity: sha512-Fow7H84Bs8XxuaK1yfSEWBC8HI7rfEQB9eR2A0J61un1WgCas7jNrt1HbT6+p6KmUH2bhR+r/RDu/6JFAvvj4g==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
'@oxlint/linux-arm64-musl@1.41.0': '@oxlint/linux-arm64-musl@1.41.0':
resolution: {integrity: sha512-WoRRDNwgP5W3rjRh42Zdx8ferYnqpKoYCv2QQLenmdrLjRGYwAd52uywfkcS45mKEWHeY1RPwPkYCSROXiGb2w==} resolution: {integrity: sha512-WoRRDNwgP5W3rjRh42Zdx8ferYnqpKoYCv2QQLenmdrLjRGYwAd52uywfkcS45mKEWHeY1RPwPkYCSROXiGb2w==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl]
'@oxlint/linux-x64-gnu@1.41.0': '@oxlint/linux-x64-gnu@1.41.0':
resolution: {integrity: sha512-75k3CKj3fOc/a/2aSgO81s3HsTZOFROthPJ+UI2Oatic1LhvH6eKjKfx3jDDyVpzeDS2qekPlc/y3N33iZz5Og==} resolution: {integrity: sha512-75k3CKj3fOc/a/2aSgO81s3HsTZOFROthPJ+UI2Oatic1LhvH6eKjKfx3jDDyVpzeDS2qekPlc/y3N33iZz5Og==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@oxlint/linux-x64-musl@1.41.0': '@oxlint/linux-x64-musl@1.41.0':
resolution: {integrity: sha512-8r82eBwGPoAPn67ZvdxTlX/Z3gVb+ZtN6nbkyFzwwHWAh8yGutX+VBcVkyrePSl6XgBP4QAaddPnHmkvJjqY0g==} resolution: {integrity: sha512-8r82eBwGPoAPn67ZvdxTlX/Z3gVb+ZtN6nbkyFzwwHWAh8yGutX+VBcVkyrePSl6XgBP4QAaddPnHmkvJjqY0g==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
'@oxlint/win32-arm64@1.41.0': '@oxlint/win32-arm64@1.41.0':
resolution: {integrity: sha512-aK+DAcckQsNCOXKruatyYuY/ROjNiRejQB1PeJtkZwM21+8rV9ODYbvKNvt0pW+YCws7svftBSFMCpl3ke2unw==} resolution: {integrity: sha512-aK+DAcckQsNCOXKruatyYuY/ROjNiRejQB1PeJtkZwM21+8rV9ODYbvKNvt0pW+YCws7svftBSFMCpl3ke2unw==}
@ -2031,28 +2073,24 @@ packages:
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
'@reflink/reflink-linux-arm64-musl@0.1.19': '@reflink/reflink-linux-arm64-musl@0.1.19':
resolution: {integrity: sha512-37iO/Dp6m5DDaC2sf3zPtx/hl9FV3Xze4xoYidrxxS9bgP3S8ALroxRK6xBG/1TtfXKTvolvp+IjrUU6ujIGmA==} resolution: {integrity: sha512-37iO/Dp6m5DDaC2sf3zPtx/hl9FV3Xze4xoYidrxxS9bgP3S8ALroxRK6xBG/1TtfXKTvolvp+IjrUU6ujIGmA==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl]
'@reflink/reflink-linux-x64-gnu@0.1.19': '@reflink/reflink-linux-x64-gnu@0.1.19':
resolution: {integrity: sha512-jbI8jvuYCaA3MVUdu8vLoLAFqC+iNMpiSuLbxlAgg7x3K5bsS8nOpTRnkLF7vISJ+rVR8W+7ThXlXlUQ93ulkw==} resolution: {integrity: sha512-jbI8jvuYCaA3MVUdu8vLoLAFqC+iNMpiSuLbxlAgg7x3K5bsS8nOpTRnkLF7vISJ+rVR8W+7ThXlXlUQ93ulkw==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@reflink/reflink-linux-x64-musl@0.1.19': '@reflink/reflink-linux-x64-musl@0.1.19':
resolution: {integrity: sha512-e9FBWDe+lv7QKAwtKOt6A2W/fyy/aEEfr0g6j/hWzvQcrzHCsz07BNQYlNOjTfeytrtLU7k449H1PI95jA4OjQ==} resolution: {integrity: sha512-e9FBWDe+lv7QKAwtKOt6A2W/fyy/aEEfr0g6j/hWzvQcrzHCsz07BNQYlNOjTfeytrtLU7k449H1PI95jA4OjQ==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
'@reflink/reflink-win32-arm64-msvc@0.1.19': '@reflink/reflink-win32-arm64-msvc@0.1.19':
resolution: {integrity: sha512-09PxnVIQcd+UOn4WAW73WU6PXL7DwGS6wPlkMhMg2zlHHG65F3vHepOw06HFCq+N42qkaNAc8AKIabWvtk6cIQ==} resolution: {integrity: sha512-09PxnVIQcd+UOn4WAW73WU6PXL7DwGS6wPlkMhMg2zlHHG65F3vHepOw06HFCq+N42qkaNAc8AKIabWvtk6cIQ==}
@ -2105,28 +2143,24 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
'@rolldown/binding-linux-arm64-musl@1.0.0-rc.1': '@rolldown/binding-linux-arm64-musl@1.0.0-rc.1':
resolution: {integrity: sha512-UvApLEGholmxw/HIwmUnLq3CwdydbhaHHllvWiCTNbyGom7wTwOtz5OAQbAKZYyiEOeIXZNPkM7nA4Dtng7CLw==} resolution: {integrity: sha512-UvApLEGholmxw/HIwmUnLq3CwdydbhaHHllvWiCTNbyGom7wTwOtz5OAQbAKZYyiEOeIXZNPkM7nA4Dtng7CLw==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl]
'@rolldown/binding-linux-x64-gnu@1.0.0-rc.1': '@rolldown/binding-linux-x64-gnu@1.0.0-rc.1':
resolution: {integrity: sha512-uVctNgZHiGnJx5Fij7wHLhgw4uyZBVi6mykeWKOqE7bVy9Hcxn0fM/IuqdMwk6hXlaf9fFShDTFz2+YejP+x0A==} resolution: {integrity: sha512-uVctNgZHiGnJx5Fij7wHLhgw4uyZBVi6mykeWKOqE7bVy9Hcxn0fM/IuqdMwk6hXlaf9fFShDTFz2+YejP+x0A==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@rolldown/binding-linux-x64-musl@1.0.0-rc.1': '@rolldown/binding-linux-x64-musl@1.0.0-rc.1':
resolution: {integrity: sha512-T6Eg0xWwcxd/MzBcuv4Z37YVbUbJxy5cMNnbIt/Yr99wFwli30O4BPlY8hKeGyn6lWNtU0QioBS46lVzDN38bg==} resolution: {integrity: sha512-T6Eg0xWwcxd/MzBcuv4Z37YVbUbJxy5cMNnbIt/Yr99wFwli30O4BPlY8hKeGyn6lWNtU0QioBS46lVzDN38bg==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
'@rolldown/binding-openharmony-arm64@1.0.0-rc.1': '@rolldown/binding-openharmony-arm64@1.0.0-rc.1':
resolution: {integrity: sha512-PuGZVS2xNJyLADeh2F04b+Cz4NwvpglbtWACgrDOa5YDTEHKwmiTDjoD5eZ9/ptXtcpeFrMqD2H4Zn33KAh1Eg==} resolution: {integrity: sha512-PuGZVS2xNJyLADeh2F04b+Cz4NwvpglbtWACgrDOa5YDTEHKwmiTDjoD5eZ9/ptXtcpeFrMqD2H4Zn33KAh1Eg==}
@ -2188,79 +2222,66 @@ packages:
resolution: {integrity: sha512-YeGUhkN1oA+iSPzzhEjVPS29YbViOr8s4lSsFaZKLHswgqP911xx25fPOyE9+khmN6W4VeM0aevbDp4kkEoHiA==} resolution: {integrity: sha512-YeGUhkN1oA+iSPzzhEjVPS29YbViOr8s4lSsFaZKLHswgqP911xx25fPOyE9+khmN6W4VeM0aevbDp4kkEoHiA==}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm-musleabihf@4.55.3': '@rollup/rollup-linux-arm-musleabihf@4.55.3':
resolution: {integrity: sha512-eo0iOIOvcAlWB3Z3eh8pVM8hZ0oVkK3AjEM9nSrkSug2l15qHzF3TOwT0747omI6+CJJvl7drwZepT+re6Fy/w==} resolution: {integrity: sha512-eo0iOIOvcAlWB3Z3eh8pVM8hZ0oVkK3AjEM9nSrkSug2l15qHzF3TOwT0747omI6+CJJvl7drwZepT+re6Fy/w==}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
libc: [musl]
'@rollup/rollup-linux-arm64-gnu@4.55.3': '@rollup/rollup-linux-arm64-gnu@4.55.3':
resolution: {integrity: sha512-DJay3ep76bKUDImmn//W5SvpjRN5LmK/ntWyeJs/dcnwiiHESd3N4uteK9FDLf0S0W8E6Y0sVRXpOCoQclQqNg==} resolution: {integrity: sha512-DJay3ep76bKUDImmn//W5SvpjRN5LmK/ntWyeJs/dcnwiiHESd3N4uteK9FDLf0S0W8E6Y0sVRXpOCoQclQqNg==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm64-musl@4.55.3': '@rollup/rollup-linux-arm64-musl@4.55.3':
resolution: {integrity: sha512-BKKWQkY2WgJ5MC/ayvIJTHjy0JUGb5efaHCUiG/39sSUvAYRBaO3+/EK0AZT1RF3pSj86O24GLLik9mAYu0IJg==} resolution: {integrity: sha512-BKKWQkY2WgJ5MC/ayvIJTHjy0JUGb5efaHCUiG/39sSUvAYRBaO3+/EK0AZT1RF3pSj86O24GLLik9mAYu0IJg==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl]
'@rollup/rollup-linux-loong64-gnu@4.55.3': '@rollup/rollup-linux-loong64-gnu@4.55.3':
resolution: {integrity: sha512-Q9nVlWtKAG7ISW80OiZGxTr6rYtyDSkauHUtvkQI6TNOJjFvpj4gcH+KaJihqYInnAzEEUetPQubRwHef4exVg==} resolution: {integrity: sha512-Q9nVlWtKAG7ISW80OiZGxTr6rYtyDSkauHUtvkQI6TNOJjFvpj4gcH+KaJihqYInnAzEEUetPQubRwHef4exVg==}
cpu: [loong64] cpu: [loong64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-loong64-musl@4.55.3': '@rollup/rollup-linux-loong64-musl@4.55.3':
resolution: {integrity: sha512-2H5LmhzrpC4fFRNwknzmmTvvyJPHwESoJgyReXeFoYYuIDfBhP29TEXOkCJE/KxHi27mj7wDUClNq78ue3QEBQ==} resolution: {integrity: sha512-2H5LmhzrpC4fFRNwknzmmTvvyJPHwESoJgyReXeFoYYuIDfBhP29TEXOkCJE/KxHi27mj7wDUClNq78ue3QEBQ==}
cpu: [loong64] cpu: [loong64]
os: [linux] os: [linux]
libc: [musl]
'@rollup/rollup-linux-ppc64-gnu@4.55.3': '@rollup/rollup-linux-ppc64-gnu@4.55.3':
resolution: {integrity: sha512-9S542V0ie9LCTznPYlvaeySwBeIEa7rDBgLHKZ5S9DBgcqdJYburabm8TqiqG6mrdTzfV5uttQRHcbKff9lWtA==} resolution: {integrity: sha512-9S542V0ie9LCTznPYlvaeySwBeIEa7rDBgLHKZ5S9DBgcqdJYburabm8TqiqG6mrdTzfV5uttQRHcbKff9lWtA==}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-ppc64-musl@4.55.3': '@rollup/rollup-linux-ppc64-musl@4.55.3':
resolution: {integrity: sha512-ukxw+YH3XXpcezLgbJeasgxyTbdpnNAkrIlFGDl7t+pgCxZ89/6n1a+MxlY7CegU+nDgrgdqDelPRNQ/47zs0g==} resolution: {integrity: sha512-ukxw+YH3XXpcezLgbJeasgxyTbdpnNAkrIlFGDl7t+pgCxZ89/6n1a+MxlY7CegU+nDgrgdqDelPRNQ/47zs0g==}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
libc: [musl]
'@rollup/rollup-linux-riscv64-gnu@4.55.3': '@rollup/rollup-linux-riscv64-gnu@4.55.3':
resolution: {integrity: sha512-Iauw9UsTTvlF++FhghFJjqYxyXdggXsOqGpFBylaRopVpcbfyIIsNvkf9oGwfgIcf57z3m8+/oSYTo6HutBFNw==} resolution: {integrity: sha512-Iauw9UsTTvlF++FhghFJjqYxyXdggXsOqGpFBylaRopVpcbfyIIsNvkf9oGwfgIcf57z3m8+/oSYTo6HutBFNw==}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-riscv64-musl@4.55.3': '@rollup/rollup-linux-riscv64-musl@4.55.3':
resolution: {integrity: sha512-3OqKAHSEQXKdq9mQ4eajqUgNIK27VZPW3I26EP8miIzuKzCJ3aW3oEn2pzF+4/Hj/Moc0YDsOtBgT5bZ56/vcA==} resolution: {integrity: sha512-3OqKAHSEQXKdq9mQ4eajqUgNIK27VZPW3I26EP8miIzuKzCJ3aW3oEn2pzF+4/Hj/Moc0YDsOtBgT5bZ56/vcA==}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
libc: [musl]
'@rollup/rollup-linux-s390x-gnu@4.55.3': '@rollup/rollup-linux-s390x-gnu@4.55.3':
resolution: {integrity: sha512-0CM8dSVzVIaqMcXIFej8zZrSFLnGrAE8qlNbbHfTw1EEPnFTg1U1ekI0JdzjPyzSfUsHWtodilQQG/RA55berA==} resolution: {integrity: sha512-0CM8dSVzVIaqMcXIFej8zZrSFLnGrAE8qlNbbHfTw1EEPnFTg1U1ekI0JdzjPyzSfUsHWtodilQQG/RA55berA==}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-gnu@4.55.3': '@rollup/rollup-linux-x64-gnu@4.55.3':
resolution: {integrity: sha512-+fgJE12FZMIgBaKIAGd45rxf+5ftcycANJRWk8Vz0NnMTM5rADPGuRFTYar+Mqs560xuART7XsX2lSACa1iOmQ==} resolution: {integrity: sha512-+fgJE12FZMIgBaKIAGd45rxf+5ftcycANJRWk8Vz0NnMTM5rADPGuRFTYar+Mqs560xuART7XsX2lSACa1iOmQ==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-musl@4.55.3': '@rollup/rollup-linux-x64-musl@4.55.3':
resolution: {integrity: sha512-tMD7NnbAolWPzQlJQJjVFh/fNH3K/KnA7K8gv2dJWCwwnaK6DFCYST1QXYWfu5V0cDwarWC8Sf/cfMHniNq21A==} resolution: {integrity: sha512-tMD7NnbAolWPzQlJQJjVFh/fNH3K/KnA7K8gv2dJWCwwnaK6DFCYST1QXYWfu5V0cDwarWC8Sf/cfMHniNq21A==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
'@rollup/rollup-openbsd-x64@4.55.3': '@rollup/rollup-openbsd-x64@4.55.3':
resolution: {integrity: sha512-u5KsqxOxjEeIbn7bUK1MPM34jrnPwjeqgyin4/N6e/KzXKfpE9Mi0nCxcQjaM9lLmPcHmn/xx1yOjgTMtu1jWQ==} resolution: {integrity: sha512-u5KsqxOxjEeIbn7bUK1MPM34jrnPwjeqgyin4/N6e/KzXKfpE9Mi0nCxcQjaM9lLmPcHmn/xx1yOjgTMtu1jWQ==}
@ -2973,6 +2994,9 @@ packages:
aws4@1.13.2: aws4@1.13.2:
resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==}
axios@0.27.2:
resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
axios@1.13.2: axios@1.13.2:
resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==}
@ -3116,6 +3140,11 @@ packages:
class-variance-authority@0.7.1: class-variance-authority@0.7.1:
resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
clawdbot@2026.1.24:
resolution: {integrity: sha512-foszbNXzk743kQBx2Nfc2KNlStZyBAVAYLQJ+KaONh009r8oB1a74kQ8wTnKX+SDNaQ9MvaE9tOisVUi+H3F+Q==}
engines: {node: '>=22.12.0'}
hasBin: true
cli-cursor@5.0.0: cli-cursor@5.0.0:
resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==}
engines: {node: '>=18'} engines: {node: '>=18'}
@ -3983,28 +4012,24 @@ packages:
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
lightningcss-linux-arm64-musl@1.30.2: lightningcss-linux-arm64-musl@1.30.2:
resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl]
lightningcss-linux-x64-gnu@1.30.2: lightningcss-linux-x64-gnu@1.30.2:
resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
lightningcss-linux-x64-musl@1.30.2: lightningcss-linux-x64-musl@1.30.2:
resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
lightningcss-win32-arm64-msvc@1.30.2: lightningcss-win32-arm64-msvc@1.30.2:
resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==}
@ -4055,6 +4080,9 @@ packages:
lodash.debounce@4.0.8: lodash.debounce@4.0.8:
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
lodash.identity@3.0.0:
resolution: {integrity: sha512-AupTIzdLQxJS5wIYUQlgGyk2XRTfGXA+MCghDHqZk0pzUNYvd3EESS6dkChNauNYVIutcb0dfHw1ri9Q1yPV8Q==}
lodash.includes@4.3.0: lodash.includes@4.3.0:
resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==}
@ -4073,9 +4101,15 @@ packages:
lodash.isstring@4.0.1: lodash.isstring@4.0.1:
resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==}
lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
lodash.once@4.1.1: lodash.once@4.1.1:
resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==}
lodash.pickby@4.6.0:
resolution: {integrity: sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==}
lodash@4.17.23: lodash@4.17.23:
resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==}
@ -6694,10 +6728,53 @@ snapshots:
'@kwsites/promise-deferred@1.1.1': '@kwsites/promise-deferred@1.1.1':
optional: true optional: true
'@lancedb/lancedb-darwin-arm64@0.23.0':
optional: true
'@lancedb/lancedb-linux-arm64-gnu@0.23.0':
optional: true
'@lancedb/lancedb-linux-arm64-musl@0.23.0':
optional: true
'@lancedb/lancedb-linux-x64-gnu@0.23.0':
optional: true
'@lancedb/lancedb-linux-x64-musl@0.23.0':
optional: true
'@lancedb/lancedb-win32-arm64-msvc@0.23.0':
optional: true
'@lancedb/lancedb-win32-x64-msvc@0.23.0':
optional: true
'@lancedb/lancedb@0.23.0(apache-arrow@18.1.0)': '@lancedb/lancedb@0.23.0(apache-arrow@18.1.0)':
dependencies: dependencies:
apache-arrow: 18.1.0 apache-arrow: 18.1.0
reflect-metadata: 0.2.2 reflect-metadata: 0.2.2
optionalDependencies:
'@lancedb/lancedb-darwin-arm64': 0.23.0
'@lancedb/lancedb-linux-arm64-gnu': 0.23.0
'@lancedb/lancedb-linux-arm64-musl': 0.23.0
'@lancedb/lancedb-linux-x64-gnu': 0.23.0
'@lancedb/lancedb-linux-x64-musl': 0.23.0
'@lancedb/lancedb-win32-arm64-msvc': 0.23.0
'@lancedb/lancedb-win32-x64-msvc': 0.23.0
'@larksuiteoapi/node-sdk@1.56.1':
dependencies:
axios: 0.27.2
lodash.identity: 3.0.0
lodash.merge: 4.6.2
lodash.pickby: 4.6.0
protobufjs: 7.5.4
qs: 6.14.1
ws: 8.19.0
transitivePeerDependencies:
- bufferutil
- debug
- utf-8-validate
'@line/bot-sdk@10.6.0': '@line/bot-sdk@10.6.0':
dependencies: dependencies:
@ -7006,6 +7083,12 @@ snapshots:
'@node-llama-cpp/linux-armv7l@3.15.0': '@node-llama-cpp/linux-armv7l@3.15.0':
optional: true optional: true
'@node-llama-cpp/linux-x64-cuda-ext@3.15.0':
optional: true
'@node-llama-cpp/linux-x64-cuda@3.15.0':
optional: true
'@node-llama-cpp/linux-x64-vulkan@3.15.0': '@node-llama-cpp/linux-x64-vulkan@3.15.0':
optional: true optional: true
@ -7021,6 +7104,15 @@ snapshots:
'@node-llama-cpp/win-arm64@3.15.0': '@node-llama-cpp/win-arm64@3.15.0':
optional: true optional: true
'@node-llama-cpp/win-x64-cuda-ext@3.15.0':
optional: true
'@node-llama-cpp/win-x64-cuda@3.15.0':
optional: true
'@node-llama-cpp/win-x64-vulkan@3.15.0':
optional: true
'@node-llama-cpp/win-x64@3.15.0': '@node-llama-cpp/win-x64@3.15.0':
optional: true optional: true
@ -8645,6 +8737,13 @@ snapshots:
aws4@1.13.2: {} aws4@1.13.2: {}
axios@0.27.2:
dependencies:
follow-redirects: 1.15.11(debug@4.4.3)
form-data: 4.0.5
transitivePeerDependencies:
- debug
axios@1.13.2(debug@4.4.3): axios@1.13.2(debug@4.4.3):
dependencies: dependencies:
follow-redirects: 1.15.11(debug@4.4.3) follow-redirects: 1.15.11(debug@4.4.3)
@ -8814,6 +8913,84 @@ snapshots:
dependencies: dependencies:
clsx: 2.1.1 clsx: 2.1.1
clawdbot@2026.1.24(@types/express@5.0.6)(audio-decode@2.2.3)(devtools-protocol@0.0.1561482)(typescript@5.9.3):
dependencies:
'@agentclientprotocol/sdk': 0.13.1(zod@4.3.6)
'@aws-sdk/client-bedrock': 3.975.0
'@buape/carbon': 0.14.0(hono@4.11.4)
'@clack/prompts': 0.11.0
'@grammyjs/runner': 2.0.3(grammy@1.39.3)
'@grammyjs/transformer-throttler': 1.2.1(grammy@1.39.3)
'@homebridge/ciao': 1.3.4
'@line/bot-sdk': 10.6.0
'@lydell/node-pty': 1.2.0-beta.3
'@mariozechner/pi-agent-core': 0.49.3(ws@8.19.0)(zod@4.3.6)
'@mariozechner/pi-ai': 0.49.3(ws@8.19.0)(zod@4.3.6)
'@mariozechner/pi-coding-agent': 0.49.3(ws@8.19.0)(zod@4.3.6)
'@mariozechner/pi-tui': 0.49.3
'@mozilla/readability': 0.6.0
'@sinclair/typebox': 0.34.47
'@slack/bolt': 4.6.0(@types/express@5.0.6)
'@slack/web-api': 7.13.0
'@whiskeysockets/baileys': 7.0.0-rc.9(audio-decode@2.2.3)(sharp@0.34.5)
ajv: 8.17.1
body-parser: 2.2.2
chalk: 5.6.2
chokidar: 5.0.0
chromium-bidi: 13.0.1(devtools-protocol@0.0.1561482)
cli-highlight: 2.1.11
commander: 14.0.2
croner: 9.1.0
detect-libc: 2.1.2
discord-api-types: 0.38.37
dotenv: 17.2.3
express: 5.2.1
file-type: 21.3.0
grammy: 1.39.3
hono: 4.11.4
jiti: 2.6.1
json5: 2.2.3
jszip: 3.10.1
linkedom: 0.18.12
long: 5.3.2
markdown-it: 14.1.0
node-edge-tts: 1.2.9
osc-progress: 0.3.0
pdfjs-dist: 5.4.530
playwright-core: 1.58.0
proper-lockfile: 4.1.2
qrcode-terminal: 0.12.0
sharp: 0.34.5
sqlite-vec: 0.1.7-alpha.2
tar: 7.5.4
tslog: 4.10.2
undici: 7.19.0
ws: 8.19.0
yaml: 2.8.2
zod: 4.3.6
optionalDependencies:
'@napi-rs/canvas': 0.1.88
node-llama-cpp: 3.15.0(typescript@5.9.3)
transitivePeerDependencies:
- '@discordjs/opus'
- '@modelcontextprotocol/sdk'
- '@types/express'
- audio-decode
- aws-crt
- bufferutil
- canvas
- debug
- devtools-protocol
- encoding
- ffmpeg-static
- jimp
- link-preview-js
- node-opus
- opusscript
- supports-color
- typescript
- utf-8-validate
cli-cursor@5.0.0: cli-cursor@5.0.0:
dependencies: dependencies:
restore-cursor: 5.1.0 restore-cursor: 5.1.0
@ -9865,6 +10042,8 @@ snapshots:
lodash.debounce@4.0.8: lodash.debounce@4.0.8:
optional: true optional: true
lodash.identity@3.0.0: {}
lodash.includes@4.3.0: {} lodash.includes@4.3.0: {}
lodash.isboolean@3.0.3: {} lodash.isboolean@3.0.3: {}
@ -9877,8 +10056,12 @@ snapshots:
lodash.isstring@4.0.1: {} lodash.isstring@4.0.1: {}
lodash.merge@4.6.2: {}
lodash.once@4.1.1: {} lodash.once@4.1.1: {}
lodash.pickby@4.6.0: {}
lodash@4.17.23: {} lodash@4.17.23: {}
log-symbols@6.0.0: log-symbols@6.0.0:
@ -10163,11 +10346,16 @@ snapshots:
'@node-llama-cpp/linux-arm64': 3.15.0 '@node-llama-cpp/linux-arm64': 3.15.0
'@node-llama-cpp/linux-armv7l': 3.15.0 '@node-llama-cpp/linux-armv7l': 3.15.0
'@node-llama-cpp/linux-x64': 3.15.0 '@node-llama-cpp/linux-x64': 3.15.0
'@node-llama-cpp/linux-x64-cuda': 3.15.0
'@node-llama-cpp/linux-x64-cuda-ext': 3.15.0
'@node-llama-cpp/linux-x64-vulkan': 3.15.0 '@node-llama-cpp/linux-x64-vulkan': 3.15.0
'@node-llama-cpp/mac-arm64-metal': 3.15.0 '@node-llama-cpp/mac-arm64-metal': 3.15.0
'@node-llama-cpp/mac-x64': 3.15.0 '@node-llama-cpp/mac-x64': 3.15.0
'@node-llama-cpp/win-arm64': 3.15.0 '@node-llama-cpp/win-arm64': 3.15.0
'@node-llama-cpp/win-x64': 3.15.0 '@node-llama-cpp/win-x64': 3.15.0
'@node-llama-cpp/win-x64-cuda': 3.15.0
'@node-llama-cpp/win-x64-cuda-ext': 3.15.0
'@node-llama-cpp/win-x64-vulkan': 3.15.0
typescript: 5.9.3 typescript: 5.9.3
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color