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

dsh-daily-calendar

v0.1.0

Published

Calendar read + controlled write plugin for the DeepSeek Harness (developer preview)

Readme

calendar

dsh(DeepSeek Harness)日历插件:读取优先的日历访问——统一 CalendarProvider 接口下接 Google Calendar(API v3)与通用 CalDAV(iCloud / Fastmail / Nextcloud 等,Basic Auth / App 专用密码),提供列表、详情、空闲时段查询三个只读工具;创建/修改事件属高风险写操作,需在配置中显式开启 writesEnabled 才会注册。

状态:developer preview。已通过 tsc --noEmit 类型检查(对齐 @deepseek-ai/[email protected] 的工具签名)与 56 例纯函数/注入替身单测;尚未在真实 dsh 运行时与真实日历账号中验证,手动验证步骤见下文。

功能

Provider 分层

工具层只面向统一的 CalendarProvider 接口(listEvents / getEvent / freeBusy / createEvent / updateEvent),服务商差异全部下沉到实现:

  • google:Google Calendar API v3。singleEvents=true 让服务端展开循环事件;freeBusy 用官方 freeBusy 接口。OAuth2 采用务实方案(见下文「Google token 获取」):用户自备 access token,可选配置 refresh 三件套实现过期自动刷新。
  • caldav:通用 CalDAV(RFC 4791)。读取用 REPORT calendar-query + 自研轻量 ICS 解析器(折行展开、TEXT 转义、UTC/浮动/TZID/纯日期四种时间格式);freeBusy 由事件列表推导(所有 CalDAV 服务器都支持 calendar-query,而 free-busy-query 支持参差)。配置了 calendarUrl 则直接使用;否则从 serverUrl 自动发现(current-user-principal → calendar-home-set → 第一个日历集合)。主要目标场景是 iCloud + App 专用密码。

新服务商(如 Microsoft Graph)实现同一接口即可接入;网络层(fetch)、环境变量读取均可注入,单测不触网。

工具

| 工具 | 作用 | 注册条件 | | --- | --- | --- | | calendar_list | 按时间范围列出事件(默认今天起 7 天),含起止、标题、地点、循环标记 | 始终 | | calendar_get | 单个事件详情(含描述、链接) | 始终 | | calendar_freebusy | 给定范围与所需时长,返回合并后的忙碌块与所有足够长的空档 | 始终 | | calendar_create | 创建事件(描述中标注【高风险·L2 每次确认】) | 仅 writesEnabled: true | | calendar_update | 修改事件标题/时间/地点/描述(同上标注) | 仅 writesEnabled: true |

所有工具返回 output.schema 声明的结构化 JSON(时间为 UTC ISO 8601),渲染文本按配置时区本地化;全部请求带超时(默认 10s)、响应 exec.signal 取消、网络错误与 5xx 自动重试一次、401/403 转为可读的"凭证过期"错误。

配置

- id: calendar
  name: dsh-daily-calendar
  config:
    enabled: true
    provider: google        # google | caldav
    writesEnabled: false    # 默认关:开启才注册 calendar_create / calendar_update
    defaultDays: 7          # calendar_list 默认范围长度(天)
    timeZone: ''            # IANA 时区,如 Asia/Shanghai;空 = 系统时区
    timeoutMs: 10000
    retry: true
    google:
      calendarId: primary
      accessTokenEnv: GOOGLE_CALENDAR_TOKEN
      refreshTokenEnv: GOOGLE_CALENDAR_REFRESH_TOKEN
      clientIdEnv: GOOGLE_CALENDAR_CLIENT_ID
      clientSecretEnv: GOOGLE_CALENDAR_CLIENT_SECRET
    caldav:
      serverUrl: ''         # 如 https://caldav.icloud.com,用于自动发现
      calendarUrl: ''       # 日历集合 URL;设置了就跳过自动发现
      usernameEnv: CALDAV_USERNAME
      passwordEnv: CALDAV_PASSWORD

所有叶子字段都有默认值;但凭证只从环境变量读取——配置里写的只是环境变量的名字,插件从不把凭证写进配置文件、日志或历史。

Google token 获取

首版不内置 OAuth 授权跳转流程(那需要一个本地回调服务与浏览器交互,超出插件边界),采用用户自备 token 的务实方案:

  1. 在 Google Cloud Console 创建项目,启用 Google Calendar API。
  2. 在「API 和服务 → 凭据」创建 OAuth 客户端 ID(类型选"桌面应用"),得到 client id / client secret。
  3. 打开 OAuth 2.0 Playground:右上角齿轮勾选"Use your own OAuth credentials"并填入上一步的 client id/secret;在左侧 scopes 中输入 https://www.googleapis.com/auth/calendar(读写)或 .../calendar.readonly(只读);走完授权后点"Exchange authorization code for tokens",得到 access token 与 refresh token。
  4. 设置环境变量:GOOGLE_CALENDAR_TOKEN=<access token>。如需过期自动刷新,再设 GOOGLE_CALENDAR_REFRESH_TOKEN / GOOGLE_CALENDAR_CLIENT_ID / GOOGLE_CALENDAR_CLIENT_SECRET 三件套。
  5. 没有 refresh 三件套时,access token(约 1 小时)过期后首次请求会报"凭证已过期,请重新生成"的可读错误。

权衡:这把 OAuth 的复杂度转嫁给了首次配置,但换来了零本地端口、零浏览器依赖、凭证完全由用户掌控;刷新流是可选增强,没有也能用。

CalDAV(iCloud 示例)

  1. Apple 账户开启双重认证后,在 appleid.apple.com 生成 App 专用密码。
  2. 设环境变量:CALDAV_USERNAME=<Apple ID 邮箱>、CALDAV_PASSWORD=<App 专用密码>。
  3. 配置 caldav.serverUrl: https://caldav.icloud.com 让插件自动发现第一个日历集合;或直接在 iCloud 日历网页版复制日历集合 URL 填 caldav.calendarUrl(跳过发现,最稳)。

Fastmail(https://caldav.fastmail.com/)与 Nextcloud(https://<host>/remote.php/dav)同理,用户名/密码或应用密码即可。

权限透明

  • 读写位置:无。插件不读写任何本地文件;唯一状态是进程内存中的"刷新后的 Google access token"(不落盘,重启即失效)。
  • 网络域名:provider: google 时仅 www.googleapis.com(Calendar API)与 oauth2.googleapis.com(仅配置 refresh 三件套且 token 过期时);provider: caldav 时仅你配置的 serverUrl / calendarUrl 那一台服务器。除此之外无任何网络请求。
  • 凭证:全部从环境变量读取——Google 侧 accessTokenEnv(默认 GOOGLE_CALENDAR_TOKEN)及可选 refresh 三件套;CalDAV 侧 usernameEnv / passwordEnv(默认 CALDAV_USERNAME / CALDAV_PASSWORD)。凭证值不出现在日志、工具输出与错误信息中;日志只记录"哪些环境变量名已配置"。注意 Google 侧 access token 会以 Authorization: Bearer 头发往 googleapis.com,CalDAV 侧以 HTTP Basic 头发往你的服务器——均仅发往对应域名。
  • 确认点:插件自身不发起 ask。三个读工具是只读操作;calendar_create / calendar_update 在描述中标注【高风险·L2 每次确认】,若同时启用 approval-guard,未知工具默认 L2(每次 ask),与本约定一致。
  • 日志内容:仅启动一行(provider、时区、写工具开关、已配置的凭证变量名)与请求失败时的警告(含状态码,不含凭证、不含事件内容)。事件内容只出现在工具返回值中。

已知限制

  • RRULE 展开范围有限:CalDAV 侧只展开 FREQ=DAILY / FREQ=WEEKLY(支持 INTERVAL / COUNT / UNTIL,按事件时区做 DST 安全的日历日推演);其余规则(MONTHLY/YEARLY/BYDAY 等)只标记 recurring: true 并返回基准次,不展开。EXDATE / RDATE / VTIMEZONE 不解析。Google 侧无此限制(服务端展开)。
  • 无会议邀请收发:创建/修改事件不处理 attendees,不会发出邀请邮件。
  • 无删除事件工具:写面刻意保持最小(创建 + 修改)。
  • Google 侧 token 刷新后的新 access token 只保存在进程内存:重启后若旧 token 已过期会再刷新一次(有 refresh 三件套时无感)。
  • CalDAV 自动发现取 calendar-home-set 下第一个日历集合;多日历用户请直接配 calendarUrl。
  • CalDAV 的 updateEvent 重建整份 VEVENT:原事件里本插件不识别的属性(提醒 VALARM、自定义扩展等)会丢失。Google 侧是 PATCH 语义,无此问题。
  • 浮动时间(无 TZID 的 ICS 本地时间)按插件 timeZone(默认系统时区)解释。

手动验证

CI 只覆盖类型检查与纯函数/注入替身单测。接入真实 dsh 与真实日历账号后请按以下步骤验证:

  1. 在 dsh 配置中启用 calendar 并设好凭证环境变量,启动日志应出现 calendar: loaded(provider=google,…,凭证环境变量已配置:GOOGLE_CALENDAR_TOKEN)。
  2. 让 agent 调用 calendar_list(不传参数)→ 返回今天起 7 天内的事件列表;传 from/to/days 验证范围参数。
  3. 用上一步返回的 id 调 calendar_get → 返回详情(描述、链接)。
  4. 调 calendar_freebusy(durationMinutes: 60)→ 返回的空档与日历实际占用一致。
  5. 把 access token 改成一个错误值再调 calendar_list → 报"凭证无效或已过期"的可读错误,且错误信息中不含 token 本身。
  6. 开启 writesEnabled: true 后调 calendar_create 创建一个测试事件 → 在 Google 日历网页 / iCloud 日历中确认出现;再调 calendar_update 改标题 → 确认同步。验证完毕建议改回 writesEnabled: false。
  7. CalDAV 路线:先只配 serverUrl 验证自动发现;发现失败时报错会提示改配 calendarUrl。

许可

MIT