npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@krischoichoi/channel-lark

v0.6.1

Published

Lark / Feishu channel adapter for DeepSeek Harness (threads, editable card streaming, edit strategy)

Readme

@krischoichoi/channel-lark

Lark / Feishu / 飞书 channel adapter for DeepSeek Harness.

Maps Lark to the stable Channel Contract through the official @larksuiteoapi/node-sdk only:

  • Inbound — WSClient + EventDispatcher (WebSocket long-connection): im.message.receive_v1 and card.action.trigger.
  • Outbound — the official OpenAPI client: im.v1.message.create / patch, image/file uploads, and CardKit 2.0 card entities with native streaming (cardkit.v1.card.create → cardElement.content → card.settings).

There is no self-hosted gateway and no legacy transport. Interactive cards use Card JSON 2.0 only (buttons are direct body.elements with behaviors[].value; no tag: "action" container and no lark_md).

Install

pnpm add @krischoichoi/channel-lark

Or install the whole bundle:

npx @deepseek-ai/dsh plugin --profile web add -w @krischoichoi/dsh-channels@latest

Configuration

- id: channels-lark
  name: '@krischoichoi/channel-lark'
  inject: [channels, credentials, channelControl]
  config:
    enabled: true
    accountId: main
    upstream:
      mode: sdk          # fixed — the official SDK is the only upstream driver
      appId: "cli_xxx"   # AppId(非机密)
      domain: feishu     # feishu(国内)| lark(海外)
      # appSecretRef 默认 DSH_CHANNEL_LARK_MAIN_APP_SECRET
      # 真实 AppSecret 只存 ctx.credentials
    card:
      createOnFirstDelta: true
      typingIndicator: true

The AppSecret is resolved through ctx.credentials at startup and injected as deps.appSecret; it is never written to profile config.

Config governance: only upstream.mode: sdk and the credential reference upstream.appSecretRef are supported. Plaintext upstream.appSecret and the former gateway settings are not part of the configuration contract.

Streaming

Lark uses edit streaming over CardKit 2.0 native streaming (the official "打字机" typewriter flow — never im.v1.message.patch pseudo-streaming):

  1. cardkit.v1.card.create creates a Card JSON 2.0 entity with streaming_mode: true and a stable element_id;
  2. im.v1.message.create sends the card reference ({ type: "card", data: { card_id } });
  3. every streamed delta replaces the markdown element's full content via cardkit.v1.cardElement.content with a monotonically increasing sequence and a stable uuid;
  4. finish() / fail() close the stream by setting streaming_mode: false (and the final summary) through cardkit.v1.card.settings.

When a single markdown element approaches the platform's ~30,000-char cap the handle rolls over into a fresh card (chunkIds records every sent card).

Capabilities

| Capability | Value | | --- | --- | | text / image / file / audio | ✅ | | markdown / cards / reactions / threads | ✅ | | interactive buttons | ✅ (card.action.trigger, Card JSON 2.0) | | video | ❌ | | streaming | edit (CardKit 2.0 native streaming) |

Upstream

| Field | Value | | --- | --- | | SDK | @larksuiteoapi/node-sdk | | Tested version | 1.73.1 | | Status | tested (offline-tested: contract + fixture + SDK-mode suites) |

Live gate status: LIVE-REQUIRED. status: tested reflects the offline Channel Contract + fixture + official-SDK offline suites only. Real-app permission / event subscription / message & card send behavior must still be verified live (see §8 of the alignment plan) before the adapter may be claimed live-tested.

Development

pnpm --filter @krischoichoi/channel-lark build
pnpm --filter @krischoichoi/channel-lark typecheck
pnpm --filter @krischoichoi/channel-lark test

Related

License

MIT