@tier0/sdk-v2 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -5
- package/dist/cjs/client.d.ts +1 -3
- package/dist/cjs/cloud-transport.js +1 -2
- package/dist/cjs/cloud-transport.js.map +1 -1
- package/dist/cjs/data/schema.js +5 -1
- package/dist/cjs/data/schema.js.map +1 -1
- package/dist/cjs/openapi/types.generated.d.ts +1 -1
- package/dist/cjs/openapi/types.generated.js.map +1 -1
- package/dist/cjs/source.d.ts +1 -0
- package/dist/cjs/source.js +1 -0
- package/dist/cjs/source.js.map +1 -1
- package/dist/cjs/stream.d.ts +0 -3
- package/dist/cjs/stream.js +0 -1
- package/dist/cjs/stream.js.map +1 -1
- package/dist/cjs/uns-v2/generated.d.ts +138 -82
- package/dist/cjs/uns-v2/generated.js +19 -19
- package/dist/cjs/uns-v2/generated.js.map +1 -1
- package/dist/esm/client.d.ts +1 -3
- package/dist/esm/cloud-transport.js +1 -2
- package/dist/esm/cloud-transport.js.map +1 -1
- package/dist/esm/data/schema.js +5 -1
- package/dist/esm/data/schema.js.map +1 -1
- package/dist/esm/openapi/types.generated.d.ts +1 -1
- package/dist/esm/openapi/types.generated.js.map +1 -1
- package/dist/esm/source.d.ts +1 -0
- package/dist/esm/source.js +1 -0
- package/dist/esm/source.js.map +1 -1
- package/dist/esm/stream.d.ts +0 -3
- package/dist/esm/stream.js +0 -1
- package/dist/esm/stream.js.map +1 -1
- package/dist/esm/uns-v2/generated.d.ts +138 -82
- package/dist/esm/uns-v2/generated.js +19 -19
- package/dist/esm/uns-v2/generated.js.map +1 -1
- package/docs/acceptance-2026-10-22.md +3 -1
- package/package.json +2 -2
- package/skills/tier0-sdk-v2/tier0-sdk-v2-controls/SKILL.md +2 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/SKILL.md +2 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/consistency.md +3 -3
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/modeling.md +6 -4
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/read-write.md +1 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/schema-evolution.md +2 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/SKILL.md +1 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/SKILL.md +2 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/create.md +1 -1
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
日期:2026-10-22。包:`@tier0/sdk-v2@0.1.0`。
|
|
4
4
|
|
|
5
|
+
> 历史记录:以下结果仅适用于当时版本。2026-10-27 已退役 Stream 就绪探针及逐 Key Control scopes/codes;当前 SDK 不再导出该探针。不得将下文历史 403 当作 Stream 故障或按旧授权模型要求扩权。后续验收见 [Tier0-doc 新版架构专题](https://github.com/FREEZONEX/Tier0-doc/blob/main/docs/新版架构/03-Cloud新版改造/112-Stream控制就绪探针退役.md)。
|
|
6
|
+
|
|
5
7
|
验收对应 SDK 提交 `5d30d5154354bac94bbbe88402a8303d6c43526d` 的安装包。报告提交时远端已合入其他功能(至 `78f5168`);下列测试数量和业务结论不覆盖那些新增功能。
|
|
6
8
|
|
|
7
9
|
结论:安装包和本地自动化通过;多组真实业务操作通过,但不能宣称“所有功能已可用”。追加验收已完成真实站内通知发送、Stream 发布、当前 release 的真实执行、停用及归档。Source 创建预检、Control 权限、Stream 能力查询、Agent 真实用户身份及文件大分片传输仍有阻断或限制。
|
|
@@ -62,7 +64,7 @@ Source 的 503 是后端返回的统一生命周期错误。对固定版本代
|
|
|
62
64
|
| --- | --- | --- |
|
|
63
65
|
| Source 创建 503 | 当前镜像仍复现;requestId `8b0197c1-3479-4277-ba70-89e131512437`。错误映射将多种内部错误合并为 `cloud lifecycle service unavailable`,现有日志未能将根因关联到此请求 | 服务端在 Source 管理身份刷新、租户解析、凭据绑定预检、事务写入边界增加不含凭据的阶段码和 requestId 关联,再针对确切失败修复。暂不能声称重启、加权限或迁库能解决。未修改部署或数据库 |
|
|
64
66
|
| 大文件分片 PUT 超时 | 追加对照中 1 KiB 的 PUT=200、complete=200;5 MiB 首片仍超过 20 秒。原测试 30/60 秒同样超时;额外把 Blob 转为 Uint8Array 发送,60 秒仍超时。小文件完成后的下载 URL 查询另遇连接错误,文件已删除,大分片会话已 abort | 签名对小分片有效,替换 Blob 发送体未解决。仍需上传路径/OSS 服务端证据定位;仅增大 timeout 不能算修复,须以两片上传、合并及下载 hash 比对为验收 |
|
|
65
|
-
| Control 与 runtime capabilities 403 |
|
|
67
|
+
| 当时的 Control 与 runtime capabilities 403 | 当时部署代码将能力查询放在旧 Control 权限分支 | 历史原因,不适用当前版本。探针现已退役,实际调用归入统一权限,不再要求逐 Key Control scopes/codes |
|
|
66
68
|
| Agent jobs 身份限制 | 当前是 service Key;任务管理明确要求真实用户 | 使用有任务权限的真实成员 personal Key 或该功能支持的会话身份。扩大 service Key scope 不能把它变成真实用户 |
|
|
67
69
|
|
|
68
70
|
ACK 日志另有 `UNS control metadata requires explicit migration before startup`,但尚未证实属于本 Workspace 或此次 Source 请求,不能把该日志当成本次 503 的根因。部署、重启、授权变更和数据库迁移均未执行。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tier0/sdk-v2",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Tier0 Cloud new-architecture SDK for TypeScript and JavaScript",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
"scripts": {
|
|
157
157
|
"sync:contracts": "node scripts/sync-contracts.mjs",
|
|
158
158
|
"generate": "node scripts/generate-openapi.mjs && node scripts/generate-uns-v2.mjs",
|
|
159
|
-
"check:contracts": "node scripts/check-contracts.mjs && node scripts/generate-openapi.mjs --check && node scripts/generate-uns-v2.mjs --check",
|
|
159
|
+
"check:contracts": "node scripts/check-contracts.mjs && node --test scripts/retired-stream-probe.test.mjs && node scripts/generate-openapi.mjs --check && node scripts/generate-uns-v2.mjs --check",
|
|
160
160
|
"check:skills": "node scripts/check-skills.mjs && node scripts/check-skill-examples.mjs",
|
|
161
161
|
"typecheck": "tsc --noEmit && tsc -p tsconfig.tests.json",
|
|
162
162
|
"build": "node scripts/build.mjs",
|
|
@@ -7,6 +7,8 @@ description: 使用 @tier0/sdk-v2 发现、描述和调用 Tier0 Control 业务
|
|
|
7
7
|
|
|
8
8
|
Control 是已发布的业务调用入口;它可由 Stream 提供,但调用方不选择内部 streamId、entryId 或部署版本。使用服务端 client.controls,实际调用 `/openapi/v2/uns/controls/discover|describe|invoke`,不重建旧 Flow 调用。
|
|
9
9
|
|
|
10
|
+
调用按服务端现有统一权限及 App 业务策略校验;不配置逐 Key 的 Control scopes/codes。旧 Stream 就绪探针已经退役,不能因为它的历史 403 判断当前入口不可用或要求扩权。
|
|
11
|
+
|
|
10
12
|
## 发现和读取契约
|
|
11
13
|
|
|
12
14
|
```ts
|
|
@@ -32,7 +32,7 @@ export const workOrders = defineCollection({
|
|
|
32
32
|
schema: z.object({
|
|
33
33
|
code: z.string(),
|
|
34
34
|
status: z.enum(['DRAFT', 'RELEASED', 'DONE', 'CANCELLED']),
|
|
35
|
-
targetQty: z.number().int().min(1),
|
|
35
|
+
targetQty: z.number().int().min(1).meta({ format: 'int32' }),
|
|
36
36
|
dueAt: z.string(),
|
|
37
37
|
}),
|
|
38
38
|
indexes: [{ path: 'code', unique: true }, { path: 'status' }],
|
|
@@ -51,6 +51,7 @@ export async function releasedOrders(): Promise<WorkOrder[]> {
|
|
|
51
51
|
|
|
52
52
|
1. 声明文件只从 `@tier0/sdk-v2/data/define` 导入,客户端代码可以安全引用它;全部集合在一个 `collections` 列表里声明(每个 App 最多 64 个),只建一个进程级 client;不要手动 ensure、不要在 import 时访问数据、不要自建“已初始化”标记。
|
|
53
53
|
2. 集合 Schema 是存储 Schema:只能用可存储的 Zod 子集,输入规则(格式、长度、默认值、transform)放在 API 入参 Schema。
|
|
54
|
+
新建数值字段明确选择 int(integer + int32)、float 或 double(number + 对应 format);普通小数选 double,嵌套对象和数组元素同样处理。SDK 会为未标注的 integer/number 补齐 int32/double;直接 MCP 请求必须自行提供 format。
|
|
54
55
|
3. 写入前按声明严格校验,未知字段、类型错误、未声明的更新路径直接抛 `ZodError`;读取不做严格解析,旧版本写入的字段、新枚举值或缺字段都可能出现。
|
|
55
56
|
4. `insertMany` / `bulkWrite` / `transact` 每次最多 200 项且原子;`updateMany` / `deleteMany` 逐条提交、非原子。
|
|
56
57
|
5. 按 `DataError.code` 与 `reason`(`data.reason`)分支,不匹配 message 文本;`status` 是 App 应回给自己调用方的 HTTP 状态。
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
import { z } from 'zod';
|
|
15
15
|
import { createDataClient, defineCollection } from '@tier0/sdk-v2/data';
|
|
16
16
|
|
|
17
|
-
const stock = defineCollection({ alias: 'stock', schema: z.object({ sku: z.string(), available: z.number().int().min(0) }) });
|
|
18
|
-
const reservations = defineCollection({ alias: 'reservations', schema: z.object({ sku: z.string(), qty: z.number().int().min(1), orderId: z.string() }) });
|
|
19
|
-
const counters = defineCollection({ alias: 'counters', schema: z.object({ value: z.number().int() }) });
|
|
17
|
+
const stock = defineCollection({ alias: 'stock', schema: z.object({ sku: z.string(), available: z.number().int().min(0).meta({ format: 'int32' }) }) });
|
|
18
|
+
const reservations = defineCollection({ alias: 'reservations', schema: z.object({ sku: z.string(), qty: z.number().int().min(1).meta({ format: 'int32' }), orderId: z.string() }) });
|
|
19
|
+
const counters = defineCollection({ alias: 'counters', schema: z.object({ value: z.number().int().meta({ format: 'int32' }) }) });
|
|
20
20
|
const data = createDataClient({ collections: [stock, reservations, counters] });
|
|
21
21
|
|
|
22
22
|
/** 扣减库存并写预留:库存不足时整体不提交。 */
|
|
@@ -23,7 +23,7 @@ export const salesOrders = defineCollection({
|
|
|
23
23
|
code: z.string(),
|
|
24
24
|
status: z.enum(['DRAFT', 'CONFIRMED', 'SHIPPED', 'CANCELLED']),
|
|
25
25
|
customer: z.object({ id: z.string(), name: z.string() }),
|
|
26
|
-
lines: z.array(z.object({ sku: z.string(), qty: z.number().int().min(1) })),
|
|
26
|
+
lines: z.array(z.object({ sku: z.string(), qty: z.number().int().min(1).meta({ format: 'int32' }) })),
|
|
27
27
|
notes: z.string().optional(),
|
|
28
28
|
orderedOn: z.string().describe('YYYY-MM-DD'),
|
|
29
29
|
confirmedAt: z.string().optional().describe('ISO-8601 UTC from toISOString()'),
|
|
@@ -63,7 +63,7 @@ export const createSalesOrderInput = salesOrders.schema
|
|
|
63
63
|
|
|
64
64
|
## 字段类型标注
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
新建数值字段必须明确选择 int、float 或 double,普通小数默认 double。需要在 Collection 中明确显示 `int`、`float`、`double`、`datetime` 时,通过 Zod 元数据添加格式声明。传输仍使用 JSON Schema 的 `integer` / `number` / `string`:
|
|
67
67
|
|
|
68
68
|
| 声明 | 传输 Schema | 显示类型 |
|
|
69
69
|
| --- | --- | --- |
|
|
@@ -72,7 +72,7 @@ export const createSalesOrderInput = salesOrders.schema
|
|
|
72
72
|
| `z.number().meta({ format: 'double' })` | `{ type: 'number', format: 'double' }` | `double` |
|
|
73
73
|
| `z.string().meta({ format: 'date-time' })` | `{ type: 'string', format: 'date-time' }` | `datetime` |
|
|
74
74
|
|
|
75
|
-
`format` 当前是类型展示注解,不额外限制数值范围或精度,也不舍入数据。写入仍按原来的 Zod 类型和显式 `.min()` / `.max()`
|
|
75
|
+
`format` 当前是类型展示注解,不额外限制数值范围或精度,也不舍入数据。写入仍按原来的 Zod 类型和显式 `.min()` / `.max()` 校验;需要业务范围时应继续声明边界。SDK 编译时递归为普通 `z.number()` 补 `double`,为 `z.int()` / `z.number().int()` 补 `int32`;显式 float/double 与 date-time 保留,普通字符串不补格式,也不根据样本数值推断精度。只接受上表四种类型与格式组合。
|
|
76
76
|
|
|
77
77
|
`datetime` 仍保存原始字符串,不校验日期是否有效、不解析或转换时区;`"not a date"` 也能通过字符串类型校验。需要日期合法性保证时,在 API 入参 Schema 单独使用 `z.iso.datetime()`;这类带 `pattern` 的验证器不能直接作为可存储的集合声明。新增注解不改变 Sample 外层 `time` 的毫秒时间戳协议、已有校验和业务时间含义。
|
|
78
78
|
|
|
@@ -90,7 +90,7 @@ import { defineCollection } from '@tier0/sdk-v2/data/define';
|
|
|
90
90
|
|
|
91
91
|
export const loginCodes = defineCollection({
|
|
92
92
|
alias: 'login_codes',
|
|
93
|
-
schema: z.object({ phone: z.string(), code: z.string(), issuedAt: z.number().int() }),
|
|
93
|
+
schema: z.object({ phone: z.string(), code: z.string(), issuedAt: z.number().int().meta({ format: 'int32' }) }),
|
|
94
94
|
// issuedAt 存 Date.now();签发 5 分钟后删除。
|
|
95
95
|
indexes: [{ path: 'phone' }, { path: 'issuedAt', expireAfterSeconds: 300 }],
|
|
96
96
|
});
|
|
@@ -111,3 +111,5 @@ export const loginCodes = defineCollection({
|
|
|
111
111
|
- 共享实体按 ID 引用,并快照需要展示的字段(`customer: { id, name }`),不要在读取时 join。`aggregate` 有 `$lookup`,但有行数限制,不要用它搭列表页。
|
|
112
112
|
- 每种业务对象一个集合,而不是每个页面一个集合。
|
|
113
113
|
- “最新优先”用 `_meta.createdAt` / `_meta.updatedAt`,由 UNS 维护。
|
|
114
|
+
|
|
115
|
+
直接通过 MCP 提交 recordSchema/sampleSchema 时必须提供上述 type + format;Zod 编译兜底不处理原始请求。ensure 保留已有字段注解,无格式的存量字段需读取完整 Schema、保留其他约束,通过 schema:replace 先 dryRun 再按明确迁移授权执行。
|
|
@@ -12,7 +12,7 @@ const workOrders = defineCollection({
|
|
|
12
12
|
code: z.string(),
|
|
13
13
|
status: z.enum(['DRAFT', 'RELEASED', 'DONE']),
|
|
14
14
|
line: z.object({ id: z.string(), name: z.string() }),
|
|
15
|
-
targetQty: z.number().int().min(1),
|
|
15
|
+
targetQty: z.number().int().min(1).meta({ format: 'int32' }),
|
|
16
16
|
notes: z.string().optional(),
|
|
17
17
|
}),
|
|
18
18
|
indexes: [{ path: 'code', unique: true }, { path: 'status' }],
|
|
@@ -34,3 +34,5 @@ export function replaceBody(expectedRevision: number) {
|
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
Schema 中 `ignored`、`warnings`、`conflicts`、`violations` 的路径用 `.` 连接属性,用 `[]` 表示数组元素(`lines.[].qty`)。
|
|
37
|
+
|
|
38
|
+
新声明的 number/integer 默认带 double/int32 格式;ensure 不改写已有字段注解,原无格式字段仍保持 legacy 显示。已有字段格式迁移需读取并保留完整 Schema,先通过 schema:replace dryRun 检查,再按明确迁移授权执行。
|
|
@@ -33,7 +33,7 @@ description: 使用 @tier0/sdk-v2 的 client.stream 创建、查询、修改和
|
|
|
33
33
|
2. create/update 保存草稿,不自动发布;documents 没有 deploy,云端 program 发布使用 programs.deploy。不能将已保存报告为已运行。
|
|
34
34
|
3. 所有更新/部署/删除携带当前 expectedRevision。原生停用另需 expectedActiveRelease,避免停掉他人刚发布的版本。
|
|
35
35
|
4. versionId 从 versions.list 取得,不把 release 序号当 ID。expectedSourceRevision 仅用于恰好一个依赖源,不代表多个源的修订。
|
|
36
|
-
5. resources=[]
|
|
36
|
+
5. resources=[] 是空冻结资源集,不是通配符。写入本身由服务端校验,需要预览时单独 validate;当前云端程序 timeoutMs 上限 30000。旧 runtime.capabilities 查询已退役,不作为管理或执行前置检查,不为此增加 Control scope 或逐 Key 控制码授权。
|
|
37
37
|
6. 仅执行用户要求的生命周期步骤;修改脚本不自动授予发布、停用或删除权限。
|
|
38
38
|
|
|
39
39
|
## 成功与异常
|
|
@@ -48,6 +48,8 @@ export async function findAppCollection(alias: string) {
|
|
|
48
48
|
5. recordFind 使用 pageInfo.hasMore/nextCursor,limit 1–200;sort 为 [['field',1]]。单页不是全量,跨页不是稳定快照。
|
|
49
49
|
6. Sample 的时间是 Unix 毫秒,查询范围 [from,to)。Record 代表业务实体,不用覆盖它来保存历史。
|
|
50
50
|
|
|
51
|
+
7. 新建 recordSchema/sampleSchema 数值字段必须明确格式:int 用 `{ type: 'integer', format: 'int32' }`,float/double 用 `{ type: 'number', format: 'float'/'double' }`;普通小数默认选 double。递归覆盖嵌套对象和数组元素,不创建无 format 的 legacy number/integer;不把 type 写成 int/float/double。已有字段迁移先 dryRun 校验。
|
|
52
|
+
|
|
51
53
|
## 结果与异常
|
|
52
54
|
|
|
53
55
|
响应为 code/msg/requestId/data。元数据 find 返回 items/pageInfo;单条 updateOne/replaceOne/deleteOne 请求 returnDocument 时附带 value;普通写入默认返回对应计数和 ID。metadataTransact 的 results 按 opId 对应。检查 committed、每项错误和实际计数;dryRun 只校验。metadataBulkWrite 默认原子,显式非原子时必须逐项检查 results/errors;跨 kind 的依赖写入使用 metadataTransact。recordBulkWrite 不保证跨集合事务。
|
|
@@ -20,7 +20,7 @@ export async function createDeviceCollection(
|
|
|
20
20
|
},
|
|
21
21
|
sampleSchema: {
|
|
22
22
|
type: 'object', additionalProperties: false, required: ['temperature'],
|
|
23
|
-
properties: { temperature: { type: 'number', unit: '°C' } },
|
|
23
|
+
properties: { temperature: { type: 'number', format: 'double', unit: '°C' } },
|
|
24
24
|
},
|
|
25
25
|
},
|
|
26
26
|
};
|