@tbox.cn/app-toolkit
v0.7.2
Published
tbox 应用工具面(运行面/工具面对仗:app-sdk 给运行的应用用,app-toolkit 给操作应用的工具用)——模块解析、集成配置求值/校验/写入内核,contracts 经应用侧动态解析(沙箱与目标应用版本解耦)。
Readme
@tbox.cn/app-toolkit
tbox 应用工具面包(与 @tbox.cn/app-sdk 运行面/工具面对仗:sdk 给运行的应用用,toolkit 给操作应用的工具用——24 个工厂方法全部以 appDir 为首参(v4.4))。
模块解析、集成配置求值/校验/写入内核。contracts 求值与校验语义由应用自己的 @tbox.cn/app-contracts 版本动态驱动(core/contracts-resolver)——沙箱镜像内 toolkit 与目标应用版本节奏解耦,呈现给用户的求值结果与写出的文件恒由应用自身 contracts 求值/校验。
分层(四层线性链,import 只准向下;tests/import-layers.test.ts 包内自测锁)
core/ 零领域依赖:descriptor zod、env 展开(纯数据)、凭据格式、fskit 原子写、file-cache、contracts 动态解析器、期望面锁
assembly/ 目录知识:walkManifests 单次遍历四产物、provider catalog、per-service schema 表
integrations/ 领域:谓词单源(doctor 同源)、写核心(PUT 节点全量替换)、mock 绑定、凭据双工件
views/ 视图装配:modules / app / service-detail / service-resolutions / providers 五投影 + 工厂禁 import @tbox.cn/app-sdk(叶包);反向 app-sdk → toolkit 仅一条永久生态兼容 re-export 桥(loadProviderCatalog + expandEnvVars——存量克隆应用模板导入零改动,桥源形态冻结)。
Freshness Contract(公开契约)
每个公开方法调用,反映调用开始前已完成的全部文件系统状态变更——无需调用方显式失效。 新鲜度承诺单位是方法调用,不是实例(长生命周期进程级单例安全的前提)。
| 状态类别 | 机制 | 成本 |
|---|---|---|
| 目录结构(packages/ 增删、node_modules 候选、契约包发现) | 枚举零缓存(每次 readdir) | ~20-40 stat/请求 |
| 清单输入(.tbox/app.json、dev-manifest、模块 manifest) | 枚举零缓存(小文件直读) | 同上 |
| 文件内容(integrations.json、credentials/、schemas/、service-slots.json、contracts package.json) | stat 指纹(mtimeMs+size;外部写下一笔自愈) | 命中后 1 stat/文件 |
| contracts 模块(动态 import 产物) | 版本轻探测(候选路径经 symlink 读 version;变更重走候选链 + 重 import) | 1 stat/请求 |
| 本进程写入 | 写后本实例即刻失效(read-your-writes,不依赖 mtime 粒度) | 0 |
边界:① 无快照隔离——请求进行中的变更可能产生部分视图,下一笔收敛(写路径写时重新枚举 + 校验,无 stale-clobber);② 同 stat 指纹的外部覆写不可觉察(现实中不发生;本进程写有显式失效兜底);③ workspace 源码态 contracts 原地改 dist 不 bump version → 不重 import(与应用自身装载行为一致)。验收面 = tests/file-cache.test.ts W1-W7 矩阵。
打包纪律三件套(tsup.config.ts 同文)
- 禁
createRequire(import.meta.url)——contracts 发布面 exports 仅 types+import 双条件,require 必抛ERR_PACKAGE_PATH_NOT_EXPORTED; - 动态 import 路径禁字面量包名折叠——resolver 探测命中文件运行时计算(agtcodingbox esbuild
packages:"external"已核实 toolkit 不进 bundle); - minify 两键 + 导出 Error 类
this.name字符串字面量约定——minify: true+charset utf8(沿 commit 72383576 配方;真源 process note2026-09-11-publish-dist-minify);Error 子类构造器必须this.name = 'XxxError'字面量赋值(禁 binding 形态——mangle 后静默漂移),tests/error-name-safety.test.tssrc 态守卫。
验证分层①-④(发布形态全链路)
| 层 | 载体 | 覆盖 |
|---|---|---|
| ① src 态守卫 | tests/error-name-safety.test.ts + 全测试矩阵(随 pnpm -r test 进根 verify 链) | 导出面/字面量约定/行为矩阵 |
| ② minified dist 冒烟 | pnpm --filter @tbox.cn/app-toolkit smoke:dist(scripts/smoke-dist.mjs——纯 node:24 方法 typeof + AppToolkitError.name + resolver 命中 + file-cache 快测) | dist 产物直调(mangle 后) |
| ③ 发布形态门禁 | pnpm --filter @tbox.cn/app-toolkit pack --check(prepack 内建 build,tgz 内即 minified dist) | 打包完整性 |
| ④ 跨仓 file: tgz 联调 | agtcodingbox 联调(file: tgz 消费——真实宿主) | 消费面全链路 |
能力门控(v7:读求值轴降级 + 写/迁移面 503)
读求值轴(loadServiceResolutions / loadServiceResolution / include=serviceResolutions):contracts 不可用(未安装 / 无严格面 / 求值面缺席 / OWNERSHIP_BINDING_V6 标记缺席,三条件与 contractsEvaluable)→ 200 降级骨架(evaluation-unavailable + N1 指引入 statusMessage + 静态可算字段 module/required/inheritance/instances 声明枚举;机制见 Agent Note evaluation-axis-degrade)。写方法与迁移面(write×4 / ensureMockBindings / writeIntegrationsConfig / evaluateIntegrationServices):contracts 不可用 → AppToolkitError('CONTRACTS_NOT_RESOLVED', 503, contractsNotResolvedMessage 四分支)。静态方法与 contracts 可用性解耦。门控断言单点 = 工厂边缘(写侧 policy at edge),机制层保持纯函数。
