@tier0/sdk-v2 0.0.0-stage → 0.1.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.
Files changed (298) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +7 -0
  3. package/README.md +201 -2
  4. package/dist/cjs/app-identity-contract.generated.d.ts +22 -0
  5. package/dist/cjs/app-identity-contract.generated.js +51 -0
  6. package/dist/cjs/app-identity-contract.generated.js.map +1 -0
  7. package/dist/cjs/capabilities.d.ts +54 -0
  8. package/dist/cjs/capabilities.js +134 -0
  9. package/dist/cjs/capabilities.js.map +1 -0
  10. package/dist/cjs/client.d.ts +604 -0
  11. package/dist/cjs/client.js +35 -0
  12. package/dist/cjs/client.js.map +1 -0
  13. package/dist/cjs/cloud-server.d.ts +31 -0
  14. package/dist/cjs/cloud-server.js +114 -0
  15. package/dist/cjs/cloud-server.js.map +1 -0
  16. package/dist/cjs/cloud-transport.d.ts +46 -0
  17. package/dist/cjs/cloud-transport.js +192 -0
  18. package/dist/cjs/cloud-transport.js.map +1 -0
  19. package/dist/cjs/controls.d.ts +93 -0
  20. package/dist/cjs/controls.js +169 -0
  21. package/dist/cjs/controls.js.map +1 -0
  22. package/dist/cjs/data/bootstrap.d.ts +66 -0
  23. package/dist/cjs/data/bootstrap.js +282 -0
  24. package/dist/cjs/data/bootstrap.js.map +1 -0
  25. package/dist/cjs/data/call.d.ts +16 -0
  26. package/dist/cjs/data/call.js +51 -0
  27. package/dist/cjs/data/call.js.map +1 -0
  28. package/dist/cjs/data/client.d.ts +92 -0
  29. package/dist/cjs/data/client.js +102 -0
  30. package/dist/cjs/data/client.js.map +1 -0
  31. package/dist/cjs/data/collection.d.ts +238 -0
  32. package/dist/cjs/data/collection.js +441 -0
  33. package/dist/cjs/data/collection.js.map +1 -0
  34. package/dist/cjs/data/context.d.ts +10 -0
  35. package/dist/cjs/data/context.js +39 -0
  36. package/dist/cjs/data/context.js.map +1 -0
  37. package/dist/cjs/data/declarations.d.ts +11 -0
  38. package/dist/cjs/data/declarations.js +18 -0
  39. package/dist/cjs/data/declarations.js.map +1 -0
  40. package/dist/cjs/data/define.d.ts +69 -0
  41. package/dist/cjs/data/define.js +31 -0
  42. package/dist/cjs/data/define.js.map +1 -0
  43. package/dist/cjs/data/error.d.ts +60 -0
  44. package/dist/cjs/data/error.js +184 -0
  45. package/dist/cjs/data/error.js.map +1 -0
  46. package/dist/cjs/data/index.d.ts +21 -0
  47. package/dist/cjs/data/index.js +43 -0
  48. package/dist/cjs/data/index.js.map +1 -0
  49. package/dist/cjs/data/schema.d.ts +82 -0
  50. package/dist/cjs/data/schema.js +607 -0
  51. package/dist/cjs/data/schema.js.map +1 -0
  52. package/dist/cjs/data/sort.d.ts +8 -0
  53. package/dist/cjs/data/sort.js +21 -0
  54. package/dist/cjs/data/sort.js.map +1 -0
  55. package/dist/cjs/files.d.ts +67 -0
  56. package/dist/cjs/files.js +119 -0
  57. package/dist/cjs/files.js.map +1 -0
  58. package/dist/cjs/framework-scope.d.ts +1 -0
  59. package/dist/cjs/framework-scope.js +14 -0
  60. package/dist/cjs/framework-scope.js.map +1 -0
  61. package/dist/cjs/index.d.ts +14 -0
  62. package/dist/cjs/index.js +33 -0
  63. package/dist/cjs/index.js.map +1 -0
  64. package/dist/cjs/mq/broker.d.ts +65 -0
  65. package/dist/cjs/mq/broker.js +115 -0
  66. package/dist/cjs/mq/broker.js.map +1 -0
  67. package/dist/cjs/mq/client.d.ts +37 -0
  68. package/dist/cjs/mq/client.js +321 -0
  69. package/dist/cjs/mq/client.js.map +1 -0
  70. package/dist/cjs/mq/index.d.ts +5 -0
  71. package/dist/cjs/mq/index.js +11 -0
  72. package/dist/cjs/mq/index.js.map +1 -0
  73. package/dist/cjs/mq/types.d.ts +48 -0
  74. package/dist/cjs/mq/types.js +3 -0
  75. package/dist/cjs/mq/types.js.map +1 -0
  76. package/dist/cjs/openapi/api.generated.d.ts +820 -0
  77. package/dist/cjs/openapi/api.generated.js +607 -0
  78. package/dist/cjs/openapi/api.generated.js.map +1 -0
  79. package/dist/cjs/openapi/client.d.ts +56 -0
  80. package/dist/cjs/openapi/client.js +219 -0
  81. package/dist/cjs/openapi/client.js.map +1 -0
  82. package/dist/cjs/openapi/codecs.generated.d.ts +2234 -0
  83. package/dist/cjs/openapi/codecs.generated.js +6 -0
  84. package/dist/cjs/openapi/codecs.generated.js.map +1 -0
  85. package/dist/cjs/openapi/index.d.ts +5 -0
  86. package/dist/cjs/openapi/index.js +12 -0
  87. package/dist/cjs/openapi/index.js.map +1 -0
  88. package/dist/cjs/openapi/types.generated.d.ts +3227 -0
  89. package/dist/cjs/openapi/types.generated.js +3 -0
  90. package/dist/cjs/openapi/types.generated.js.map +1 -0
  91. package/dist/cjs/package.json +1 -0
  92. package/dist/cjs/react.d.ts +9 -0
  93. package/dist/cjs/react.js +16 -0
  94. package/dist/cjs/react.js.map +1 -0
  95. package/dist/cjs/runtime-context.d.ts +9 -0
  96. package/dist/cjs/runtime-context.js +25 -0
  97. package/dist/cjs/runtime-context.js.map +1 -0
  98. package/dist/cjs/runtime-env.d.ts +1 -0
  99. package/dist/cjs/runtime-env.js +18 -0
  100. package/dist/cjs/runtime-env.js.map +1 -0
  101. package/dist/cjs/source.d.ts +39 -0
  102. package/dist/cjs/source.js +29 -0
  103. package/dist/cjs/source.js.map +1 -0
  104. package/dist/cjs/stream.d.ts +40 -0
  105. package/dist/cjs/stream.js +33 -0
  106. package/dist/cjs/stream.js.map +1 -0
  107. package/dist/cjs/uns-v2/client.d.ts +54 -0
  108. package/dist/cjs/uns-v2/client.js +177 -0
  109. package/dist/cjs/uns-v2/client.js.map +1 -0
  110. package/dist/cjs/uns-v2/codec.d.ts +11 -0
  111. package/dist/cjs/uns-v2/codec.js +290 -0
  112. package/dist/cjs/uns-v2/codec.js.map +1 -0
  113. package/dist/cjs/uns-v2/data-client.d.ts +10 -0
  114. package/dist/cjs/uns-v2/data-client.js +18 -0
  115. package/dist/cjs/uns-v2/data-client.js.map +1 -0
  116. package/dist/cjs/uns-v2/generated.d.ts +15551 -0
  117. package/dist/cjs/uns-v2/generated.js +139 -0
  118. package/dist/cjs/uns-v2/generated.js.map +1 -0
  119. package/dist/cjs/uns-v2/index.d.ts +5 -0
  120. package/dist/cjs/uns-v2/index.js +24 -0
  121. package/dist/cjs/uns-v2/index.js.map +1 -0
  122. package/dist/cjs/vue.d.ts +9 -0
  123. package/dist/cjs/vue.js +39 -0
  124. package/dist/cjs/vue.js.map +1 -0
  125. package/dist/esm/app-identity-contract.generated.d.ts +22 -0
  126. package/dist/esm/app-identity-contract.generated.js +48 -0
  127. package/dist/esm/app-identity-contract.generated.js.map +1 -0
  128. package/dist/esm/capabilities.d.ts +54 -0
  129. package/dist/esm/capabilities.js +129 -0
  130. package/dist/esm/capabilities.js.map +1 -0
  131. package/dist/esm/client.d.ts +604 -0
  132. package/dist/esm/client.js +32 -0
  133. package/dist/esm/client.js.map +1 -0
  134. package/dist/esm/cloud-server.d.ts +31 -0
  135. package/dist/esm/cloud-server.js +109 -0
  136. package/dist/esm/cloud-server.js.map +1 -0
  137. package/dist/esm/cloud-transport.d.ts +46 -0
  138. package/dist/esm/cloud-transport.js +187 -0
  139. package/dist/esm/cloud-transport.js.map +1 -0
  140. package/dist/esm/controls.d.ts +93 -0
  141. package/dist/esm/controls.js +163 -0
  142. package/dist/esm/controls.js.map +1 -0
  143. package/dist/esm/data/bootstrap.d.ts +66 -0
  144. package/dist/esm/data/bootstrap.js +277 -0
  145. package/dist/esm/data/bootstrap.js.map +1 -0
  146. package/dist/esm/data/call.d.ts +16 -0
  147. package/dist/esm/data/call.js +47 -0
  148. package/dist/esm/data/call.js.map +1 -0
  149. package/dist/esm/data/client.d.ts +92 -0
  150. package/dist/esm/data/client.js +99 -0
  151. package/dist/esm/data/client.js.map +1 -0
  152. package/dist/esm/data/collection.d.ts +238 -0
  153. package/dist/esm/data/collection.js +434 -0
  154. package/dist/esm/data/collection.js.map +1 -0
  155. package/dist/esm/data/context.d.ts +10 -0
  156. package/dist/esm/data/context.js +34 -0
  157. package/dist/esm/data/context.js.map +1 -0
  158. package/dist/esm/data/declarations.d.ts +11 -0
  159. package/dist/esm/data/declarations.js +10 -0
  160. package/dist/esm/data/declarations.js.map +1 -0
  161. package/dist/esm/data/define.d.ts +69 -0
  162. package/dist/esm/data/define.js +27 -0
  163. package/dist/esm/data/define.js.map +1 -0
  164. package/dist/esm/data/error.d.ts +60 -0
  165. package/dist/esm/data/error.js +178 -0
  166. package/dist/esm/data/error.js.map +1 -0
  167. package/dist/esm/data/index.d.ts +21 -0
  168. package/dist/esm/data/index.js +18 -0
  169. package/dist/esm/data/index.js.map +1 -0
  170. package/dist/esm/data/schema.d.ts +82 -0
  171. package/dist/esm/data/schema.js +596 -0
  172. package/dist/esm/data/schema.js.map +1 -0
  173. package/dist/esm/data/sort.d.ts +8 -0
  174. package/dist/esm/data/sort.js +18 -0
  175. package/dist/esm/data/sort.js.map +1 -0
  176. package/dist/esm/files.d.ts +67 -0
  177. package/dist/esm/files.js +113 -0
  178. package/dist/esm/files.js.map +1 -0
  179. package/dist/esm/framework-scope.d.ts +1 -0
  180. package/dist/esm/framework-scope.js +11 -0
  181. package/dist/esm/framework-scope.js.map +1 -0
  182. package/dist/esm/index.d.ts +14 -0
  183. package/dist/esm/index.js +10 -0
  184. package/dist/esm/index.js.map +1 -0
  185. package/dist/esm/mq/broker.d.ts +65 -0
  186. package/dist/esm/mq/broker.js +109 -0
  187. package/dist/esm/mq/broker.js.map +1 -0
  188. package/dist/esm/mq/client.d.ts +37 -0
  189. package/dist/esm/mq/client.js +314 -0
  190. package/dist/esm/mq/client.js.map +1 -0
  191. package/dist/esm/mq/index.d.ts +5 -0
  192. package/dist/esm/mq/index.js +3 -0
  193. package/dist/esm/mq/index.js.map +1 -0
  194. package/dist/esm/mq/types.d.ts +48 -0
  195. package/dist/esm/mq/types.js +2 -0
  196. package/dist/esm/mq/types.js.map +1 -0
  197. package/dist/esm/openapi/api.generated.d.ts +820 -0
  198. package/dist/esm/openapi/api.generated.js +603 -0
  199. package/dist/esm/openapi/api.generated.js.map +1 -0
  200. package/dist/esm/openapi/client.d.ts +56 -0
  201. package/dist/esm/openapi/client.js +210 -0
  202. package/dist/esm/openapi/client.js.map +1 -0
  203. package/dist/esm/openapi/codecs.generated.d.ts +2234 -0
  204. package/dist/esm/openapi/codecs.generated.js +3 -0
  205. package/dist/esm/openapi/codecs.generated.js.map +1 -0
  206. package/dist/esm/openapi/index.d.ts +5 -0
  207. package/dist/esm/openapi/index.js +3 -0
  208. package/dist/esm/openapi/index.js.map +1 -0
  209. package/dist/esm/openapi/types.generated.d.ts +3227 -0
  210. package/dist/esm/openapi/types.generated.js +2 -0
  211. package/dist/esm/openapi/types.generated.js.map +1 -0
  212. package/dist/esm/package.json +1 -0
  213. package/dist/esm/react.d.ts +9 -0
  214. package/dist/esm/react.js +12 -0
  215. package/dist/esm/react.js.map +1 -0
  216. package/dist/esm/runtime-context.d.ts +9 -0
  217. package/dist/esm/runtime-context.js +22 -0
  218. package/dist/esm/runtime-context.js.map +1 -0
  219. package/dist/esm/runtime-env.d.ts +1 -0
  220. package/dist/esm/runtime-env.js +15 -0
  221. package/dist/esm/runtime-env.js.map +1 -0
  222. package/dist/esm/source.d.ts +39 -0
  223. package/dist/esm/source.js +25 -0
  224. package/dist/esm/source.js.map +1 -0
  225. package/dist/esm/stream.d.ts +40 -0
  226. package/dist/esm/stream.js +29 -0
  227. package/dist/esm/stream.js.map +1 -0
  228. package/dist/esm/uns-v2/client.d.ts +54 -0
  229. package/dist/esm/uns-v2/client.js +170 -0
  230. package/dist/esm/uns-v2/client.js.map +1 -0
  231. package/dist/esm/uns-v2/codec.d.ts +11 -0
  232. package/dist/esm/uns-v2/codec.js +284 -0
  233. package/dist/esm/uns-v2/codec.js.map +1 -0
  234. package/dist/esm/uns-v2/data-client.d.ts +10 -0
  235. package/dist/esm/uns-v2/data-client.js +14 -0
  236. package/dist/esm/uns-v2/data-client.js.map +1 -0
  237. package/dist/esm/uns-v2/generated.d.ts +15551 -0
  238. package/dist/esm/uns-v2/generated.js +136 -0
  239. package/dist/esm/uns-v2/generated.js.map +1 -0
  240. package/dist/esm/uns-v2/index.d.ts +5 -0
  241. package/dist/esm/uns-v2/index.js +5 -0
  242. package/dist/esm/uns-v2/index.js.map +1 -0
  243. package/dist/esm/vue.d.ts +9 -0
  244. package/dist/esm/vue.js +36 -0
  245. package/dist/esm/vue.js.map +1 -0
  246. package/docs/acceptance-2026-10-22.md +88 -0
  247. package/package.json +242 -4
  248. package/skills/tier0-sdk-v2/SKILL.md +66 -0
  249. package/skills/tier0-sdk-v2/references/integration.md +72 -0
  250. package/skills/tier0-sdk-v2-agent/SKILL.md +73 -0
  251. package/skills/tier0-sdk-v2-agent/references/results.md +45 -0
  252. package/skills/tier0-sdk-v2-controls/SKILL.md +63 -0
  253. package/skills/tier0-sdk-v2-data/SKILL.md +57 -0
  254. package/skills/tier0-sdk-v2-data/references/consistency.md +70 -0
  255. package/skills/tier0-sdk-v2-data/references/errors.md +69 -0
  256. package/skills/tier0-sdk-v2-data/references/modeling.md +77 -0
  257. package/skills/tier0-sdk-v2-data/references/read-write.md +72 -0
  258. package/skills/tier0-sdk-v2-data/references/schema-evolution.md +36 -0
  259. package/skills/tier0-sdk-v2-files/SKILL.md +85 -0
  260. package/skills/tier0-sdk-v2-files/references/delete.md +22 -0
  261. package/skills/tier0-sdk-v2-files/references/download.md +49 -0
  262. package/skills/tier0-sdk-v2-files/references/multipart.md +42 -0
  263. package/skills/tier0-sdk-v2-files/references/upload.md +27 -0
  264. package/skills/tier0-sdk-v2-files/references/url.md +22 -0
  265. package/skills/tier0-sdk-v2-members/SKILL.md +56 -0
  266. package/skills/tier0-sdk-v2-members/references/app-members.md +41 -0
  267. package/skills/tier0-sdk-v2-members/references/platform-members.md +56 -0
  268. package/skills/tier0-sdk-v2-mq/SKILL.md +78 -0
  269. package/skills/tier0-sdk-v2-mq/references/quickstart.md +69 -0
  270. package/skills/tier0-sdk-v2-notifications/SKILL.md +42 -0
  271. package/skills/tier0-sdk-v2-notifications/references/get.md +34 -0
  272. package/skills/tier0-sdk-v2-notifications/references/send.md +72 -0
  273. package/skills/tier0-sdk-v2-source/SKILL.md +38 -0
  274. package/skills/tier0-sdk-v2-source/references/changes.md +40 -0
  275. package/skills/tier0-sdk-v2-source/references/create.md +63 -0
  276. package/skills/tier0-sdk-v2-source/references/delete.md +47 -0
  277. package/skills/tier0-sdk-v2-source/references/protocols.md +36 -0
  278. package/skills/tier0-sdk-v2-source/references/read.md +34 -0
  279. package/skills/tier0-sdk-v2-source/references/state.md +37 -0
  280. package/skills/tier0-sdk-v2-source/references/update.md +61 -0
  281. package/skills/tier0-sdk-v2-stream/SKILL.md +43 -0
  282. package/skills/tier0-sdk-v2-stream/references/create.md +55 -0
  283. package/skills/tier0-sdk-v2-stream/references/delete.md +35 -0
  284. package/skills/tier0-sdk-v2-stream/references/deploy.md +63 -0
  285. package/skills/tier0-sdk-v2-stream/references/lifecycle.md +25 -0
  286. package/skills/tier0-sdk-v2-stream/references/read.md +35 -0
  287. package/skills/tier0-sdk-v2-stream/references/update.md +35 -0
  288. package/skills/tier0-sdk-v2-system/SKILL.md +64 -0
  289. package/skills/tier0-sdk-v2-system/references/info.md +23 -0
  290. package/skills/tier0-sdk-v2-system/references/whoami.md +21 -0
  291. package/skills/tier0-sdk-v2-uns/SKILL.md +53 -0
  292. package/skills/tier0-sdk-v2-uns/references/create.md +85 -0
  293. package/skills/tier0-sdk-v2-uns/references/data-workflows.md +73 -0
  294. package/skills/tier0-sdk-v2-uns/references/delete.md +69 -0
  295. package/skills/tier0-sdk-v2-uns/references/namespace.md +75 -0
  296. package/skills/tier0-sdk-v2-uns/references/read.md +32 -0
  297. package/skills/tier0-sdk-v2-uns/references/restore.md +41 -0
  298. package/skills/tier0-sdk-v2-uns/references/update.md +86 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 FREEZONEX
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/NOTICE.md ADDED
@@ -0,0 +1,7 @@
1
+ # Source attribution
2
+
3
+ This SDK is distributed under the MIT license in LICENSE.
4
+
5
+ The UNS lossless codec, transport safeguards, Control and capability clients, MQTT implementation, App request identity verifier, and selected regression tests were adapted from FREEZONEX/Tier0-sdk at commit `3e43f33f4d13729e61b3d7e9bd8225a42f6843a8` (MIT). The original copyright notice is retained.
6
+
7
+ Public API contracts were obtained from FREEZONEX/Tier0-Backend at the revision pinned in `contracts/upstream.json`. The bundled App request identity contract was inherited from the same SDK revision; its upstream contract digest is preserved in the generated source. This provenance does not establish deployment or interoperability with a later gateway revision.
package/README.md CHANGED
@@ -1,3 +1,202 @@
1
- # Temporary Holding Version
1
+ # @tier0/sdk-v2
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Tier0 云端新架构的独立 TypeScript / JavaScript SDK。新仓库、新 npm 包,不覆盖 `@tier0/sdk`。
4
+
5
+ 当前版本 `0.1.0` 是待联调的首版源码,尚未发布 npm,也不表示开发环境已部署对应后端。要求 Node.js 20.19+。浏览器 HTTP、MQTT、React、Vue 和服务端身份验签分别提供独立入口。
6
+
7
+ ## 安装与初始化
8
+
9
+ 首发前在本仓库运行 `npm ci`、`npm run check`、`npm pack`,业务项目安装生成的 `.tgz`。发布后使用:
10
+
11
+ ```sh
12
+ npm install @tier0/sdk-v2
13
+ ```
14
+
15
+ ```ts
16
+ import { createClient } from '@tier0/sdk-v2';
17
+
18
+ // 服务端环境注入 TIER0_API_HOST 和 TIER0_API_KEY。
19
+ const tier0 = createClient();
20
+ const user = await tier0.system.whoami();
21
+ const platform = await tier0.system.info();
22
+ const capabilities = await tier0.capabilities.discover();
23
+ ```
24
+
25
+ 也可显式配置 `{ apiHost, apiKey, transportTimeoutMs, fetch }`,或提供 `getApiHost` / `getApiKey` 回调。裸域名默认使用 HTTPS;本地 HTTP 测试请显式写 `http://127.0.0.1:端口`。不自动向浏览器注入或读取 `VITE_` API Key。
26
+
27
+ `createClient()` 实例之间不共享配置;推荐在一个稳定身份的服务生命周期内复用实例。员工数据委托必须为每个请求创建新实例,传入受信网关的 `unsV2AppDataSubject`。App Key 只代表 App,不能替代当前用户身份,也不能下发到浏览器。浏览器页面应调用自己的服务端 API。
28
+
29
+ ## 能力与入口
30
+
31
+ | 入口 | 能力 |
32
+ | --- | --- |
33
+ | `tier0.source` | 数据源、连接文档、影响分析、版本历史与运行观测 |
34
+ | `tier0.stream` | Runtime programs、原生文档、校验、部署、回滚与运行记录 |
35
+ | `tier0.uns` | 目录、Topic、Collection、Record、Sample、事务与 App 数据上下文 |
36
+ | `tier0.system` | `whoami()`、`info()` |
37
+ | `tier0.members` | `listWorkspace()` 用于 Workspace 级成员选择;`listApp({ appId })` 查询能使用指定 App 的成员 |
38
+ | `tier0.notifications` | `send()`、`get()` |
39
+ | `tier0.files` | `upload()`、`uploadMultipart()`、`url()`、`download()`、`delete()`、`multipart` 原子接口 |
40
+ | `tier0.mqttAuth` | 创建、删除 MQTT 凭证 |
41
+ | `tier0.agent` | `analyses`、`canvases`、`cards`、`jobs`、`jobRuns`、`library`、`nodes`、`relations`、`results` |
42
+ | `tier0.capabilities` | 当前凭证可见的能力发现;就绪状态由服务端判断 |
43
+ | `tier0.controls` | Control 发现、描述、执行及结果未知错误 |
44
+ | `tier0.api` | 51 个普通 OpenAPI 的完整生成接口;通常优先使用上面的领域入口 |
45
+ | `@tier0/sdk-v2/mq` | MQTT WebSocket 客户端与 broker 地址工具;不进入根入口依赖图 |
46
+ | `@tier0/sdk-v2/source` | `createSourceClient()`,独立 Source 客户端 |
47
+ | `@tier0/sdk-v2/stream` | `createStreamClient()`,独立 Stream 客户端 |
48
+ | `@tier0/sdk-v2/react` | `useTier0Query()`、`useTier0Mutation()`,需要 React 和 TanStack Query |
49
+ | `@tier0/sdk-v2/vue` | `useTier0Request()`,需要 Vue 3 |
50
+ | `@tier0/sdk-v2/server` | `createCloudAppRequestVerifier()`,仅服务端加载 `node:crypto` |
51
+ | `@tier0/sdk-v2/data` | App 数据层:`defineCollection()` 声明集合、`createDataClient()` 首次访问时 ensure,Mongo 风格读写、原子批量与 `transact`、员工数据主体透传;仅服务端,需要 `zod` 4 |
52
+ | `@tier0/sdk-v2/data/define` | 集合声明与类型:`defineCollection()`、`Doc` / `NewDoc` 等、`compileCollection()`、`validateDocument()`;可进浏览器包,组件和 route 的客户端代码只从这里取声明和类型 |
53
+
54
+ 不保留 UNS v1、旧 Flow、`getCurrentProjectId()`、project 成员查询或 `/gw/reload`。Workspace 成员不等于能使用某个 App 的成员,不可用前者在客户端猜测 App 权限。
55
+
56
+ ## Source、Stream 与 UNS 分域
57
+
58
+ Source 负责连接外部系统,Stream 负责处理与运行,UNS 负责命名空间与业务数据。共用底层 106 个公开生成操作,业务入口按领域组织;Control 使用 `tier0.controls` 的专属契约。
59
+
60
+ ```ts
61
+ const sources = await tier0.source.documents.list({ page: 1, size: 20 });
62
+ const programs = await tier0.stream.programs.list({ page: 1, size: 20 });
63
+ const runtime = await tier0.stream.runtime.capabilities({});
64
+ ```
65
+
66
+ Source/Stream 仍保留 `{ code, msg, requestId, data }` 响应以及 `UnsV2Error` 错误类型。`source.documents` 是云端原生文档,`source.create/validate` 等是通用投影;`stream.programs` 与 `stream.documents` 使用不同文档结构,不可混用。保存、部署、运行成功分别判断。
67
+
68
+ 从最初提交迁移:`uns.sourceList` → `source.list`;`uns.sourceDocumentGet` → `source.documents.get`;`uns.streamProgramDeploy` → `stream.programs.deploy`;`uns.streamDocumentValidate` → `stream.documents.validate`。这些管理方法已移出主入口的 `uns`。底层 `createUnsV2Client()` 仍提供完整生成契约供契约工具使用;数据专用客户端可用 `createUnsDataClient()`。
69
+
70
+ 随包提供 12 个可独立发现的 Skill,包含完整流程、参数边界、错误处理与可类型检查的示例:[入口](skills/tier0-sdk-v2/SKILL.md)、[Source](skills/tier0-sdk-v2-source/SKILL.md)、[Stream](skills/tier0-sdk-v2-stream/SKILL.md)、[UNS](skills/tier0-sdk-v2-uns/SKILL.md)、[通知](skills/tier0-sdk-v2-notifications/SKILL.md)、[系统](skills/tier0-sdk-v2-system/SKILL.md)、[文件](skills/tier0-sdk-v2-files/SKILL.md)、[MQTT](skills/tier0-sdk-v2-mq/SKILL.md)、[成员](skills/tier0-sdk-v2-members/SKILL.md)、[Controls](skills/tier0-sdk-v2-controls/SKILL.md)、[Agent](skills/tier0-sdk-v2-agent/SKILL.md)、[App 数据](skills/tier0-sdk-v2-data/SKILL.md)。复杂流程的参考文档随 Skill 一起打包。
71
+
72
+ ## UNS 数据访问
73
+
74
+ ```ts
75
+ const context = await tier0.uns.dataAppContext({});
76
+ const page = await tier0.uns.recordFind({ collectionId: 'orders', limit: 20 });
77
+ const records = page.data;
78
+
79
+ const controller = new AbortController();
80
+ await tier0.uns.recordFind(
81
+ { collectionId: 'orders', limit: 20 },
82
+ { signal: controller.signal },
83
+ );
84
+ ```
85
+
86
+ 实际集合 ID 和有效权限从平台配置/数据上下文取得。管理操作中,App 凭证只能调用本 App 集合的 `appCollectionsEnsure` / `appCollectionsSchemaReplace` / `appCollectionsArchive` / `appCollectionsRestore`;SDK 中存在 `collectionCreate` 等其他管理方法,不表示 App 凭证有对应权限。App 数据授权 `appDataPolicyGet` / `appDataPolicyUpdate` 的调用方必须是:持有 `uns.write` 的登录会话、持有 `uns.write` 且 full_access、不绑定 App 的 personal / agent Key,或治理会话;运行时 App 凭证不能管理授权。Core-only 后台接口不导出到公开 SDK。
87
+
88
+ UNS 保留 `{ code, msg, requestId, data }` 完整响应。普通 v1 包装接口返回已解包的 `data`,通知/Control/能力发现返回服务端直接对象。业务错误即使 HTTP 为 200 也会抛出 `ApiError`。
89
+
90
+ `int64` 和普通 v1 整数字段使用 `number | bigint`:安全范围内返回 number,超出范围返回 bigint。UNS 任意 JSON 中无法无损表示的数字用 `UnsV2RawNumber`;传回 SDK 可保持原值。对外输出 JSON 时自行确定 bigint/精确数字的表示,不要直接 `JSON.stringify` 包含这些值的对象。
91
+
92
+ HTTP 操作不自动重试。`UnsV2OutcomeUnknownError`、`ControlResultUnknownError` 或 `ApiError.outcomeUnknown` 表示写操作可能已执行;先查询结果/作业,按业务意图保留原幂等键,不自动生成新键重放。查询与写入均可受配置超时约束。
93
+
94
+ ## 通知
95
+
96
+ ```ts
97
+ import { getCurrentAppId } from '@tier0/sdk-v2';
98
+
99
+ await tier0.notifications.send({
100
+ recipientUserId: '目标用户ID',
101
+ type: 'business',
102
+ title: '工单已完成',
103
+ content: '请查看处理结果。',
104
+ idempotencyKey: 'work-order-123-completed',
105
+ sender: { type: 'app', id: getCurrentAppId() },
106
+ });
107
+ ```
108
+
109
+ 不传 `channels` 时发送 `['web', 'mobile']`;`web` 包含 Web 与 Desktop;`[]` 只创建站内信。重复值去重,显式单渠道不补齐,不接受 `desktop`。App 身份读取平台注入的真实 `APP_ID`,不依赖 Folder 或 project。
110
+
111
+ ## 文件
112
+
113
+ ```ts
114
+ const saved = await tier0.files.upload(new File(['report'], 'report.txt'));
115
+ const stableReference = saved.filePath;
116
+ const { fileUrl } = await tier0.files.url({ filePath: stableReference });
117
+ const response = await tier0.files.download({ filePath: stableReference });
118
+ const bytes = await response.arrayBuffer();
119
+ ```
120
+
121
+ 保存 `filePath`,不把临时签名地址当作持久化引用。上传由平台签发地址后直传对象存储,平台 API Key 不传到存储域名;下载先获取签名地址,再匿名获取文件,避免认证重定向泄漏凭证。
122
+
123
+ 超过 100 MiB 自动使用分片上传,也可调用 `uploadMultipart(file, { partSize, signal, onProgress })`。首版顺序上传分片,不自动重试。中断后 `MultipartUploadError.session` 保留 uploadId、fileKey、已完成 parts 和 `completionAttempted`,可以通过 `files.multipart` 完成或终止;尝试过 complete 后必须先核对结果。未实现自动断点续传。
124
+
125
+ 返回的下载 `Response` 由调用方消费;文件传输配置超时约束取得响应头的阶段,后续流式读取由调用方管理。所有业务附件、头像、导入/导出文件使用平台文件存储,不以 App 本地目录作为持久化存储。
126
+
127
+ ## MQTT
128
+
129
+ ```ts
130
+ import { Tier0MQClient, toWebSocketUrl } from '@tier0/sdk-v2/mq';
131
+
132
+ const info = await tier0.system.info();
133
+ const credentials = await tier0.mqttAuth.create({ name: 'integration-client' });
134
+ const mq = new Tier0MQClient({
135
+ host: toWebSocketUrl(info.mqttBroker),
136
+ clientId: credentials.clientID,
137
+ username: credentials.username,
138
+ password: credentials.password,
139
+ });
140
+ await mq.connect();
141
+ mq.subscribe('平台授权的主题', (_topic, payload) => { /* 处理消息 */ });
142
+ ```
143
+
144
+ 完整凭证只在创建时返回一次。也支持从编码 Workspace 的平台 API Key 推导 MQTT 身份;无法解析的 Key 会拒绝连接,不回退到 Enterprise 身份。MQTT 自身的连接恢复/QoS 语义与 HTTP 的“不自动重试写入”是不同机制。
145
+
146
+ ## React / Vue
147
+
148
+ ```ts
149
+ import { useTier0Query, useTier0Mutation } from '@tier0/sdk-v2/react';
150
+
151
+ const orders = useTier0Query(tier0, ['orders'], (client, signal) =>
152
+ client.uns.recordFind({ collectionId: 'orders' }, { signal }));
153
+ const send = useTier0Mutation(tier0, (client, body: Parameters<typeof tier0.notifications.send>[0]) =>
154
+ client.notifications.send(body));
155
+ ```
156
+
157
+ React 需要 `QueryClientProvider`。保持客户端实例稳定;查询缓存按实例隔离,不跨凭证共享。查询 hook 只用于读取,写操作用 mutation。框架入口不会自动重试。
158
+
159
+ ```ts
160
+ import { useTier0Request } from '@tier0/sdk-v2/vue';
161
+ const orders = useTier0Request(tier0, (client, collectionId: string, signal) =>
162
+ client.uns.recordFind({ collectionId }, { signal }));
163
+ await orders.execute('orders');
164
+ ```
165
+
166
+ Vue 由 `execute()` 显式执行,后发请求的结果优先;取消不表示服务端写入已撤销。
167
+
168
+ ## 契约更新与验证
169
+
170
+ 上游:`FREEZONEX/Tier0-Backend`,固定提交 `fb35598ae8404e1a64bdc8a500341f12aeff2744`。`contracts/upstream.json` 记录来源和 SHA-256。
171
+
172
+ ```sh
173
+ npm ci
174
+ npm run check
175
+
176
+ # 更新时显式提供后端 checkout 与已提交版本;不会自动读取工作区未提交修改。
177
+ npm run sync:contracts -- ../Tier0-Backend <commit>
178
+ npm run generate
179
+ npm run check
180
+ ```
181
+
182
+ v1 来自网关 Swagger,并按实际 handler 补齐响应外层;UNS 来自 `contract_generated.go#ContractJSON` 中已经应用 Cloud 扩展的契约,结合 manifest/registry 生成。不能直接使用仍含 Enterprise 基础操作的 `share/unscontract/contract.json` 作为最终云端契约。
183
+
184
+ `npm run check` 包含契约一致性、Skill 注册及递归引用检查、所有 Skill TypeScript 示例的源码/安装包类型校验、单元和本地 HTTP 测试、ESM/CJS 构建、实际 npm 包安装、浏览器打包及导入验证。完整行为测试还会在独立 consumer 中对已安装的 `.tgz` 再跑一遍,导入目标严格指向包内 `dist`;包内调试映射包含源内容。当前 652 项测试包含全部 157 个公开操作的路由检查。路由检查使用本地 HTTP fixture,不等于每个操作的业务验收。
185
+
186
+ `tests/skill-workflows.test.ts` 直接提取 Markdown 示例,验证 Source/Stream/UNS 的创建、查询、修改、删除或归档恢复,影响分页和结果未知分支,以及通知请求、状态查询和成员展示。默认检查不调用线上接口。
187
+
188
+ 真实环境验收脚本使用刚安装的包,先通过 `whoami` 核对 Workspace,再执行选定操作。`TIER0_API_HOST` 必须指向 API 网关(开发环境为 `https://api-dev.tier0.cn`,不是网页域名 `dev.tier0.cn`),`TIER0_API_KEY` 由当前进程环境提供,不放进命令行参数或版本库。
189
+
190
+ ```sh
191
+ # consumer 路径使用 npm run check 最后输出的 .tmp/package-check-* 目录。
192
+ node scripts/check-live-readonly.mjs <consumer> <workspaceId> .tmp/live-readonly.json
193
+
194
+ # 仅在已授权的测试 Workspace 执行;会创建、修改、归档/删除本次测试资源。
195
+ # 可用 TIER0_TEST_DOMAINS 选择 source,stream,uns,files;追加 extended 扩展 UNS 验收。
196
+ node scripts/check-live-workflows.mjs <consumer> <workspaceId> .tmp/live-workflows.json --write-test-fixtures
197
+ node scripts/check-live-transports.mjs <consumer> <workspaceId> .tmp/live-transports.json --write-test-fixtures
198
+ ```
199
+
200
+ 写入验收不发布 Stream、不启用 Source、不发送通知。归档资源保留正常产品恢复能力;报告区分通过、服务端拒绝和未验证范围。分片上传失败会保留错误原因,确认尚未尝试 complete 时清理本次会话;完成结果未知时先对账。完整结果见 [2026-10-22 验收报告](docs/acceptance-2026-10-22.md)。
201
+
202
+ 首发前仍需:解决验收报告中的阻断并补齐未验收范围、App 脚手架切换精确依赖 `"@tier0/sdk-v2": "0.1.0"`、新 Skill 上传和 npm 发布授权。
@@ -0,0 +1,22 @@
1
+ export declare const APP_REQUEST_IDENTITY_CONTRACT: {
2
+ readonly version: "tier0.app-request-identity/v1";
3
+ readonly header: "X-Tier0-App-Identity";
4
+ readonly type: "tier0-app-request+jwt";
5
+ readonly algorithm: "EdDSA";
6
+ readonly issuer: "tier0-app-gateway";
7
+ readonly audience: "tier0-app-runtime";
8
+ readonly maxTokenBytes: 8192;
9
+ readonly maxBodyBytes: 65536;
10
+ readonly maxURIBytes: 8192;
11
+ readonly maxTTLSeconds: 30;
12
+ readonly clockSkewSeconds: 5;
13
+ readonly maxRoles: 32;
14
+ readonly maxRoleBytes: 128;
15
+ readonly maxKeys: 8;
16
+ readonly keyIDPattern: "^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$";
17
+ readonly appIDPattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$";
18
+ readonly requiredClaims: readonly ["ver", "iss", "aud", "sub", "workspaceID", "appID", "method", "requestURI", "bodySHA256", "iat", "exp", "jti", "roles"];
19
+ readonly methodPattern: "^[A-Z]{1,16}$";
20
+ readonly requiredHeaderFields: readonly ["alg", "typ", "kid"];
21
+ readonly publicKeyFields: readonly ["kty", "crv", "x", "kid"];
22
+ };
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.APP_REQUEST_IDENTITY_CONTRACT = void 0;
4
+ // Generated from SWE gatewayheader/app-request-identity.v1.json; do not edit.
5
+ // Source SHA-256: ac5ec2efb882395e63a46c9ec479de16c09943b88fc0bd906dd77c7f9f4bfaa3
6
+ exports.APP_REQUEST_IDENTITY_CONTRACT = {
7
+ "version": "tier0.app-request-identity/v1",
8
+ "header": "X-Tier0-App-Identity",
9
+ "type": "tier0-app-request+jwt",
10
+ "algorithm": "EdDSA",
11
+ "issuer": "tier0-app-gateway",
12
+ "audience": "tier0-app-runtime",
13
+ "maxTokenBytes": 8192,
14
+ "maxBodyBytes": 65536,
15
+ "maxURIBytes": 8192,
16
+ "maxTTLSeconds": 30,
17
+ "clockSkewSeconds": 5,
18
+ "maxRoles": 32,
19
+ "maxRoleBytes": 128,
20
+ "maxKeys": 8,
21
+ "keyIDPattern": "^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$",
22
+ "appIDPattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
23
+ "requiredClaims": [
24
+ "ver",
25
+ "iss",
26
+ "aud",
27
+ "sub",
28
+ "workspaceID",
29
+ "appID",
30
+ "method",
31
+ "requestURI",
32
+ "bodySHA256",
33
+ "iat",
34
+ "exp",
35
+ "jti",
36
+ "roles"
37
+ ],
38
+ "methodPattern": "^[A-Z]{1,16}$",
39
+ "requiredHeaderFields": [
40
+ "alg",
41
+ "typ",
42
+ "kid"
43
+ ],
44
+ "publicKeyFields": [
45
+ "kty",
46
+ "crv",
47
+ "x",
48
+ "kid"
49
+ ]
50
+ };
51
+ //# sourceMappingURL=app-identity-contract.generated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-identity-contract.generated.js","sourceRoot":"","sources":["../../src/app-identity-contract.generated.ts"],"names":[],"mappings":";;;AAAA,8EAA8E;AAC9E,mFAAmF;AACtE,QAAA,6BAA6B,GAAG;IAC3C,SAAS,EAAE,+BAA+B;IAC1C,QAAQ,EAAE,sBAAsB;IAChC,MAAM,EAAE,uBAAuB;IAC/B,WAAW,EAAE,OAAO;IACpB,QAAQ,EAAE,mBAAmB;IAC7B,UAAU,EAAE,mBAAmB;IAC/B,eAAe,EAAE,IAAI;IACrB,cAAc,EAAE,KAAK;IACrB,aAAa,EAAE,IAAI;IACnB,eAAe,EAAE,EAAE;IACnB,kBAAkB,EAAE,CAAC;IACrB,UAAU,EAAE,EAAE;IACd,cAAc,EAAE,GAAG;IACnB,SAAS,EAAE,CAAC;IACZ,cAAc,EAAE,mCAAmC;IACnD,cAAc,EAAE,2EAA2E;IAC3F,gBAAgB,EAAE;QAChB,KAAK;QACL,KAAK;QACL,KAAK;QACL,KAAK;QACL,aAAa;QACb,OAAO;QACP,QAAQ;QACR,YAAY;QACZ,YAAY;QACZ,KAAK;QACL,KAAK;QACL,KAAK;QACL,OAAO;KACR;IACD,eAAe,EAAE,eAAe;IAChC,sBAAsB,EAAE;QACtB,KAAK;QACL,KAAK;QACL,KAAK;KACN;IACD,iBAAiB,EAAE;QACjB,KAAK;QACL,KAAK;QACL,GAAG;QACH,KAAK;KACN;CACO,CAAC","sourcesContent":["// Generated from SWE gatewayheader/app-request-identity.v1.json; do not edit.\r\n// Source SHA-256: ac5ec2efb882395e63a46c9ec479de16c09943b88fc0bd906dd77c7f9f4bfaa3\r\nexport const APP_REQUEST_IDENTITY_CONTRACT = {\r\n \"version\": \"tier0.app-request-identity/v1\",\r\n \"header\": \"X-Tier0-App-Identity\",\r\n \"type\": \"tier0-app-request+jwt\",\r\n \"algorithm\": \"EdDSA\",\r\n \"issuer\": \"tier0-app-gateway\",\r\n \"audience\": \"tier0-app-runtime\",\r\n \"maxTokenBytes\": 8192,\r\n \"maxBodyBytes\": 65536,\r\n \"maxURIBytes\": 8192,\r\n \"maxTTLSeconds\": 30,\r\n \"clockSkewSeconds\": 5,\r\n \"maxRoles\": 32,\r\n \"maxRoleBytes\": 128,\r\n \"maxKeys\": 8,\r\n \"keyIDPattern\": \"^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$\",\r\n \"appIDPattern\": \"^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$\",\r\n \"requiredClaims\": [\r\n \"ver\",\r\n \"iss\",\r\n \"aud\",\r\n \"sub\",\r\n \"workspaceID\",\r\n \"appID\",\r\n \"method\",\r\n \"requestURI\",\r\n \"bodySHA256\",\r\n \"iat\",\r\n \"exp\",\r\n \"jti\",\r\n \"roles\"\r\n ],\r\n \"methodPattern\": \"^[A-Z]{1,16}$\",\r\n \"requiredHeaderFields\": [\r\n \"alg\",\r\n \"typ\",\r\n \"kid\"\r\n ],\r\n \"publicKeyFields\": [\r\n \"kty\",\r\n \"crv\",\r\n \"x\",\r\n \"kid\"\r\n ]\r\n} as const;\r\n"]}
@@ -0,0 +1,54 @@
1
+ import { type CloudTransportConfig } from './cloud-transport.js';
2
+ import { type HttpClient } from './openapi/client.js';
3
+ export type CapabilityCode = 'namespace.v2' | 'source.v1' | 'stream.v2' | 'control.v1' | 'control.invoke.v1';
4
+ export type CapabilityState = 'disabled' | 'not_supported' | 'unavailable' | 'readiness_unknown' | 'ready';
5
+ export type CapabilityAvailability = 'unavailable' | 'unknown' | 'available';
6
+ export interface PublicCapability {
7
+ code: CapabilityCode;
8
+ /** Public release and workspace gates; does not establish runtime readiness. */
9
+ releaseEnabled: boolean;
10
+ /** Server-assessed implementation/readiness, never inferred from releaseEnabled. */
11
+ enabled: boolean;
12
+ /** Authorization summary, not a grant for every individual Control code. */
13
+ allowed: boolean;
14
+ state: CapabilityState;
15
+ /** Not device online status or execution/ACK confirmation. */
16
+ availability: CapabilityAvailability;
17
+ contractVersions: string[];
18
+ }
19
+ export interface CapabilityDeprecation {
20
+ contract: string;
21
+ replacement?: string;
22
+ sunsetAt?: string;
23
+ }
24
+ export interface CapabilityDiscoverResponse {
25
+ product: 'cloud';
26
+ /** Trusted server configuration only; absent when unconfigured. */
27
+ productVersion?: string;
28
+ contractVersion: '1.0';
29
+ apiContractVersions: string[];
30
+ interpreterContractVersions: string[];
31
+ /** Public SDK contract labels, not npm package versions. */
32
+ sdkContractVersions: string[];
33
+ capabilities: PublicCapability[];
34
+ deprecations: CapabilityDeprecation[];
35
+ }
36
+ export interface CapabilityErrorInfo {
37
+ status?: number;
38
+ /** Gateway string code (including unknown future codes), or an SDK-local CAPABILITY_* code. */
39
+ errorCode: string;
40
+ }
41
+ export declare class CapabilityError extends Error {
42
+ readonly status?: number;
43
+ readonly errorCode: string;
44
+ readonly retryable = false;
45
+ constructor(message: string, info: CapabilityErrorInfo);
46
+ }
47
+ export declare class CapabilitiesClient {
48
+ private readonly transport;
49
+ constructor(resolveClient?: () => HttpClient, config?: CloudTransportConfig);
50
+ /** Workspace comes exclusively from the authenticated key. One POST, no automatic retries or caching. */
51
+ discover(): Promise<CapabilityDiscoverResponse>;
52
+ }
53
+ /** Uses configureClient()/runtime environment, resolving the host and workspace key on every call. */
54
+ export declare const capabilities: CapabilitiesClient;
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.capabilities = exports.CapabilitiesClient = exports.CapabilityError = void 0;
4
+ const cloud_transport_js_1 = require("./cloud-transport.js");
5
+ const client_js_1 = require("./openapi/client.js");
6
+ class CapabilityError extends Error {
7
+ status;
8
+ errorCode;
9
+ retryable = false;
10
+ constructor(message, info) {
11
+ super(message);
12
+ this.name = 'CapabilityError';
13
+ this.status = info.status;
14
+ this.errorCode = info.errorCode;
15
+ }
16
+ }
17
+ exports.CapabilityError = CapabilityError;
18
+ const contracts = {
19
+ 'namespace.v2': ['openapi/v2'],
20
+ 'source.v1': ['openapi/v1'],
21
+ 'stream.v2': ['tier0-stream/v2'],
22
+ 'control.v1': ['openapi/v1', 'control/v1'],
23
+ 'control.invoke.v1': ['openapi/v1', 'tier0-stream/v2', 'control/v1'],
24
+ };
25
+ function record(value) {
26
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
27
+ }
28
+ function text(value) {
29
+ return typeof value === 'string' && value.length > 0;
30
+ }
31
+ function strings(value) {
32
+ return Array.isArray(value) && value.every(text) && new Set(value).size === value.length;
33
+ }
34
+ /** Validate and explicitly project the frozen contract; unknown capabilities/extension fields are ignored. */
35
+ function discovery(value, status) {
36
+ const fail = (version = false) => {
37
+ throw new CapabilityError(version ? 'Unsupported capability contract version.' : 'Invalid capability discovery response.', {
38
+ status, errorCode: version ? 'CAPABILITY_UNSUPPORTED_VERSION' : 'CAPABILITY_PROTOCOL_ERROR',
39
+ });
40
+ };
41
+ if (!record(value))
42
+ return fail();
43
+ if (!text(value.product) || !text(value.contractVersion) ||
44
+ !strings(value.apiContractVersions) || !strings(value.interpreterContractVersions) || !strings(value.sdkContractVersions) ||
45
+ !Array.isArray(value.capabilities) || !Array.isArray(value.deprecations) ||
46
+ (value.productVersion !== undefined && !text(value.productVersion)))
47
+ return fail();
48
+ if (value.product !== 'cloud' || value.contractVersion !== '1.0' ||
49
+ !value.apiContractVersions.includes('openapi/v1') ||
50
+ !value.interpreterContractVersions.includes('tier0-stream/v2') ||
51
+ !value.sdkContractVersions.includes('control/v1'))
52
+ return fail(true);
53
+ const capabilities = [];
54
+ const seen = new Set();
55
+ for (const item of value.capabilities) {
56
+ if (!record(item) || !text(item.code))
57
+ return fail();
58
+ if (!Object.prototype.hasOwnProperty.call(contracts, item.code))
59
+ continue;
60
+ const code = item.code;
61
+ if (seen.has(code))
62
+ return fail();
63
+ seen.add(code);
64
+ if (typeof item.releaseEnabled !== 'boolean' || typeof item.enabled !== 'boolean' || typeof item.allowed !== 'boolean' ||
65
+ !['disabled', 'not_supported', 'unavailable', 'readiness_unknown', 'ready'].includes(item.state) ||
66
+ !['unavailable', 'unknown', 'available'].includes(item.availability) || !strings(item.contractVersions))
67
+ return fail();
68
+ if (contracts[code].some(version => !item.contractVersions.includes(version) ||
69
+ (version.startsWith('openapi/') && !value.apiContractVersions.includes(version))))
70
+ return fail(true);
71
+ const ready = item.state === 'ready';
72
+ const expectedAvailability = ready ? 'available' : item.state === 'readiness_unknown' ? 'unknown' : 'unavailable';
73
+ if (item.enabled !== ready || item.availability !== expectedAvailability ||
74
+ (ready && (!item.releaseEnabled || !item.allowed)) ||
75
+ (item.state === 'disabled' ? item.releaseEnabled : !item.releaseEnabled))
76
+ return fail();
77
+ capabilities.push({
78
+ code, releaseEnabled: item.releaseEnabled, enabled: item.enabled, allowed: item.allowed,
79
+ state: item.state, availability: item.availability,
80
+ contractVersions: [...item.contractVersions],
81
+ });
82
+ }
83
+ const deprecations = [];
84
+ for (const item of value.deprecations) {
85
+ if (!record(item) || !text(item.contract) ||
86
+ (item.replacement !== undefined && !text(item.replacement)) ||
87
+ (item.sunsetAt !== undefined && !text(item.sunsetAt)))
88
+ return fail();
89
+ deprecations.push({ contract: item.contract,
90
+ ...(item.replacement === undefined ? {} : { replacement: item.replacement }),
91
+ ...(item.sunsetAt === undefined ? {} : { sunsetAt: item.sunsetAt }),
92
+ });
93
+ }
94
+ return {
95
+ product: 'cloud', ...(value.productVersion === undefined ? {} : { productVersion: value.productVersion }),
96
+ contractVersion: '1.0', apiContractVersions: [...value.apiContractVersions],
97
+ interpreterContractVersions: [...value.interpreterContractVersions], sdkContractVersions: [...value.sdkContractVersions],
98
+ capabilities, deprecations,
99
+ };
100
+ }
101
+ class CapabilitiesClient {
102
+ transport;
103
+ constructor(resolveClient = client_js_1.getClient, config = {}) {
104
+ this.transport = new cloud_transport_js_1.CloudTransport(resolveClient, config);
105
+ }
106
+ /** Workspace comes exclusively from the authenticated key. One POST, no automatic retries or caching. */
107
+ async discover() {
108
+ if (arguments.length !== 0)
109
+ throw new TypeError('Tier0 SDK: capability discovery accepts no arguments.');
110
+ let response;
111
+ try {
112
+ response = await this.transport.post('/openapi/v1/capabilities/discover', {});
113
+ }
114
+ catch (error) {
115
+ if (!(error instanceof cloud_transport_js_1.CloudTransportError))
116
+ throw error;
117
+ throw new CapabilityError('Capability discovery HTTP exchange failed.', {
118
+ status: error.status, errorCode: `CAPABILITY_${error.kind}`,
119
+ });
120
+ }
121
+ const { value, status, ok } = response;
122
+ if (!ok) {
123
+ if (!record(value) || !text(value.errorCode) || typeof value.message !== 'string') {
124
+ throw new CapabilityError('Invalid capability error response.', { status, errorCode: 'CAPABILITY_PROTOCOL_ERROR' });
125
+ }
126
+ throw new CapabilityError(value.message, { status, errorCode: value.errorCode });
127
+ }
128
+ return discovery(value, status);
129
+ }
130
+ }
131
+ exports.CapabilitiesClient = CapabilitiesClient;
132
+ /** Uses configureClient()/runtime environment, resolving the host and workspace key on every call. */
133
+ exports.capabilities = new CapabilitiesClient();
134
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/capabilities.ts"],"names":[],"mappings":"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","sourcesContent":["import { CloudTransport, CloudTransportError, type CloudTransportConfig } from './cloud-transport.js';\r\nimport { getClient, type HttpClient } from './openapi/client.js';\r\n\r\nexport type CapabilityCode = 'namespace.v2' | 'source.v1' | 'stream.v2' | 'control.v1' | 'control.invoke.v1';\r\nexport type CapabilityState = 'disabled' | 'not_supported' | 'unavailable' | 'readiness_unknown' | 'ready';\r\nexport type CapabilityAvailability = 'unavailable' | 'unknown' | 'available';\r\n\r\nexport interface PublicCapability {\r\n code: CapabilityCode;\r\n /** Public release and workspace gates; does not establish runtime readiness. */\r\n releaseEnabled: boolean;\r\n /** Server-assessed implementation/readiness, never inferred from releaseEnabled. */\r\n enabled: boolean;\r\n /** Authorization summary, not a grant for every individual Control code. */\r\n allowed: boolean;\r\n state: CapabilityState;\r\n /** Not device online status or execution/ACK confirmation. */\r\n availability: CapabilityAvailability;\r\n contractVersions: string[];\r\n}\r\n\r\nexport interface CapabilityDeprecation {\r\n contract: string;\r\n replacement?: string;\r\n sunsetAt?: string;\r\n}\r\n\r\nexport interface CapabilityDiscoverResponse {\r\n product: 'cloud';\r\n /** Trusted server configuration only; absent when unconfigured. */\r\n productVersion?: string;\r\n contractVersion: '1.0';\r\n apiContractVersions: string[];\r\n interpreterContractVersions: string[];\r\n /** Public SDK contract labels, not npm package versions. */\r\n sdkContractVersions: string[];\r\n capabilities: PublicCapability[];\r\n deprecations: CapabilityDeprecation[];\r\n}\r\n\r\nexport interface CapabilityErrorInfo {\r\n status?: number;\r\n /** Gateway string code (including unknown future codes), or an SDK-local CAPABILITY_* code. */\r\n errorCode: string;\r\n}\r\n\r\nexport class CapabilityError extends Error {\r\n readonly status?: number;\r\n readonly errorCode: string;\r\n readonly retryable = false;\r\n\r\n constructor(message: string, info: CapabilityErrorInfo) {\r\n super(message);\r\n this.name = 'CapabilityError';\r\n this.status = info.status;\r\n this.errorCode = info.errorCode;\r\n }\r\n}\r\n\r\nconst contracts: Record<CapabilityCode, string[]> = {\r\n 'namespace.v2': ['openapi/v2'],\r\n 'source.v1': ['openapi/v1'],\r\n 'stream.v2': ['tier0-stream/v2'],\r\n 'control.v1': ['openapi/v1', 'control/v1'],\r\n 'control.invoke.v1': ['openapi/v1', 'tier0-stream/v2', 'control/v1'],\r\n};\r\n\r\nfunction record(value: unknown): value is Record<string, unknown> {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value);\r\n}\r\nfunction text(value: unknown): value is string {\r\n return typeof value === 'string' && value.length > 0;\r\n}\r\nfunction strings(value: unknown): value is string[] {\r\n return Array.isArray(value) && value.every(text) && new Set(value).size === value.length;\r\n}\r\n\r\n/** Validate and explicitly project the frozen contract; unknown capabilities/extension fields are ignored. */\r\nfunction discovery(value: unknown, status: number): CapabilityDiscoverResponse {\r\n const fail = (version = false): never => {\r\n throw new CapabilityError(version ? 'Unsupported capability contract version.' : 'Invalid capability discovery response.', {\r\n status, errorCode: version ? 'CAPABILITY_UNSUPPORTED_VERSION' : 'CAPABILITY_PROTOCOL_ERROR',\r\n });\r\n };\r\n if (!record(value)) return fail();\r\n if (!text(value.product) || !text(value.contractVersion) ||\r\n !strings(value.apiContractVersions) || !strings(value.interpreterContractVersions) || !strings(value.sdkContractVersions) ||\r\n !Array.isArray(value.capabilities) || !Array.isArray(value.deprecations) ||\r\n (value.productVersion !== undefined && !text(value.productVersion))) return fail();\r\n if (value.product !== 'cloud' || value.contractVersion !== '1.0' ||\r\n !value.apiContractVersions.includes('openapi/v1') ||\r\n !value.interpreterContractVersions.includes('tier0-stream/v2') ||\r\n !value.sdkContractVersions.includes('control/v1')) return fail(true);\r\n\r\n const capabilities: PublicCapability[] = [];\r\n const seen = new Set<string>();\r\n for (const item of value.capabilities) {\r\n if (!record(item) || !text(item.code)) return fail();\r\n if (!Object.prototype.hasOwnProperty.call(contracts, item.code)) continue;\r\n const code = item.code as CapabilityCode;\r\n if (seen.has(code)) return fail();\r\n seen.add(code);\r\n if (typeof item.releaseEnabled !== 'boolean' || typeof item.enabled !== 'boolean' || typeof item.allowed !== 'boolean' ||\r\n !['disabled', 'not_supported', 'unavailable', 'readiness_unknown', 'ready'].includes(item.state as string) ||\r\n !['unavailable', 'unknown', 'available'].includes(item.availability as string) || !strings(item.contractVersions)) return fail();\r\n if (contracts[code].some(version =>\r\n !(item.contractVersions as string[]).includes(version) ||\r\n (version.startsWith('openapi/') && !(value.apiContractVersions as string[]).includes(version)))) return fail(true);\r\n const ready = item.state === 'ready';\r\n const expectedAvailability = ready ? 'available' : item.state === 'readiness_unknown' ? 'unknown' : 'unavailable';\r\n if (item.enabled !== ready || item.availability !== expectedAvailability ||\r\n (ready && (!item.releaseEnabled || !item.allowed)) ||\r\n (item.state === 'disabled' ? item.releaseEnabled : !item.releaseEnabled)) return fail();\r\n capabilities.push({\r\n code, releaseEnabled: item.releaseEnabled, enabled: item.enabled, allowed: item.allowed,\r\n state: item.state as CapabilityState, availability: item.availability as CapabilityAvailability,\r\n contractVersions: [...item.contractVersions],\r\n });\r\n }\r\n const deprecations: CapabilityDeprecation[] = [];\r\n for (const item of value.deprecations) {\r\n if (!record(item) || !text(item.contract) ||\r\n (item.replacement !== undefined && !text(item.replacement)) ||\r\n (item.sunsetAt !== undefined && !text(item.sunsetAt))) return fail();\r\n deprecations.push({ contract: item.contract,\r\n ...(item.replacement === undefined ? {} : { replacement: item.replacement as string }),\r\n ...(item.sunsetAt === undefined ? {} : { sunsetAt: item.sunsetAt as string }),\r\n });\r\n }\r\n return {\r\n product: 'cloud', ...(value.productVersion === undefined ? {} : { productVersion: value.productVersion as string }),\r\n contractVersion: '1.0', apiContractVersions: [...value.apiContractVersions],\r\n interpreterContractVersions: [...value.interpreterContractVersions], sdkContractVersions: [...value.sdkContractVersions],\r\n capabilities, deprecations,\r\n };\r\n}\r\n\r\nexport class CapabilitiesClient {\r\n private readonly transport: CloudTransport;\r\n\r\n constructor(resolveClient: () => HttpClient = getClient, config: CloudTransportConfig = {}) {\r\n this.transport = new CloudTransport(resolveClient, config);\r\n }\r\n\r\n /** Workspace comes exclusively from the authenticated key. One POST, no automatic retries or caching. */\r\n async discover(): Promise<CapabilityDiscoverResponse> {\r\n if (arguments.length !== 0) throw new TypeError('Tier0 SDK: capability discovery accepts no arguments.');\r\n let response: Awaited<ReturnType<CloudTransport['post']>>;\r\n try {\r\n response = await this.transport.post('/openapi/v1/capabilities/discover', {});\r\n } catch (error) {\r\n if (!(error instanceof CloudTransportError)) throw error;\r\n throw new CapabilityError('Capability discovery HTTP exchange failed.', {\r\n status: error.status, errorCode: `CAPABILITY_${error.kind}`,\r\n });\r\n }\r\n const { value, status, ok } = response;\r\n if (!ok) {\r\n if (!record(value) || !text(value.errorCode) || typeof value.message !== 'string') {\r\n throw new CapabilityError('Invalid capability error response.', { status, errorCode: 'CAPABILITY_PROTOCOL_ERROR' });\r\n }\r\n throw new CapabilityError(value.message, { status, errorCode: value.errorCode });\r\n }\r\n return discovery(value, status);\r\n }\r\n}\r\n\r\n/** Uses configureClient()/runtime environment, resolving the host and workspace key on every call. */\r\nexport const capabilities = new CapabilitiesClient();\r\n"]}