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

@di-code/plugin-sdk

v0.2.6

Published

Public SDK entry point for di-code plugins

Readme

@di-code/plugin-sdk

@di-code/plugin-sdk 是第三方 di-code 插件的稳定公开入口。它重导出 @di-code/plugin-runtime/@di-code/plugin-loader 的根 API,并提供 Session、Agent hook、事件、projection、交互和策略契约;插件不得导入任何包的 src、dist 或未声明 subpath。

最小插件可以只导出 setup(api)。api.registerCommand() 注册宿主 HostCommandRegistry(是否有入口调用取决于 Composition),api.registerTool() 注册 Agent 工具,api.registerProvider() 注册 Provider(需要宿主提供对应 registry),api.on() 监听运行时事件。宿主命令不会自动进入交互 slash 菜单或 RPC run_command。命令、工具和事件监听的 disposer 会绑定当前 Fiber 并在卸载时清理;当前 Provider registry 没有移除接口。api.registerWeb() 只保留兼容形状,不发布 Web contribution,WebUI 扩展必须使用 manifest 的 diCode.web。

npm install @di-code/plugin-sdk
import { createServiceKey, type PluginDefinition } from "@di-code/plugin-sdk";

export const greetingKey = createServiceKey<string>("acme.greeting");
export const apiVersion = 1 as const;
export const name = "acme.greeting";
export const version = "1.0.0";
export const apply: PluginDefinition["apply"] = (context) => {
	context.set(greetingKey, "hello");
};

发布 package 推荐以 ESM exports["."] 声明入口;旧版 package.json.diCode.plugins 仅用于兼容。完整 manifest、Composition、trust、capability 和 lifecycle 规则见仓库 docs/插件使用指南.md。

Web UI 扩展使用 WebManifest、WebContribution 和 WebSlotId。贡献通过宿主 WebSlotRegistry 按 owner 管理,dispose 幂等;componentKey 是宿主白名单键,不是 URL、HTML 或 JavaScript。插件只能提供声明式只读数据;Workspace trust 控制是否聚合贡献,组件白名单和运行时 capability 由宿主检查。

Session 级 UI 使用 createSessionExtensionRegistry()。插件 scope 可通过 registerBadge() 和 registerUi() 动态添加徽章、控制、审阅面板或输入占位符;返回的 disposer、scope dispose 和 HMR 卸载都会移除贡献。宿主通过 SessionExtensionFacade 向 SessionHost/RPC 提供只读快照,RPC 以 extension:ui projection 推送;componentKey 仍必须由宿主白名单解析。当前 WebUI 的静态 slot 贡献使用 manifest 的 diCode.web,不会直接执行插件 UI 代码。

本包根入口导出 SessionPluginFactory、SessionPluginScope 和 createSessionPluginFactory。factory 为每个 session ID 创建独立 scope;scope 提供 opaque ID、AbortSignal、不可变 capabilities、hooks、typed events/projections registry、动态 prompt sections、appendEvent() 和可选 UserInteraction,不暴露 Agent、AgentSession、SessionManager、文件句柄或 transport。appendEvent() 由宿主绑定到当前 Session 的串行持久化队列;无持久化宿主时会明确失败。重复 session ID 会以 PluginLifecycleError(DUPLICATE)拒绝;初始化失败会回滚已注册的 disposer;scope 与 factory 的 dispose() 都幂等,并在释放时 abort signal。factory 卸载会清理所有已创建 scope,适用于 Composition/Fiber 卸载和 HMR 重载。宿主将 scope hooks、events 和 projections 接入单一 Session/Agent,并执行迁移、校验和回放。完整的插件 manifest、Composition、trust 和版本规则见仓库 docs/插件使用指南.md。

根入口还导出 AGENT_HOOK_API_VERSION、AgentHookRegistration、AgentHookObserver 和 AgentHookModifier。这些 facade 对应宿主单一 Agent loop 的版本 1 生命周期阶段:request_prepare、pre_step、request_accept、tool_execute_before、step_complete、turn_complete、failed、cancelled。观察型 hook 只读取数据;修改型 hook 仅能在 pre_step 通过返回新的 AgentRequestAssembly 或结构化 decision 影响请求。hook 接收 AbortSignal,可声明 timeoutMs 与 onError,但不能取得 Agent、Provider、transport 或循环控制权。

Session scope 还提供 promptSections。插件通过 register({ name, order, owner, generate }) 注册动态 system prompt section;名称必须唯一,顺序相同时按注册顺序排列,空结果跳过,生成异常和取消会终止当前请求。每次 Provider request 都读取新的 Agent/Session 快照,返回的 disposer 在插件或 Session 卸载时移除贡献。旧的 systemPrompt 仍由宿主作为最低层前缀保留。

Typed Session event 使用 createSessionEventRegistry() 注册 namespace、eventName、schemaVersion、validate 和可选 migrate;事件由宿主 SessionManager.appendEvent() 串行追加,payload 上限为 256 KiB,并继承文件锁和 AbortSignal 取消语义。createSessionProjectionRegistry() 的 replay() 只接受完整事件日志并返回版本化状态,适合恢复、fork、compaction 后和冷读;未知事件或迁移失败通过 diagnostics() 暴露,不会被静默丢弃。事件不得包含凭据、完整请求体或敏感用户内容。

Session policy facade 使用版本化 ToolPolicyMode/ToolPolicySnapshot。宿主在每次工具 execute 前调用 SessionToolPolicy.authorize(),catalog 不因模式变化而隐藏;策略可以读取当前 projection 和 plugin state。read_only 的 mutation tool 拒绝、取消、超时和重复切换具有明确错误码,切换事件由宿主持久化,恢复/fork 不依赖内存镜像。

UserInteraction

@di-code/plugin-sdk exports createUserInteraction and UserInteraction for provider-neutral user prompts. Requests support question, questions, choice, and approval, optional choices/free text, intent, requestId/toolCallId, timeout, and AbortSignal. Results are structured (approved, value, values, feedback) and contain no UI transport credentials. Duplicate request IDs share one pending result; duplicate answers are idempotent. Without a provider the facade rejects with INTERACTION_UNAVAILABLE, and disposal cancels pending work.

Hosts can use createFakeInteractionProvider in tests. RPC hosts negotiate the interaction_request event and answer with respond_interaction; legacy tool_approval/approve_tool remains supported with deny-by-default when no UI channel exists.

Plan Mode integration

The standalone @di-code/plan-mode package consumes the SDK's versioned prompt, Session event, tool-policy, projection, and UserInteraction contracts. Hosts provide a PlanModeAdapter; plugins must call the host SessionManager.appendEvent() through that adapter and must not access Session JSONL directly. See docs/插件/Plan Mode迁移指南.md for the integration contract.