Machine-produced by `pnpm run rescope-vendor --apply` plus the regeneration it prints: `pnpm install` for the lockfile, `pnpm run gen-third-party-notices`, `verify-translation-pairing --write` for the touched bilingual pairs, `gen-doc-graphs`, and one typert snapshot whose ids embed character offsets. `pnpm run rescope-vendor --check` verifies the result. Renames nine vendored packages (cordis, cosmokit, schemastery and the six @cordisjs plugins) and every reference that resolves them: manifest names and dependency keys, module specifiers including declare-module merges, cordis.yml plugin names, tsconfig paths, every Markdown fence, and `docs/` prose. Directory names, upstream versions, and dependency ranges are unchanged, so vendor/README.md still reads as an upstream snapshot; its manifest table gains an upstream-name column so THIRD_PARTY_NOTICES keeps MIT attribution pointed at each fork's origin. The tutorial tier follows the rename end to end: its yaml fences named plugins the Loader can no longer resolve, its `ts ignore-check` fences disagreed with the compiled fences beside them, and its prose quoted both. The contracts that told readers to keep upstream names — the root convention and the vendoring cookbook's tree comment and manifest invariant — now say to rescope instead. Two rules read `@deepseek-ai/` as "another workspace plugin": the client bundle purity gate now names the vendored libraries a browser bundle inlines, and the files where a bare `cordis` is an agent-preset id keep that product data.
3.2 KiB
dsh-credentials
English | 中文
凭据 Service Definition(ctx.credentials)。一条准则,三个推论:
配置只携带对机密的引用,绝不携带机密本身。 settings 分节或 cordis.yml 条目写 apiKeyEnv: DEEPSEEK_API_KEY,引用背后的值归凭据提供方所有。于是设置文档可以放心同步、放心渲染进配置界面;describe() 无需持有值就能回答「配置了吗、来自哪层、能否写入」;轮换机密不触碰任何配置文件。
消费方按操作解析。 resolve(ref) 在每个操作开始时调用(LLM 适配器每次模型请求解析一次),绝不跨操作缓存——正是这次读取让改过的凭据无需重启任何插件就作用于下一次请求。
**空的存储值等于不存在。**处处如此:resolve 跳过它,describe 报告未配置。空白永远不会伪装成已配置的机密。
接口
import type { Context } from '@deepseek-ai/cordis'
import { credentialRef } from '@deepseek-ai/dsh-credentials'
declare const ctx: Context
const ref = credentialRef('DEEPSEEK_API_KEY') // POSIX shell identifier, branded
const hit = await ctx.credentials.resolve(ref) // { value, source } | undefined
const info = await ctx.credentials.describe(ref) // { configured, source?, writable } — never the value
await ctx.credentials.set(ref, 'sk-…') // rejects while a read-only source shadows the ref
await ctx.credentials.unset(ref) // no-op when absent; same shadowing rule
credentials/updated (ref) 在提供方管理的来源发生已提交变更后触发——set、unset 或在存储中观察到的外部编辑。进程环境变量的变化不可观测,永不触发。消费方不需要该事件(它们按操作重新解析);它服务于配置界面刷新「已配置」徽标。
set/unset 的遮蔽规则是刻意设计为明确报错:当只读来源(本地提供方中即当前进程环境)正在提供该引用时,写入会表面成功而解析仍返回遮蔽值——seam 选择直接拒绝,并通过 describe().writable 让界面提前把该引用渲染为只读。
提供方
dsh-credentials-local 把继承的进程环境叠加在其受管 $DSH_HOME/.credentials.yaml 文档之上,并以启动器的项目和用户 .env 层作为后备。seam 形状为 keyring、辅助命令、为 KMS 后端提供方留好了位置;远端设置提供方永远不必携带机密。
模型体验
经由消费它的 LLM 适配器间接生效:解析出的值为适配器的提供方请求授权,所有模型可见接口都由适配器负责。
KV Cache effect
无直接失效;凭据绝不进入请求前缀。
已知限制与暂缓事项
- 不提供枚举——seam 只回答被问到的引用;配置界面从 settings schema 得知引用集合,
list()没有当前消费方。 - 引用限定为环境变量形状——在有提供方需要更丰富的寻址方式前,保持单一扁平的 POSIX 标识符命名空间。
- 进程环境变化不可见——不可能为其发事件;界面只能在自身导航时重新读取
describe()。