@stigmer/sdk 3.35.0 → 3.37.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 (348) hide show
  1. package/activity.d.ts.map +1 -1
  2. package/activity.js.map +1 -1
  3. package/artifact-routing.d.ts.map +1 -1
  4. package/artifact-routing.js.map +1 -1
  5. package/authorization-config.d.ts.map +1 -1
  6. package/authorization-config.js.map +1 -1
  7. package/billing.d.ts.map +1 -1
  8. package/billing.js.map +1 -1
  9. package/config.d.ts.map +1 -1
  10. package/config.js.map +1 -1
  11. package/cursor-accounts.d.ts.map +1 -1
  12. package/cursor-accounts.js.map +1 -1
  13. package/ensure-identity-account.d.ts.map +1 -1
  14. package/ensure-identity-account.js.map +1 -1
  15. package/errors.d.ts.map +1 -1
  16. package/errors.js.map +1 -1
  17. package/execution/approval-provenance.d.ts.map +1 -1
  18. package/execution/approval-provenance.js.map +1 -1
  19. package/execution/conversation-rules.d.ts.map +1 -1
  20. package/execution/conversation-rules.js.map +1 -1
  21. package/execution/execution-phases.d.ts.map +1 -1
  22. package/execution/execution-phases.js.map +1 -1
  23. package/execution/file-review-fold.d.ts.map +1 -1
  24. package/execution/file-review-fold.js.map +1 -1
  25. package/execution/to-display-file-change.d.ts.map +1 -1
  26. package/execution/to-display-file-change.js.map +1 -1
  27. package/execution/tool-view.d.ts.map +1 -1
  28. package/execution/tool-view.js.map +1 -1
  29. package/execution/transcript.d.ts.map +1 -1
  30. package/execution/transcript.js.map +1 -1
  31. package/gen/agent.d.ts.map +1 -1
  32. package/gen/agent.js.map +1 -1
  33. package/gen/agentchannel.d.ts.map +1 -1
  34. package/gen/agentchannel.js.map +1 -1
  35. package/gen/agentexecution.d.ts.map +1 -1
  36. package/gen/agentexecution.js.map +1 -1
  37. package/gen/agentinstance.d.ts.map +1 -1
  38. package/gen/agentinstance.js.map +1 -1
  39. package/gen/agentshare.d.ts.map +1 -1
  40. package/gen/agentshare.js.map +1 -1
  41. package/gen/apikey.d.ts.map +1 -1
  42. package/gen/apikey.js.map +1 -1
  43. package/gen/artifact.d.ts.map +1 -1
  44. package/gen/artifact.js.map +1 -1
  45. package/gen/authorization-config.d.ts.map +1 -1
  46. package/gen/authorization-config.js +2 -2
  47. package/gen/authorization-config.js.map +1 -1
  48. package/gen/bidi-stream.d.ts.map +1 -1
  49. package/gen/bidi-stream.js.map +1 -1
  50. package/gen/channelapp.d.ts.map +1 -1
  51. package/gen/channelapp.js.map +1 -1
  52. package/gen/client.d.ts.map +1 -1
  53. package/gen/client.js.map +1 -1
  54. package/gen/environment.d.ts.map +1 -1
  55. package/gen/environment.js.map +1 -1
  56. package/gen/errors.d.ts.map +1 -1
  57. package/gen/errors.js.map +1 -1
  58. package/gen/executioncontext.d.ts.map +1 -1
  59. package/gen/executioncontext.js.map +1 -1
  60. package/gen/iampolicy.d.ts.map +1 -1
  61. package/gen/iampolicy.js.map +1 -1
  62. package/gen/identityaccount.d.ts.map +1 -1
  63. package/gen/identityaccount.js.map +1 -1
  64. package/gen/identityprovider.d.ts.map +1 -1
  65. package/gen/identityprovider.js.map +1 -1
  66. package/gen/invitation.d.ts.map +1 -1
  67. package/gen/invitation.js.map +1 -1
  68. package/gen/license.d.ts.map +1 -1
  69. package/gen/license.js.map +1 -1
  70. package/gen/mcpserver.d.ts.map +1 -1
  71. package/gen/mcpserver.js.map +1 -1
  72. package/gen/memory.d.ts.map +1 -1
  73. package/gen/memory.js.map +1 -1
  74. package/gen/oauthapp.d.ts.map +1 -1
  75. package/gen/oauthapp.js.map +1 -1
  76. package/gen/organization.d.ts.map +1 -1
  77. package/gen/organization.js.map +1 -1
  78. package/gen/plan.d.ts.map +1 -1
  79. package/gen/plan.js.map +1 -1
  80. package/gen/platformclient.d.ts.map +1 -1
  81. package/gen/platformclient.js.map +1 -1
  82. package/gen/plugin.d.ts.map +1 -1
  83. package/gen/plugin.js.map +1 -1
  84. package/gen/proto-utils.d.ts.map +1 -1
  85. package/gen/proto-utils.js.map +1 -1
  86. package/gen/resource-availability.d.ts.map +1 -1
  87. package/gen/resource-availability.js.map +1 -1
  88. package/gen/schedule.d.ts.map +1 -1
  89. package/gen/schedule.js.map +1 -1
  90. package/gen/session.d.ts.map +1 -1
  91. package/gen/session.js.map +1 -1
  92. package/gen/skill.d.ts.map +1 -1
  93. package/gen/skill.js.map +1 -1
  94. package/gen/subscription.d.ts.map +1 -1
  95. package/gen/subscription.js.map +1 -1
  96. package/gen/team.d.ts.map +1 -1
  97. package/gen/team.js.map +1 -1
  98. package/gen/types.d.ts.map +1 -1
  99. package/gen/types.js.map +1 -1
  100. package/gen/workflow.d.ts.map +1 -1
  101. package/gen/workflow.js.map +1 -1
  102. package/gen/workflowexecution.d.ts.map +1 -1
  103. package/gen/workflowexecution.js.map +1 -1
  104. package/gen/workflowinstance.d.ts.map +1 -1
  105. package/gen/workflowinstance.js.map +1 -1
  106. package/github.d.ts.map +1 -1
  107. package/github.js.map +1 -1
  108. package/guest-auth.d.ts.map +1 -1
  109. package/guest-auth.js.map +1 -1
  110. package/iam-principal.d.ts +6 -0
  111. package/iam-principal.d.ts.map +1 -1
  112. package/iam-principal.js +19 -0
  113. package/iam-principal.js.map +1 -1
  114. package/iam-role.d.ts.map +1 -1
  115. package/iam-role.js.map +1 -1
  116. package/index.d.ts +1 -1
  117. package/index.d.ts.map +1 -1
  118. package/index.js +1 -1
  119. package/index.js.map +1 -1
  120. package/internal/interceptors.d.ts.map +1 -1
  121. package/internal/interceptors.js.map +1 -1
  122. package/manifest/client.d.ts.map +1 -1
  123. package/manifest/client.js.map +1 -1
  124. package/manifest/document.d.ts.map +1 -1
  125. package/manifest/document.js.map +1 -1
  126. package/manifest/index.d.ts.map +1 -1
  127. package/manifest/index.js.map +1 -1
  128. package/manifest/parse.d.ts.map +1 -1
  129. package/manifest/parse.js.map +1 -1
  130. package/manifest/redaction.d.ts.map +1 -1
  131. package/manifest/redaction.js.map +1 -1
  132. package/manifest/registry.d.ts.map +1 -1
  133. package/manifest/registry.js.map +1 -1
  134. package/manifest/serialize.d.ts.map +1 -1
  135. package/manifest/serialize.js.map +1 -1
  136. package/mcpserver-connect.d.ts.map +1 -1
  137. package/mcpserver-connect.js.map +1 -1
  138. package/node.d.ts.map +1 -1
  139. package/node.js.map +1 -1
  140. package/package.json +2 -2
  141. package/platform-client-auth.d.ts.map +1 -1
  142. package/platform-client-auth.js.map +1 -1
  143. package/platform.d.ts.map +1 -1
  144. package/platform.js.map +1 -1
  145. package/plugin.d.ts.map +1 -1
  146. package/plugin.js.map +1 -1
  147. package/provider-standing.d.ts.map +1 -1
  148. package/provider-standing.js.map +1 -1
  149. package/resource-availability.d.ts.map +1 -1
  150. package/resource-availability.js.map +1 -1
  151. package/runner-adapter.d.ts.map +1 -1
  152. package/runner-adapter.js.map +1 -1
  153. package/search.d.ts.map +1 -1
  154. package/search.js.map +1 -1
  155. package/session.d.ts.map +1 -1
  156. package/session.js.map +1 -1
  157. package/sharing.d.ts.map +1 -1
  158. package/sharing.js.map +1 -1
  159. package/skill.d.ts.map +1 -1
  160. package/skill.js.map +1 -1
  161. package/src/gen/authorization-config.ts +2 -2
  162. package/src/iam-principal.ts +24 -0
  163. package/src/index.ts +1 -0
  164. package/stigmer.d.ts.map +1 -1
  165. package/stigmer.js.map +1 -1
  166. package/transport.d.ts.map +1 -1
  167. package/transport.js.map +1 -1
  168. package/__tests__/billing.test.d.ts +0 -2
  169. package/__tests__/billing.test.d.ts.map +0 -1
  170. package/__tests__/billing.test.js +0 -120
  171. package/__tests__/billing.test.js.map +0 -1
  172. package/__tests__/config.test.d.ts +0 -2
  173. package/__tests__/config.test.d.ts.map +0 -1
  174. package/__tests__/config.test.js +0 -35
  175. package/__tests__/config.test.js.map +0 -1
  176. package/__tests__/ensure-identity-account.test.d.ts +0 -2
  177. package/__tests__/ensure-identity-account.test.d.ts.map +0 -1
  178. package/__tests__/ensure-identity-account.test.js +0 -108
  179. package/__tests__/ensure-identity-account.test.js.map +0 -1
  180. package/__tests__/errors.test.d.ts +0 -2
  181. package/__tests__/errors.test.d.ts.map +0 -1
  182. package/__tests__/errors.test.js +0 -228
  183. package/__tests__/errors.test.js.map +0 -1
  184. package/__tests__/gen/errors.test.d.ts +0 -2
  185. package/__tests__/gen/errors.test.d.ts.map +0 -1
  186. package/__tests__/gen/errors.test.js +0 -97
  187. package/__tests__/gen/errors.test.js.map +0 -1
  188. package/__tests__/gen/invitation-client.test.d.ts +0 -2
  189. package/__tests__/gen/invitation-client.test.d.ts.map +0 -1
  190. package/__tests__/gen/invitation-client.test.js +0 -106
  191. package/__tests__/gen/invitation-client.test.js.map +0 -1
  192. package/__tests__/gen/proto-utils.test.d.ts +0 -2
  193. package/__tests__/gen/proto-utils.test.d.ts.map +0 -1
  194. package/__tests__/gen/proto-utils.test.js +0 -85
  195. package/__tests__/gen/proto-utils.test.js.map +0 -1
  196. package/__tests__/gen/session-client.test.d.ts +0 -2
  197. package/__tests__/gen/session-client.test.d.ts.map +0 -1
  198. package/__tests__/gen/session-client.test.js +0 -152
  199. package/__tests__/gen/session-client.test.js.map +0 -1
  200. package/__tests__/guest-auth.test.d.ts +0 -2
  201. package/__tests__/guest-auth.test.d.ts.map +0 -1
  202. package/__tests__/guest-auth.test.js +0 -223
  203. package/__tests__/guest-auth.test.js.map +0 -1
  204. package/__tests__/iam-principal.test.d.ts +0 -2
  205. package/__tests__/iam-principal.test.d.ts.map +0 -1
  206. package/__tests__/iam-principal.test.js +0 -65
  207. package/__tests__/iam-principal.test.js.map +0 -1
  208. package/__tests__/manifest.test.d.ts +0 -2
  209. package/__tests__/manifest.test.d.ts.map +0 -1
  210. package/__tests__/manifest.test.js +0 -306
  211. package/__tests__/manifest.test.js.map +0 -1
  212. package/__tests__/mcpserver-connect.test.d.ts +0 -2
  213. package/__tests__/mcpserver-connect.test.d.ts.map +0 -1
  214. package/__tests__/mcpserver-connect.test.js +0 -146
  215. package/__tests__/mcpserver-connect.test.js.map +0 -1
  216. package/__tests__/node.test.d.ts +0 -2
  217. package/__tests__/node.test.d.ts.map +0 -1
  218. package/__tests__/node.test.js +0 -67
  219. package/__tests__/node.test.js.map +0 -1
  220. package/__tests__/platform-client-auth.test.d.ts +0 -2
  221. package/__tests__/platform-client-auth.test.d.ts.map +0 -1
  222. package/__tests__/platform-client-auth.test.js +0 -59
  223. package/__tests__/platform-client-auth.test.js.map +0 -1
  224. package/__tests__/platform.test.d.ts +0 -2
  225. package/__tests__/platform.test.d.ts.map +0 -1
  226. package/__tests__/platform.test.js +0 -52
  227. package/__tests__/platform.test.js.map +0 -1
  228. package/__tests__/plugin.test.d.ts +0 -2
  229. package/__tests__/plugin.test.d.ts.map +0 -1
  230. package/__tests__/plugin.test.js +0 -74
  231. package/__tests__/plugin.test.js.map +0 -1
  232. package/__tests__/resource-availability.test.d.ts +0 -2
  233. package/__tests__/resource-availability.test.d.ts.map +0 -1
  234. package/__tests__/resource-availability.test.js +0 -80
  235. package/__tests__/resource-availability.test.js.map +0 -1
  236. package/__tests__/runner-adapter.test.d.ts +0 -2
  237. package/__tests__/runner-adapter.test.d.ts.map +0 -1
  238. package/__tests__/runner-adapter.test.js +0 -88
  239. package/__tests__/runner-adapter.test.js.map +0 -1
  240. package/__tests__/session.test.d.ts +0 -6
  241. package/__tests__/session.test.d.ts.map +0 -1
  242. package/__tests__/session.test.js +0 -50
  243. package/__tests__/session.test.js.map +0 -1
  244. package/__tests__/sharing.test.d.ts +0 -2
  245. package/__tests__/sharing.test.d.ts.map +0 -1
  246. package/__tests__/sharing.test.js +0 -106
  247. package/__tests__/sharing.test.js.map +0 -1
  248. package/__tests__/skill.test.d.ts +0 -2
  249. package/__tests__/skill.test.d.ts.map +0 -1
  250. package/__tests__/skill.test.js +0 -117
  251. package/__tests__/skill.test.js.map +0 -1
  252. package/__tests__/stigmer.test.d.ts +0 -2
  253. package/__tests__/stigmer.test.d.ts.map +0 -1
  254. package/__tests__/stigmer.test.js +0 -127
  255. package/__tests__/stigmer.test.js.map +0 -1
  256. package/__tests__/update-input-roundtrip.test.d.ts +0 -2
  257. package/__tests__/update-input-roundtrip.test.d.ts.map +0 -1
  258. package/__tests__/update-input-roundtrip.test.js +0 -775
  259. package/__tests__/update-input-roundtrip.test.js.map +0 -1
  260. package/__tests__/update-input.test.d.ts +0 -2
  261. package/__tests__/update-input.test.d.ts.map +0 -1
  262. package/__tests__/update-input.test.js +0 -188
  263. package/__tests__/update-input.test.js.map +0 -1
  264. package/execution/__tests__/approval-provenance.test.d.ts +0 -2
  265. package/execution/__tests__/approval-provenance.test.d.ts.map +0 -1
  266. package/execution/__tests__/approval-provenance.test.js +0 -42
  267. package/execution/__tests__/approval-provenance.test.js.map +0 -1
  268. package/execution/__tests__/file-review-fold.corpus.test.d.ts +0 -2
  269. package/execution/__tests__/file-review-fold.corpus.test.d.ts.map +0 -1
  270. package/execution/__tests__/file-review-fold.corpus.test.js +0 -82
  271. package/execution/__tests__/file-review-fold.corpus.test.js.map +0 -1
  272. package/execution/__tests__/file-review-fold.test.d.ts +0 -2
  273. package/execution/__tests__/file-review-fold.test.d.ts.map +0 -1
  274. package/execution/__tests__/file-review-fold.test.js +0 -184
  275. package/execution/__tests__/file-review-fold.test.js.map +0 -1
  276. package/execution/__tests__/to-display-file-change.test.d.ts +0 -2
  277. package/execution/__tests__/to-display-file-change.test.d.ts.map +0 -1
  278. package/execution/__tests__/to-display-file-change.test.js +0 -81
  279. package/execution/__tests__/to-display-file-change.test.js.map +0 -1
  280. package/execution/__tests__/tool-view.file-changes.test.d.ts +0 -2
  281. package/execution/__tests__/tool-view.file-changes.test.d.ts.map +0 -1
  282. package/execution/__tests__/tool-view.file-changes.test.js +0 -86
  283. package/execution/__tests__/tool-view.file-changes.test.js.map +0 -1
  284. package/execution/__tests__/tool-view.fixtures.test.d.ts +0 -2
  285. package/execution/__tests__/tool-view.fixtures.test.d.ts.map +0 -1
  286. package/execution/__tests__/tool-view.fixtures.test.js +0 -152
  287. package/execution/__tests__/tool-view.fixtures.test.js.map +0 -1
  288. package/execution/__tests__/tool-view.output-ref.test.d.ts +0 -2
  289. package/execution/__tests__/tool-view.output-ref.test.d.ts.map +0 -1
  290. package/execution/__tests__/tool-view.output-ref.test.js +0 -64
  291. package/execution/__tests__/tool-view.output-ref.test.js.map +0 -1
  292. package/execution/__tests__/tool-view.read.test.d.ts +0 -2
  293. package/execution/__tests__/tool-view.read.test.d.ts.map +0 -1
  294. package/execution/__tests__/tool-view.read.test.js +0 -56
  295. package/execution/__tests__/tool-view.read.test.js.map +0 -1
  296. package/execution/__tests__/tool-view.search.test.d.ts +0 -2
  297. package/execution/__tests__/tool-view.search.test.d.ts.map +0 -1
  298. package/execution/__tests__/tool-view.search.test.js +0 -200
  299. package/execution/__tests__/tool-view.search.test.js.map +0 -1
  300. package/execution/__tests__/tool-view.shell.test.d.ts +0 -2
  301. package/execution/__tests__/tool-view.shell.test.d.ts.map +0 -1
  302. package/execution/__tests__/tool-view.shell.test.js +0 -104
  303. package/execution/__tests__/tool-view.shell.test.js.map +0 -1
  304. package/execution/__tests__/transcript.test.d.ts +0 -2
  305. package/execution/__tests__/transcript.test.d.ts.map +0 -1
  306. package/execution/__tests__/transcript.test.js +0 -591
  307. package/execution/__tests__/transcript.test.js.map +0 -1
  308. package/node.test.d.ts +0 -2
  309. package/node.test.d.ts.map +0 -1
  310. package/node.test.js +0 -35
  311. package/node.test.js.map +0 -1
  312. package/src/__tests__/billing.test.ts +0 -146
  313. package/src/__tests__/config.test.ts +0 -52
  314. package/src/__tests__/ensure-identity-account.test.ts +0 -146
  315. package/src/__tests__/errors.test.ts +0 -349
  316. package/src/__tests__/gen/errors.test.ts +0 -138
  317. package/src/__tests__/gen/invitation-client.test.ts +0 -132
  318. package/src/__tests__/gen/proto-utils.test.ts +0 -99
  319. package/src/__tests__/gen/session-client.test.ts +0 -208
  320. package/src/__tests__/guest-auth.test.ts +0 -287
  321. package/src/__tests__/iam-principal.test.ts +0 -82
  322. package/src/__tests__/manifest.test.ts +0 -362
  323. package/src/__tests__/mcpserver-connect.test.ts +0 -181
  324. package/src/__tests__/node.test.ts +0 -74
  325. package/src/__tests__/platform-client-auth.test.ts +0 -76
  326. package/src/__tests__/platform.test.ts +0 -74
  327. package/src/__tests__/plugin.test.ts +0 -92
  328. package/src/__tests__/resource-availability.test.ts +0 -118
  329. package/src/__tests__/runner-adapter.test.ts +0 -122
  330. package/src/__tests__/session.test.ts +0 -66
  331. package/src/__tests__/sharing.test.ts +0 -159
  332. package/src/__tests__/skill.test.ts +0 -150
  333. package/src/__tests__/stigmer.test.ts +0 -170
  334. package/src/__tests__/update-input-roundtrip.test.ts +0 -1007
  335. package/src/__tests__/update-input.test.ts +0 -250
  336. package/src/execution/__tests__/approval-provenance.test.ts +0 -60
  337. package/src/execution/__tests__/file-review-fold.corpus.test.ts +0 -127
  338. package/src/execution/__tests__/file-review-fold.test.ts +0 -281
  339. package/src/execution/__tests__/to-display-file-change.test.ts +0 -106
  340. package/src/execution/__tests__/tool-view.file-changes.test.ts +0 -100
  341. package/src/execution/__tests__/tool-view.fixtures.test.ts +0 -225
  342. package/src/execution/__tests__/tool-view.output-ref.test.ts +0 -76
  343. package/src/execution/__tests__/tool-view.read.test.ts +0 -71
  344. package/src/execution/__tests__/tool-view.search.test.ts +0 -264
  345. package/src/execution/__tests__/tool-view.shell.test.ts +0 -127
  346. package/src/execution/__tests__/transcript.golden.md +0 -100
  347. package/src/execution/__tests__/transcript.test.ts +0 -697
  348. package/src/node.test.ts +0 -38
@@ -1,223 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
- import { create } from "@bufbuild/protobuf";
3
- import { MintGuestTokenResponseSchema } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/token_pb";
4
- import { ConnectError, Code } from "@connectrpc/connect";
5
- // Intercept the token client so no transport is exercised. The mock
6
- // preserves the real module (create/Code/ConnectError) and only stubs
7
- // createClient, which GuestAuth uses to build its RPC client.
8
- const mintGuestToken = vi.fn();
9
- vi.mock("@connectrpc/connect", async (importOriginal) => {
10
- const actual = await importOriginal();
11
- return {
12
- ...actual,
13
- createClient: () => ({ mintGuestToken }),
14
- };
15
- });
16
- import { createGuestAuth, GuestAuth } from "../guest-auth";
17
- const CONFIG = {
18
- baseUrl: "https://api.stigmer.ai",
19
- org: "acme",
20
- slug: "support-agent",
21
- };
22
- function createMemoryStorage() {
23
- const store = new Map();
24
- return {
25
- store,
26
- getItem: (key) => store.get(key) ?? null,
27
- setItem: (key, value) => {
28
- store.set(key, value);
29
- },
30
- };
31
- }
32
- function mintResponse(overrides) {
33
- return create(MintGuestTokenResponseSchema, {
34
- accessToken: overrides?.accessToken ?? "guest-jwt-1",
35
- tokenType: "Bearer",
36
- expiresIn: overrides?.expiresIn ?? 900,
37
- guestCookieId: overrides?.guestCookieId ?? "cookie-abc",
38
- });
39
- }
40
- beforeEach(() => {
41
- mintGuestToken.mockReset();
42
- vi.useFakeTimers();
43
- });
44
- afterEach(() => {
45
- vi.useRealTimers();
46
- });
47
- describe("createGuestAuth", () => {
48
- it("throws when baseUrl is missing", () => {
49
- expect(() => createGuestAuth({ ...CONFIG, baseUrl: "" })).toThrow("baseUrl is required");
50
- });
51
- it("throws when org is missing", () => {
52
- expect(() => createGuestAuth({ ...CONFIG, org: "" })).toThrow("org is required");
53
- });
54
- it("throws when slug is missing", () => {
55
- expect(() => createGuestAuth({ ...CONFIG, slug: "" })).toThrow("slug is required");
56
- });
57
- it("returns a GuestAuth instance with valid config", () => {
58
- expect(createGuestAuth(CONFIG)).toBeInstanceOf(GuestAuth);
59
- });
60
- });
61
- describe("GuestAuth.getAccessToken", () => {
62
- it("mints on first call and sends an empty guest id", async () => {
63
- mintGuestToken.mockResolvedValue(mintResponse());
64
- const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
65
- const token = await auth.getAccessToken();
66
- expect(token).toBe("guest-jwt-1");
67
- expect(mintGuestToken).toHaveBeenCalledTimes(1);
68
- expect(mintGuestToken.mock.calls[0][0]).toMatchObject({
69
- org: "acme",
70
- slug: "support-agent",
71
- guestCookieId: "",
72
- // No embedOrigin configured (the unframed hosted page): the field
73
- // must stay empty so the server's absence-means-exempt rule applies.
74
- embedOrigin: "",
75
- });
76
- });
77
- it("passes the configured embedOrigin through to every mint", async () => {
78
- mintGuestToken.mockResolvedValue(mintResponse());
79
- const auth = createGuestAuth({
80
- ...CONFIG,
81
- storage: createMemoryStorage(),
82
- embedOrigin: "https://docs.example.com",
83
- });
84
- await auth.getAccessToken();
85
- // Expire the cached token, forcing a re-mint — the origin must persist.
86
- vi.advanceTimersByTime(900_000);
87
- await auth.getAccessToken();
88
- expect(mintGuestToken).toHaveBeenCalledTimes(2);
89
- for (const call of mintGuestToken.mock.calls) {
90
- expect(call[0]).toMatchObject({ embedOrigin: "https://docs.example.com" });
91
- }
92
- });
93
- it("passes the configured linkToken through to every mint", async () => {
94
- mintGuestToken.mockResolvedValue(mintResponse());
95
- const auth = createGuestAuth({
96
- ...CONFIG,
97
- storage: createMemoryStorage(),
98
- linkToken: "tok123",
99
- });
100
- await auth.getAccessToken();
101
- // Expire the cached token, forcing a re-mint — the token must persist
102
- // so a locked link keeps working across silent re-mints.
103
- vi.advanceTimersByTime(900_000);
104
- await auth.getAccessToken();
105
- expect(mintGuestToken).toHaveBeenCalledTimes(2);
106
- for (const call of mintGuestToken.mock.calls) {
107
- expect(call[0]).toMatchObject({ linkToken: "tok123" });
108
- }
109
- });
110
- it("sends an empty linkToken when none is configured (plain link)", async () => {
111
- mintGuestToken.mockResolvedValue(mintResponse());
112
- const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
113
- await auth.getAccessToken();
114
- expect(mintGuestToken.mock.calls[0][0]).toMatchObject({ linkToken: "" });
115
- });
116
- it("rejects with permission-denied when the embed origin is refused", async () => {
117
- mintGuestToken.mockRejectedValue(new ConnectError("This agent can\u2019t be embedded on this site.", Code.PermissionDenied));
118
- const auth = createGuestAuth({
119
- ...CONFIG,
120
- storage: createMemoryStorage(),
121
- embedOrigin: "https://evil.example.com",
122
- });
123
- await expect(auth.getAccessToken()).rejects.toMatchObject({
124
- code: "permission-denied",
125
- });
126
- });
127
- it("persists the server-issued guest id and presents it on re-mint", async () => {
128
- const storage = createMemoryStorage();
129
- mintGuestToken.mockResolvedValue(mintResponse({ guestCookieId: "cookie-abc" }));
130
- const auth = createGuestAuth({ ...CONFIG, storage });
131
- await auth.getAccessToken();
132
- expect(storage.store.get("stigmer:guest-id:acme")).toBe("cookie-abc");
133
- expect(auth.guestCookieId).toBe("cookie-abc");
134
- // Expire the cached token, forcing a second mint.
135
- vi.advanceTimersByTime(900_000);
136
- await auth.getAccessToken();
137
- expect(mintGuestToken).toHaveBeenCalledTimes(2);
138
- expect(mintGuestToken.mock.calls[1][0]).toMatchObject({
139
- guestCookieId: "cookie-abc",
140
- });
141
- });
142
- it("restores a persisted guest id from a prior visit", async () => {
143
- const storage = createMemoryStorage();
144
- storage.setItem("stigmer:guest-id:acme", "cookie-from-last-visit");
145
- mintGuestToken.mockResolvedValue(mintResponse());
146
- const auth = createGuestAuth({ ...CONFIG, storage });
147
- await auth.getAccessToken();
148
- expect(mintGuestToken.mock.calls[0][0]).toMatchObject({
149
- guestCookieId: "cookie-from-last-visit",
150
- });
151
- });
152
- it("returns the cached token while it is fresh", async () => {
153
- mintGuestToken.mockResolvedValue(mintResponse());
154
- const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
155
- await auth.getAccessToken();
156
- // 13 minutes into a 15-minute token: still beyond the 60s skew.
157
- vi.advanceTimersByTime(13 * 60_000);
158
- const token = await auth.getAccessToken();
159
- expect(token).toBe("guest-jwt-1");
160
- expect(mintGuestToken).toHaveBeenCalledTimes(1);
161
- });
162
- it("re-mints when the cached token is within the expiry skew", async () => {
163
- mintGuestToken
164
- .mockResolvedValueOnce(mintResponse({ accessToken: "guest-jwt-1" }))
165
- .mockResolvedValueOnce(mintResponse({ accessToken: "guest-jwt-2" }));
166
- const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
167
- await auth.getAccessToken();
168
- // 30 seconds of life left — inside the 60s skew window.
169
- vi.advanceTimersByTime(900_000 - 30_000);
170
- const token = await auth.getAccessToken();
171
- expect(token).toBe("guest-jwt-2");
172
- expect(mintGuestToken).toHaveBeenCalledTimes(2);
173
- });
174
- it("collapses concurrent callers into a single mint", async () => {
175
- let release;
176
- mintGuestToken.mockImplementation(() => new Promise((resolve) => { release = resolve; }));
177
- const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
178
- const first = auth.getAccessToken();
179
- const second = auth.getAccessToken();
180
- release(mintResponse());
181
- await expect(first).resolves.toBe("guest-jwt-1");
182
- await expect(second).resolves.toBe("guest-jwt-1");
183
- expect(mintGuestToken).toHaveBeenCalledTimes(1);
184
- });
185
- it("rejects with a wrapped StigmerError when sharing is revoked", async () => {
186
- mintGuestToken.mockRejectedValue(new ConnectError("agent not found", Code.NotFound));
187
- const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
188
- try {
189
- await auth.getAccessToken();
190
- expect.fail("should have thrown");
191
- }
192
- catch (e) {
193
- expect(e).toHaveProperty("name", "StigmerError");
194
- expect(e).toHaveProperty("code", "not-found");
195
- }
196
- });
197
- it("recovers after a failed mint instead of caching the failure", async () => {
198
- mintGuestToken
199
- .mockRejectedValueOnce(new ConnectError("unavailable", Code.Unavailable))
200
- .mockResolvedValueOnce(mintResponse());
201
- const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
202
- await expect(auth.getAccessToken()).rejects.toMatchObject({
203
- code: "unavailable",
204
- });
205
- await expect(auth.getAccessToken()).resolves.toBe("guest-jwt-1");
206
- expect(mintGuestToken).toHaveBeenCalledTimes(2);
207
- });
208
- it("still mints when storage throws", async () => {
209
- const brokenStorage = {
210
- getItem: () => {
211
- throw new Error("storage disabled");
212
- },
213
- setItem: () => {
214
- throw new Error("storage disabled");
215
- },
216
- };
217
- mintGuestToken.mockResolvedValue(mintResponse());
218
- const auth = createGuestAuth({ ...CONFIG, storage: brokenStorage });
219
- await expect(auth.getAccessToken()).resolves.toBe("guest-jwt-1");
220
- expect(auth.guestCookieId).toBeNull();
221
- });
222
- });
223
- //# sourceMappingURL=guest-auth.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"guest-auth.test.js","sourceRoot":"","sources":["../../src/__tests__/guest-auth.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=iam-principal.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"iam-principal.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/iam-principal.test.ts"],"names":[],"mappings":""}
@@ -1,65 +0,0 @@
1
- /**
2
- * Pins the grantee vocabulary (`iam-principal.ts`) and the team half of the
3
- * authorization config (`authorization-config.ts`):
4
- *
5
- * - a team is always granted as `team:<id>#member` and a person always
6
- * unqualified, because the server's revoke matches the qualifier
7
- * exactly and a dropped `#member` revokes nothing while reporting
8
- * success;
9
- * - reading an access-list entry back is the inverse of building one,
10
- * and anything else (a structural principal, another team qualifier)
11
- * is refused rather than guessed at;
12
- * - a team may only ever be offered a subset of a person's roles, never
13
- * `owner`, and nothing on `organization` (the circular grant the
14
- * model's membership bound forbids).
15
- */
16
- import { describe, expect, it } from "vitest";
17
- import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
18
- import { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
19
- import { getGrantableRoles, getTeamGrantableRoles, hasTeamGrantableRoles, isRoleTeamGrantable, } from "../authorization-config";
20
- import { TEAM_GRANTABLE_ROLES } from "../gen/authorization-config";
21
- import { granteeFromView, granteeRef, personGrantee, teamGrantee, } from "../iam-principal";
22
- describe("granteeRef — the one spelling of a grantee on the wire", () => {
23
- it("names a team as its members", () => {
24
- const ref = granteeRef(teamGrantee("tm_sre"));
25
- expect([ref.kind, ref.id, ref.relation]).toEqual(["team", "tm_sre", "member"]);
26
- });
27
- it("names a person with no relation qualifier", () => {
28
- const ref = granteeRef(personGrantee("ida_alice"));
29
- expect([ref.kind, ref.id, ref.relation]).toEqual(["identity_account", "ida_alice", ""]);
30
- });
31
- });
32
- describe("granteeFromView — reading an access-list entry back", () => {
33
- it("round-trips both grantees through their wire reference", () => {
34
- for (const grantee of [teamGrantee("tm_sre"), personGrantee("ida_alice")]) {
35
- expect(granteeFromView(granteeRef(grantee))).toEqual(grantee);
36
- }
37
- });
38
- it("refuses what it would misname: a team without its members qualifier, a qualified person, a structural principal, an empty id", () => {
39
- expect(granteeFromView({ kind: "team", id: "tm_sre", relation: "" })).toBeUndefined();
40
- expect(granteeFromView({ kind: "team", id: "tm_sre", relation: "maintainer" })).toBeUndefined();
41
- expect(granteeFromView({ kind: "identity_account", id: "ida_alice", relation: "member" })).toBeUndefined();
42
- expect(granteeFromView({ kind: "organization", id: "acme", relation: "" })).toBeUndefined();
43
- expect(granteeFromView({ kind: "identity_account", id: "", relation: "" })).toBeUndefined();
44
- });
45
- });
46
- describe("team grantable roles", () => {
47
- it("are, for every kind, a subset of the person's roles and never owner", () => {
48
- for (const [kind, teamRoles] of TEAM_GRANTABLE_ROLES) {
49
- const personRoles = getGrantableRoles(kind);
50
- for (const role of teamRoles) {
51
- expect(personRoles).toContain(role);
52
- expect(role).not.toBe(IamRole.owner);
53
- }
54
- }
55
- });
56
- it("list nothing on organization, so an organization is never shared with a team", () => {
57
- expect(hasTeamGrantableRoles(ApiResourceKind.organization)).toBe(false);
58
- expect(getTeamGrantableRoles(ApiResourceKind.organization)).toEqual([]);
59
- });
60
- it("answer per role on a kind a team may be shared", () => {
61
- expect(isRoleTeamGrantable(ApiResourceKind.agent, IamRole.viewer)).toBe(true);
62
- expect(isRoleTeamGrantable(ApiResourceKind.agent, IamRole.owner)).toBe(false);
63
- });
64
- });
65
- //# sourceMappingURL=iam-principal.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"iam-principal.test.js","sourceRoot":"","sources":["../../src/__tests__/iam-principal.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=manifest.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"manifest.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/manifest.test.ts"],"names":[],"mappings":""}
@@ -1,306 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { clone, create, equals } from "@bufbuild/protobuf";
3
- import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
4
- import { EnvironmentSchema } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/api_pb";
5
- import { ScheduleSchema } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/api_pb";
6
- import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
7
- import { ApiResourceMetadataSchema } from "@stigmer/protos/ai/stigmer/commons/apiresource/metadata_pb";
8
- import { parse as parseYaml } from "yaml";
9
- import { parseManifest } from "../manifest/parse";
10
- import { serializeManifest } from "../manifest/serialize";
11
- import { manifestDocumentForResource } from "../manifest/document";
12
- import { manifestKinds, manifestHandlerForYamlKind } from "../manifest/registry";
13
- /**
14
- * Manifest engine contract tests.
15
- *
16
- * The engine's core promise is *round-trip fidelity against the generated
17
- * proto schemas*: any resource the server returns serializes to YAML that
18
- * parses back to the same proto (minus system-managed state), and any
19
- * repo-authored manifest (snake_case fields, `apiVersion` spelling) parses
20
- * to a proto the `apply` RPC accepts. Fixtures mirror the real manifests
21
- * in the whatsapp-doctor-assistant dogfooding repo.
22
- */
23
- // ---------------------------------------------------------------------------
24
- // Fixtures — shaped like the whatsapp-doctor-assistant repo manifests
25
- // ---------------------------------------------------------------------------
26
- const AGENT_YAML = `
27
- apiVersion: agentic.stigmer.ai/v1
28
- kind: Agent
29
- metadata:
30
- name: clinic-patient-assistant
31
- org: rakeshreddi098
32
- spec:
33
- description: Patient-facing WhatsApp assistant for the clinic.
34
- instructions: |
35
- You are the appointment assistant for the clinic.
36
- Short messages. One question at a time.
37
- `;
38
- const ENVIRONMENT_YAML = `
39
- apiVersion: agentic.stigmer.ai/v1
40
- kind: Environment
41
- metadata:
42
- name: clinic-patient-db
43
- org: rakeshreddi098
44
- spec:
45
- description: "Clinic records access for the patient assistant"
46
- data:
47
- POSTGRES_CONNECTION_URL:
48
- value: "postgresql://patient_role:secret@host:5432/postgres"
49
- is_secret: true
50
- description: "Supabase Postgres connection URL for patient_role"
51
- `;
52
- const AGENT_CHANNEL_YAML = `
53
- apiVersion: agentic.stigmer.ai/v1
54
- kind: AgentChannel
55
- metadata:
56
- name: clinic-patient-whatsapp
57
- org: rakeshreddi098
58
- spec:
59
- agent_ref:
60
- kind: agent
61
- org: rakeshreddi098
62
- slug: clinic-patient-assistant
63
- enabled: true
64
- whatsapp:
65
- phone_number_id: "1234567890"
66
- app_ref:
67
- kind: channel_app
68
- org: rakeshreddi098
69
- slug: hosipital
70
- environment_refs:
71
- - kind: environment
72
- org: rakeshreddi098
73
- slug: clinic-patient-db
74
- `;
75
- // ---------------------------------------------------------------------------
76
- // parseManifest
77
- // ---------------------------------------------------------------------------
78
- describe("parseManifest", () => {
79
- it("parses a snake_case Agent manifest into a full Agent proto", () => {
80
- const docs = parseManifest(AGENT_YAML);
81
- expect(docs).toHaveLength(1);
82
- const doc = docs[0];
83
- expect(doc.handler.yamlKind).toBe("Agent");
84
- expect(doc.name).toBe("clinic-patient-assistant");
85
- expect(doc.org).toBe("rakeshreddi098");
86
- const agent = doc.message;
87
- expect(agent.spec?.description).toBe("Patient-facing WhatsApp assistant for the clinic.");
88
- expect(agent.spec?.instructions).toContain("appointment assistant");
89
- });
90
- it("parses an AgentChannel manifest with enum-valued resource refs", () => {
91
- const docs = parseManifest(AGENT_CHANNEL_YAML);
92
- expect(docs).toHaveLength(1);
93
- expect(docs[0].handler.yamlKind).toBe("AgentChannel");
94
- expect(docs[0].slug).toBe("clinic-patient-whatsapp");
95
- });
96
- it("sorts multi-document manifests into dependency apply order", () => {
97
- // Authored channel-first; the Environment must still apply first.
98
- const docs = parseManifest(`${AGENT_CHANNEL_YAML}\n---\n${ENVIRONMENT_YAML}`);
99
- expect(docs.map((d) => d.handler.yamlKind)).toEqual([
100
- "Environment",
101
- "AgentChannel",
102
- ]);
103
- });
104
- it("injects the target org when the document omits it", () => {
105
- const yaml = AGENT_YAML.replace(" org: rakeshreddi098\n", "");
106
- const docs = parseManifest(yaml, { org: "acme" });
107
- expect(docs[0].org).toBe("acme");
108
- expect(docs[0].warning).toBeUndefined();
109
- });
110
- it("honors the document org and warns when it differs from the target", () => {
111
- const docs = parseManifest(AGENT_YAML, { org: "acme" });
112
- expect(docs[0].org).toBe("rakeshreddi098");
113
- expect(docs[0].warning).toContain('"rakeshreddi098"');
114
- expect(docs[0].warning).toContain('"acme"');
115
- });
116
- it("rejects unknown fields loudly (strict schema contract)", () => {
117
- const yaml = AGENT_YAML.replace("spec:", "spec:\n instrctions: typo");
118
- expect(() => parseManifest(yaml)).toThrow(/Invalid Agent/);
119
- });
120
- it("rejects a document without a kind", () => {
121
- expect(() => parseManifest("metadata:\n name: x\n")).toThrow(/'kind'/);
122
- });
123
- it("rejects unsupported kinds with the supported list", () => {
124
- expect(() => parseManifest("kind: Skill\nmetadata:\n name: x\n")).toThrow(/Unsupported resource kind "Skill".*Agent/s);
125
- });
126
- it("rejects empty input with actionable guidance", () => {
127
- expect(() => parseManifest(" \n")).toThrow(/empty/i);
128
- });
129
- it("rejects malformed YAML", () => {
130
- expect(() => parseManifest("kind: Agent\n bad indent: [")).toThrow(/Invalid YAML/);
131
- });
132
- });
133
- // ---------------------------------------------------------------------------
134
- // serializeManifest
135
- // ---------------------------------------------------------------------------
136
- describe("serializeManifest", () => {
137
- const agent = create(AgentSchema, {
138
- apiVersion: "agentic.stigmer.ai/v1",
139
- kind: "Agent",
140
- metadata: {
141
- id: "agt_01example",
142
- name: "clinic-patient-assistant",
143
- slug: "clinic-patient-assistant",
144
- org: "rakeshreddi098",
145
- version: { id: "ver_01", message: "server-managed" },
146
- },
147
- spec: {
148
- description: "Patient-facing WhatsApp assistant.",
149
- instructions: "Short messages.\nOne question at a time.\n",
150
- },
151
- status: { defaultInstanceId: "agi_01example" },
152
- });
153
- it("emits the canonical envelope: apiVersion spelling, no status", () => {
154
- const yaml = serializeManifest(agent);
155
- const doc = parseYaml(yaml);
156
- expect(Object.keys(doc)[0]).toBe("apiVersion");
157
- expect(doc.apiVersion).toBe("agentic.stigmer.ai/v1");
158
- expect(doc.kind).toBe("Agent");
159
- expect(doc.status).toBeUndefined();
160
- expect(yaml).not.toContain("api_version:");
161
- });
162
- it("keeps metadata.id but strips server-managed metadata.version", () => {
163
- const doc = parseYaml(serializeManifest(agent));
164
- expect(doc.metadata.id).toBe("agt_01example");
165
- expect(doc.metadata.version).toBeUndefined();
166
- });
167
- it("fills apiVersion and kind from the registry when the proto omits them", () => {
168
- const bare = create(AgentSchema, {
169
- metadata: { name: "x", org: "acme" },
170
- });
171
- const doc = parseYaml(serializeManifest(bare));
172
- expect(doc.apiVersion).toBe("agentic.stigmer.ai/v1");
173
- expect(doc.kind).toBe("Agent");
174
- });
175
- it("round-trips through parseManifest to an equal proto", () => {
176
- const docs = parseManifest(serializeManifest(agent));
177
- expect(docs).toHaveLength(1);
178
- // The round-tripped proto matches the original minus system-managed
179
- // state (status, metadata.version) — exactly what apply consumes.
180
- const expected = create(AgentSchema, {
181
- ...agent,
182
- status: undefined,
183
- metadata: { ...agent.metadata, version: undefined },
184
- });
185
- expect(equals(AgentSchema, docs[0].message, expected)).toBe(true);
186
- });
187
- it("round-trips Environment secret values byte-identically", () => {
188
- const env = create(EnvironmentSchema, {
189
- metadata: { name: "clinic-patient-db", org: "rakeshreddi098" },
190
- spec: {
191
- data: {
192
- POSTGRES_CONNECTION_URL: {
193
- value: "***REDACTED***",
194
- isSecret: true,
195
- description: "Supabase Postgres connection URL",
196
- },
197
- },
198
- },
199
- });
200
- const docs = parseManifest(serializeManifest(env));
201
- const roundTripped = docs[0].message;
202
- expect(roundTripped.spec?.data.POSTGRES_CONNECTION_URL?.value).toBe("***REDACTED***");
203
- expect(roundTripped.spec?.data.POSTGRES_CONNECTION_URL?.isSecret).toBe(true);
204
- });
205
- it("rejects messages of kinds outside the registry", () => {
206
- // ApiResourceMetadata is a real proto message but not a manifest kind.
207
- const notAResource = create(ApiResourceMetadataSchema, { name: "x" });
208
- expect(() => serializeManifest(notAResource)).toThrow(/not.*registry/i);
209
- });
210
- });
211
- // ---------------------------------------------------------------------------
212
- // manifestDocumentForResource
213
- // ---------------------------------------------------------------------------
214
- describe("manifestDocumentForResource", () => {
215
- // Shaped like a server-returned schedule: full metadata (including
216
- // fields the curated ScheduleInput cannot express, like tags) and a
217
- // populated status — the exact input of a lossless partial edit.
218
- const schedule = create(ScheduleSchema, {
219
- apiVersion: "agentic.stigmer.ai/v1",
220
- kind: "Schedule",
221
- metadata: {
222
- id: "sch_01example",
223
- name: "daily-fee-reminders",
224
- slug: "daily-fee-reminders",
225
- org: "isc",
226
- tags: ["billing"],
227
- labels: { team: "ops" },
228
- },
229
- spec: {
230
- cron: "0 9 * * *",
231
- timeZone: "Asia/Kolkata",
232
- enabled: true,
233
- target: {
234
- case: "agent",
235
- value: {
236
- agentRef: { kind: ApiResourceKind.agent, org: "isc", slug: "fee-reminder" },
237
- message: "Send today's fee reminders.",
238
- },
239
- },
240
- },
241
- status: { consecutiveFailures: 2, pausedReason: "" },
242
- });
243
- it("wraps a fetched proto untouched — the lossless edit contract", () => {
244
- const flipped = clone(ScheduleSchema, schedule);
245
- flipped.spec.enabled = false;
246
- const doc = manifestDocumentForResource(flipped);
247
- expect(doc.handler.yamlKind).toBe("Schedule");
248
- expect(doc.name).toBe("daily-fee-reminders");
249
- expect(doc.slug).toBe("daily-fee-reminders");
250
- expect(doc.org).toBe("isc");
251
- // Identity, not a copy: nothing is re-serialized or down-converted,
252
- // so every field survives (the ScheduleInput path would drop tags).
253
- expect(doc.message).toBe(flipped);
254
- const expected = clone(ScheduleSchema, schedule);
255
- expected.spec.enabled = false;
256
- expect(equals(ScheduleSchema, doc.message, expected)).toBe(true);
257
- });
258
- it("falls back to name when the proto has no slug", () => {
259
- const bare = create(AgentSchema, { metadata: { name: "x", org: "acme" } });
260
- const doc = manifestDocumentForResource(bare);
261
- expect(doc.slug).toBe("x");
262
- });
263
- it("rejects messages of kinds outside the registry", () => {
264
- const notAResource = create(ApiResourceMetadataSchema, { name: "x" });
265
- expect(() => manifestDocumentForResource(notAResource)).toThrow(/not.*registry/i);
266
- });
267
- it("rejects a resource without metadata.name", () => {
268
- const nameless = create(ScheduleSchema, { metadata: { org: "acme" } });
269
- expect(() => manifestDocumentForResource(nameless)).toThrow(/metadata\.name/);
270
- });
271
- });
272
- // ---------------------------------------------------------------------------
273
- // Registry invariants
274
- // ---------------------------------------------------------------------------
275
- describe("manifest registry", () => {
276
- it("every handler resolves by its own YAML kind", () => {
277
- for (const handler of manifestKinds()) {
278
- expect(manifestHandlerForYamlKind(handler.yamlKind)).toBe(handler);
279
- }
280
- });
281
- it("apply order is strictly increasing (no accidental ties)", () => {
282
- const orders = manifestKinds().map((h) => h.applyOrder);
283
- for (let i = 1; i < orders.length; i++) {
284
- expect(orders[i]).toBeGreaterThan(orders[i - 1]);
285
- }
286
- });
287
- it("covers the kinds the console flows depend on", () => {
288
- for (const kind of ["Agent", "McpServer", "Workflow", "Environment", "AgentChannel", "ChannelApp"]) {
289
- expect(manifestHandlerForYamlKind(kind), `missing handler for ${kind}`).toBeDefined();
290
- }
291
- });
292
- it("declares the updateVisibility binding on exactly the guarded-RPC kinds (oss#573)", () => {
293
- // Visibility changes go through the updateVisibility RPC only (plain
294
- // updates preserve stored visibility on both editions). The binding set
295
- // mirrors the kinds whose proto VisibilityConfig grants non-private
296
- // levels, minus Skill (push flow, not a manifest kind) — a kind added
297
- // here without the RPC fails at compile time, one dropped from here
298
- // silently strands manifest-declared visibility, which this pins.
299
- const withBinding = manifestKinds()
300
- .filter((h) => h.updateVisibility !== undefined)
301
- .map((h) => h.yamlKind)
302
- .sort();
303
- expect(withBinding).toEqual(["Agent", "AgentInstance", "Environment", "McpServer", "Workflow"]);
304
- });
305
- });
306
- //# sourceMappingURL=manifest.test.js.map