11 KiB
Agent Note: SDK 后续功能
Status: proposed
English | 中文
问题
首个 SDK 版本通过开发者工程 Agent Note 和 SDK 工程编辑架构定义的共享模型创建和编辑开发者拥有的 Cordis 工程。create 和 config 工作流仅支持交互调用,接入外部 Cordis 插件需要手工修改依赖和配置,命令行遥测没有明确的所属边界,交互分支也缺少稳定的测试策略。
这些缺口彼此关联。create 和 config 已经共享问题、功能配置和 ProjectEditSession;若另建自动化路径,就会复制领域逻辑。安装外部插件必须同时修改包管理器文件和 cordis.yml。遥测需要观察 create、build 等不会启动 Cordis 的命令。交互测试需要覆盖 Harness 自身行为,同时避免把终端渲染固化成脆弱的产品契约。
提案
SDK 扩展现有提示词与工程编辑边界,不另建平行工作流。非交互式 PromptPort 实现和结构化功能计划驱动 create 与 config;dsh-sdk create <source> 先把依赖解析交给工程的包管理器,再通过 ProjectEditSession 挂载解析所得的包;启动器侧遥测包住 create-sdk 和每个 dsh-sdk 命令;交互测试主要通过注入的提示词输入输出流完成。
| 功能 | 产品入口 | 所属机制 | 必须达到的结果 |
|---|---|---|---|
| Headless 工程创建 | create-sdk --config <file> 或 --config-json <json>,可搭配 --json |
HeadlessPromptPort、结构化工程答案和完整功能计划 |
不阻塞等待终端;明确报告缺失的必答输入 |
| 外部 Cordis 插件安装 | dsh-sdk create <source> |
包管理器原生 add 加 ProjectEditSession |
依赖和 cordis.yml 配置项指向包管理器解析出的包 |
| 开发周期遥测 | create-sdk 和每个 dsh-sdk 命令 |
启动器侧的上报条件判断、遥测内容构建、脱敏、匿名身份和传输服务 | 上报采用尽力而为语义,不能改变命令结果 |
| 交互回归覆盖 | create 和 config 测试 | 注入的 PromptPort 输入输出和文件系统断言 |
测试覆盖 Harness 决策与生成文件,不快照终端重绘 |
共享 headless 工作流
结构化输入和生命周期事件
Headless create 通过 --config-json 接收内联 JSON 对象,或通过 --config 从文件读取。标量字段提供普通 create 答案,features 提供完整的已选功能、功能选项、secret(密钥)和专用值。只有所属问题明确声明的默认值才有效;headless 路径绝不为必答问题臆造答案。
使用 --json 时,stdout 是 NDJSON 事件流。done 表示创建及要求执行的安装和构建均已完成,action-required 指明一个尚未回答的必答问题,error 报告其他失败。面向人的进度信息和包管理器输出写入 stderr,确保 stdout 每一行都能解析成一个事件。调用方收到 action-required 后补充缺失值,再次运行命令。
Create 和 config 使用相同的功能计划形状。create 通过上述命令行输入公开该形状;config 在共享工作流边界使用同一形状,使后续自动化入口无需另建功能选择模型。
Prompt 与工程编辑边界
PromptPort 仍是 SDK 问题与交互实现之间的唯一边界。ClackPromptPort 负责终端交互。HeadlessPromptPort 使用问题契约公开的默认值,否则通过未回答问题快速失败;预填值通常会让流程根本不调用该 port。
两条路径使用相同的 Question 对象、FeatureConfigurator、SdkProject 和 ProjectEditSession。因此,headless 路径只改变答案的到达方式,不改变功能解释或文件提交方式。
Agent skill
仓库提供一份轻量 SKILL.md,指导 agent skill(智能体技能)构造结构化输入、请求 NDJSON、补充 action-required 指明的值并重试。该 skill 调用公开 CLI,不导入 SDK 内部 API,也不引入另一套工程规格。
外部 Cordis 插件安装
dsh-sdk create <source> 接受包管理器原生的 npm package specifier,例如 pkg@version,也接受 github:owner/repo#ref 等 GitHub package specifier。用户确认后,命令要求工程包管理器添加来源,对比操作前后的直接依赖名,重新打开工程,再通过 ProjectEditSession 把每个新增且已解析的包挂载进 cordis.yml。
包管理器负责来源解析、版本或 commit 解析、integrity 数据、lockfile 更新和构建策略。SDK 不再通过 giget 或 pacote 下载、解压第二份副本。外部插件是 node_modules 下的依赖;本地插件脚手架仍属于独立的工程创建问题。
Launcher 遥测
Consent 与采集
遥测包住 create-sdk 初始化命令与 dsh-sdk launcher 的命令生命周期,因为工程初始化、插件创建和 build 都不会稳定地启动 Cordis。每个事件记录命令名、时长、成败、随机生成的用户级匿名标识符,以及符合条件时经过脱敏的 cordis.yml 与 package.json 文本。
除非当前存在的遥测配置项被明确禁用,否则允许上报。DO_NOT_TRACK 和 CI 无论工程配置如何都禁止上报。缺少 cordis.yml 本身不会禁止事件,但只有 cordis.yml 能证明目录是 SDK 工程时,遥测内容才包含 package.json 文本。
安全与传输
Payload 构建器绝不读取 .env。它会脱敏两个符合条件的文本文件中的疑似密钥键和值、已知 token 形式、PEM 块、URL 凭据和高熵不透明字符串。脱敏只是安全兜底,不能提供绝对保证;SDK 工程必须把凭据放进 .env。
TelemetryReporter 使用固定 endpoint,每条发送路径都会正常结束且不抛错。命令分发通过 finally 路径记录成败,在命令结果已确定后启动上报,并在有界时间内等待传输结束。只有遥测边界会吞掉上报条件解析、遥测内容构建、存储或网络错误,这些错误绝不改变命令退出码。
交互工作流测试
Create 和 config 测试向现有工作流注入 PromptPort 和脚本化输入输出流。参数化场景覆盖功能选择、功能选项、secret、取消、评审和应用行为,再断言最终的 cordis.yml 及其他工程文件。稳定的产品断言是生成后的工程状态,不是 clack 的 ANSI 重绘序列。
可以用一到两个可选的真实 PTY 冒烟测试覆盖注入无法复现的发布二进制和 TTY 检查。除非原生 PTY 工具在仓库支持的 Node 与宿主版本上足够可靠,否则它不进入必跑路径。
延后工作
- 扩展 headless create 规格,使其能表达本地
plugin或tool脚手架,而不是把该交互选择默认为 none。 - 在 create 和 config 中公开遥测关闭选项,同时保留只有禁用时才写入遥测配置项的上报许可表示。
- 明确 GitHub 来源依赖必须预先构建,还是允许运行由包管理器控制的 preparation script(准备脚本),并在安装前向用户展示该策略。
- 发布前把遥测包中的
.invalidendpoint 占位符替换为生产端点。
曾考虑的替代方案
另建 headless 创建引擎。 该方案会复制问题、功能依赖、配置行为和工程编辑规则。复用提示词与编辑会话边界,可以保证工程语义只有一份实现。
把规格文件作为主要自动化接口。 Agent 可以内联传入相同的类型化 JSON 对象,人和 CI 仍可选用文件。文件专用协议会增加持久化与清理工作,却不增加语义。
使用 npx skills add 创建工程。 Skills CLI 只安装 Markdown skill,不创建 SDK 工程,也不安装 npm 包。因此,agent skill 驱动 SDK 初始化命令,而不是取代它。
通过 giget 或 pacote 获取 GitHub 与 npm 来源。 第二套获取层会复制包管理器的解析、完整性、lockfile 和生命周期策略。原生 package specifier 让这些决策留在所选包管理器中。
把遥测实现成 Cordis 运行时插件。 Create 和 build 不一定启动 Cordis,因此运行时插件无法观察完整的开发命令周期。Launcher 是这些命令共用的边界。
从 git 元数据派生匿名标识符。 仓库的 git remote 可能识别工程或组织。随机的用户级标识符能够支持聚合,同时不编码仓库身份。
只采集聚合计数。 仅聚合事件可以降低暴露,但无法回答开发者实际使用哪些插件、依赖和配置形状。本提案接受采集脱敏后的工程文本,并明确记录这项暴露。
把真实 PTY 和 transcript(文本记录)快照作为主要测试策略。 原生 PTY 依赖与终端重绘序列会带来平台和渲染不稳定性,而且主要是在测试 clack。注入交互并断言生成文件,可以直接测试 SDK 拥有的行为。
验收标准
- Create 能依据完整结构化输入在没有 TTY 时运行;使用
--json时 stdout 只输出 NDJSON;缺少必答输入时通过action-required报告,且不写入部分工程。 - Create 和 config 通过共享的问题、功能配置和工程编辑代码路径解析相同的功能计划契约。
dsh-sdk create <source>使用工程选定的包管理器,挂载该操作实际新增的依赖名;无法识别新增依赖时快速失败。- 初始化命令与每个
dsh-sdk命令都进入同一条尽力而为的遥测收尾路径;明确禁用的配置项、DO_NOT_TRACK或 CI 会阻止传输,遥测失败绝不改变命令结果。 - 遥测绝不读取
.env;没有cordis.yml时不发送无关的package.json内容;两个符合条件的文本都经过脱敏;匿名标识符与 git 元数据无关。 - 交互测试通过注入交互覆盖 create 和 config 决策,并断言已提交的工程文件;真实 PTY 覆盖只作为窄范围冒烟层。
- Agent skill 说明公开的结构化输入与事件契约,不依赖包的私有导出。
风险
- 即使经过脱敏,完整的
cordis.yml与package.json文本仍会向 endpoint 运营方暴露插件名、依赖名、URL、路径和配置值;启发式脱敏也可能漏掉 secret。 - 没有遥测配置项时默认上报可能让开发者意外;发布前 CLI 必须让关闭方法易于发现。
- 在
ProjectEditSession挂载插件前,包管理器的 add 操作已经可能修改package.json、lockfile 和安装文件;后续挂载失败会留下需要手工恢复的依赖改动。 - GitHub 依赖可能按包管理器策略执行 preparation 或 lifecycle script;尚未解决的构建策略会带来供应链与可复现性风险。
- 注入提示词交互的测试无法证明真实终端中的 raw mode、signal 或重绘行为;可选冒烟层只应覆盖这些残余契约。
参考资料
- Vercel Eve 与 Vercel Labs Skills 用于区分 headless 初始化命令与 skill 分发。
- npm package specifications、pnpm add和 Yarn add说明包管理器原生来源。
DO_NOT_TRACK定义环境级关闭约定。- Clack 和 Vitest snapshots 说明注入提示词交互与生成文件断言。