@stigmer/sdk 3.35.0 → 3.36.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 (342) 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.map +1 -1
  111. package/iam-principal.js.map +1 -1
  112. package/iam-role.d.ts.map +1 -1
  113. package/iam-role.js.map +1 -1
  114. package/index.d.ts.map +1 -1
  115. package/index.js.map +1 -1
  116. package/internal/interceptors.d.ts.map +1 -1
  117. package/internal/interceptors.js.map +1 -1
  118. package/manifest/client.d.ts.map +1 -1
  119. package/manifest/client.js.map +1 -1
  120. package/manifest/document.d.ts.map +1 -1
  121. package/manifest/document.js.map +1 -1
  122. package/manifest/index.d.ts.map +1 -1
  123. package/manifest/index.js.map +1 -1
  124. package/manifest/parse.d.ts.map +1 -1
  125. package/manifest/parse.js.map +1 -1
  126. package/manifest/redaction.d.ts.map +1 -1
  127. package/manifest/redaction.js.map +1 -1
  128. package/manifest/registry.d.ts.map +1 -1
  129. package/manifest/registry.js.map +1 -1
  130. package/manifest/serialize.d.ts.map +1 -1
  131. package/manifest/serialize.js.map +1 -1
  132. package/mcpserver-connect.d.ts.map +1 -1
  133. package/mcpserver-connect.js.map +1 -1
  134. package/node.d.ts.map +1 -1
  135. package/node.js.map +1 -1
  136. package/package.json +2 -2
  137. package/platform-client-auth.d.ts.map +1 -1
  138. package/platform-client-auth.js.map +1 -1
  139. package/platform.d.ts.map +1 -1
  140. package/platform.js.map +1 -1
  141. package/plugin.d.ts.map +1 -1
  142. package/plugin.js.map +1 -1
  143. package/provider-standing.d.ts.map +1 -1
  144. package/provider-standing.js.map +1 -1
  145. package/resource-availability.d.ts.map +1 -1
  146. package/resource-availability.js.map +1 -1
  147. package/runner-adapter.d.ts.map +1 -1
  148. package/runner-adapter.js.map +1 -1
  149. package/search.d.ts.map +1 -1
  150. package/search.js.map +1 -1
  151. package/session.d.ts.map +1 -1
  152. package/session.js.map +1 -1
  153. package/sharing.d.ts.map +1 -1
  154. package/sharing.js.map +1 -1
  155. package/skill.d.ts.map +1 -1
  156. package/skill.js.map +1 -1
  157. package/src/gen/authorization-config.ts +2 -2
  158. package/stigmer.d.ts.map +1 -1
  159. package/stigmer.js.map +1 -1
  160. package/transport.d.ts.map +1 -1
  161. package/transport.js.map +1 -1
  162. package/__tests__/billing.test.d.ts +0 -2
  163. package/__tests__/billing.test.d.ts.map +0 -1
  164. package/__tests__/billing.test.js +0 -120
  165. package/__tests__/billing.test.js.map +0 -1
  166. package/__tests__/config.test.d.ts +0 -2
  167. package/__tests__/config.test.d.ts.map +0 -1
  168. package/__tests__/config.test.js +0 -35
  169. package/__tests__/config.test.js.map +0 -1
  170. package/__tests__/ensure-identity-account.test.d.ts +0 -2
  171. package/__tests__/ensure-identity-account.test.d.ts.map +0 -1
  172. package/__tests__/ensure-identity-account.test.js +0 -108
  173. package/__tests__/ensure-identity-account.test.js.map +0 -1
  174. package/__tests__/errors.test.d.ts +0 -2
  175. package/__tests__/errors.test.d.ts.map +0 -1
  176. package/__tests__/errors.test.js +0 -228
  177. package/__tests__/errors.test.js.map +0 -1
  178. package/__tests__/gen/errors.test.d.ts +0 -2
  179. package/__tests__/gen/errors.test.d.ts.map +0 -1
  180. package/__tests__/gen/errors.test.js +0 -97
  181. package/__tests__/gen/errors.test.js.map +0 -1
  182. package/__tests__/gen/invitation-client.test.d.ts +0 -2
  183. package/__tests__/gen/invitation-client.test.d.ts.map +0 -1
  184. package/__tests__/gen/invitation-client.test.js +0 -106
  185. package/__tests__/gen/invitation-client.test.js.map +0 -1
  186. package/__tests__/gen/proto-utils.test.d.ts +0 -2
  187. package/__tests__/gen/proto-utils.test.d.ts.map +0 -1
  188. package/__tests__/gen/proto-utils.test.js +0 -85
  189. package/__tests__/gen/proto-utils.test.js.map +0 -1
  190. package/__tests__/gen/session-client.test.d.ts +0 -2
  191. package/__tests__/gen/session-client.test.d.ts.map +0 -1
  192. package/__tests__/gen/session-client.test.js +0 -152
  193. package/__tests__/gen/session-client.test.js.map +0 -1
  194. package/__tests__/guest-auth.test.d.ts +0 -2
  195. package/__tests__/guest-auth.test.d.ts.map +0 -1
  196. package/__tests__/guest-auth.test.js +0 -223
  197. package/__tests__/guest-auth.test.js.map +0 -1
  198. package/__tests__/iam-principal.test.d.ts +0 -2
  199. package/__tests__/iam-principal.test.d.ts.map +0 -1
  200. package/__tests__/iam-principal.test.js +0 -65
  201. package/__tests__/iam-principal.test.js.map +0 -1
  202. package/__tests__/manifest.test.d.ts +0 -2
  203. package/__tests__/manifest.test.d.ts.map +0 -1
  204. package/__tests__/manifest.test.js +0 -306
  205. package/__tests__/manifest.test.js.map +0 -1
  206. package/__tests__/mcpserver-connect.test.d.ts +0 -2
  207. package/__tests__/mcpserver-connect.test.d.ts.map +0 -1
  208. package/__tests__/mcpserver-connect.test.js +0 -146
  209. package/__tests__/mcpserver-connect.test.js.map +0 -1
  210. package/__tests__/node.test.d.ts +0 -2
  211. package/__tests__/node.test.d.ts.map +0 -1
  212. package/__tests__/node.test.js +0 -67
  213. package/__tests__/node.test.js.map +0 -1
  214. package/__tests__/platform-client-auth.test.d.ts +0 -2
  215. package/__tests__/platform-client-auth.test.d.ts.map +0 -1
  216. package/__tests__/platform-client-auth.test.js +0 -59
  217. package/__tests__/platform-client-auth.test.js.map +0 -1
  218. package/__tests__/platform.test.d.ts +0 -2
  219. package/__tests__/platform.test.d.ts.map +0 -1
  220. package/__tests__/platform.test.js +0 -52
  221. package/__tests__/platform.test.js.map +0 -1
  222. package/__tests__/plugin.test.d.ts +0 -2
  223. package/__tests__/plugin.test.d.ts.map +0 -1
  224. package/__tests__/plugin.test.js +0 -74
  225. package/__tests__/plugin.test.js.map +0 -1
  226. package/__tests__/resource-availability.test.d.ts +0 -2
  227. package/__tests__/resource-availability.test.d.ts.map +0 -1
  228. package/__tests__/resource-availability.test.js +0 -80
  229. package/__tests__/resource-availability.test.js.map +0 -1
  230. package/__tests__/runner-adapter.test.d.ts +0 -2
  231. package/__tests__/runner-adapter.test.d.ts.map +0 -1
  232. package/__tests__/runner-adapter.test.js +0 -88
  233. package/__tests__/runner-adapter.test.js.map +0 -1
  234. package/__tests__/session.test.d.ts +0 -6
  235. package/__tests__/session.test.d.ts.map +0 -1
  236. package/__tests__/session.test.js +0 -50
  237. package/__tests__/session.test.js.map +0 -1
  238. package/__tests__/sharing.test.d.ts +0 -2
  239. package/__tests__/sharing.test.d.ts.map +0 -1
  240. package/__tests__/sharing.test.js +0 -106
  241. package/__tests__/sharing.test.js.map +0 -1
  242. package/__tests__/skill.test.d.ts +0 -2
  243. package/__tests__/skill.test.d.ts.map +0 -1
  244. package/__tests__/skill.test.js +0 -117
  245. package/__tests__/skill.test.js.map +0 -1
  246. package/__tests__/stigmer.test.d.ts +0 -2
  247. package/__tests__/stigmer.test.d.ts.map +0 -1
  248. package/__tests__/stigmer.test.js +0 -127
  249. package/__tests__/stigmer.test.js.map +0 -1
  250. package/__tests__/update-input-roundtrip.test.d.ts +0 -2
  251. package/__tests__/update-input-roundtrip.test.d.ts.map +0 -1
  252. package/__tests__/update-input-roundtrip.test.js +0 -775
  253. package/__tests__/update-input-roundtrip.test.js.map +0 -1
  254. package/__tests__/update-input.test.d.ts +0 -2
  255. package/__tests__/update-input.test.d.ts.map +0 -1
  256. package/__tests__/update-input.test.js +0 -188
  257. package/__tests__/update-input.test.js.map +0 -1
  258. package/execution/__tests__/approval-provenance.test.d.ts +0 -2
  259. package/execution/__tests__/approval-provenance.test.d.ts.map +0 -1
  260. package/execution/__tests__/approval-provenance.test.js +0 -42
  261. package/execution/__tests__/approval-provenance.test.js.map +0 -1
  262. package/execution/__tests__/file-review-fold.corpus.test.d.ts +0 -2
  263. package/execution/__tests__/file-review-fold.corpus.test.d.ts.map +0 -1
  264. package/execution/__tests__/file-review-fold.corpus.test.js +0 -82
  265. package/execution/__tests__/file-review-fold.corpus.test.js.map +0 -1
  266. package/execution/__tests__/file-review-fold.test.d.ts +0 -2
  267. package/execution/__tests__/file-review-fold.test.d.ts.map +0 -1
  268. package/execution/__tests__/file-review-fold.test.js +0 -184
  269. package/execution/__tests__/file-review-fold.test.js.map +0 -1
  270. package/execution/__tests__/to-display-file-change.test.d.ts +0 -2
  271. package/execution/__tests__/to-display-file-change.test.d.ts.map +0 -1
  272. package/execution/__tests__/to-display-file-change.test.js +0 -81
  273. package/execution/__tests__/to-display-file-change.test.js.map +0 -1
  274. package/execution/__tests__/tool-view.file-changes.test.d.ts +0 -2
  275. package/execution/__tests__/tool-view.file-changes.test.d.ts.map +0 -1
  276. package/execution/__tests__/tool-view.file-changes.test.js +0 -86
  277. package/execution/__tests__/tool-view.file-changes.test.js.map +0 -1
  278. package/execution/__tests__/tool-view.fixtures.test.d.ts +0 -2
  279. package/execution/__tests__/tool-view.fixtures.test.d.ts.map +0 -1
  280. package/execution/__tests__/tool-view.fixtures.test.js +0 -152
  281. package/execution/__tests__/tool-view.fixtures.test.js.map +0 -1
  282. package/execution/__tests__/tool-view.output-ref.test.d.ts +0 -2
  283. package/execution/__tests__/tool-view.output-ref.test.d.ts.map +0 -1
  284. package/execution/__tests__/tool-view.output-ref.test.js +0 -64
  285. package/execution/__tests__/tool-view.output-ref.test.js.map +0 -1
  286. package/execution/__tests__/tool-view.read.test.d.ts +0 -2
  287. package/execution/__tests__/tool-view.read.test.d.ts.map +0 -1
  288. package/execution/__tests__/tool-view.read.test.js +0 -56
  289. package/execution/__tests__/tool-view.read.test.js.map +0 -1
  290. package/execution/__tests__/tool-view.search.test.d.ts +0 -2
  291. package/execution/__tests__/tool-view.search.test.d.ts.map +0 -1
  292. package/execution/__tests__/tool-view.search.test.js +0 -200
  293. package/execution/__tests__/tool-view.search.test.js.map +0 -1
  294. package/execution/__tests__/tool-view.shell.test.d.ts +0 -2
  295. package/execution/__tests__/tool-view.shell.test.d.ts.map +0 -1
  296. package/execution/__tests__/tool-view.shell.test.js +0 -104
  297. package/execution/__tests__/tool-view.shell.test.js.map +0 -1
  298. package/execution/__tests__/transcript.test.d.ts +0 -2
  299. package/execution/__tests__/transcript.test.d.ts.map +0 -1
  300. package/execution/__tests__/transcript.test.js +0 -591
  301. package/execution/__tests__/transcript.test.js.map +0 -1
  302. package/node.test.d.ts +0 -2
  303. package/node.test.d.ts.map +0 -1
  304. package/node.test.js +0 -35
  305. package/node.test.js.map +0 -1
  306. package/src/__tests__/billing.test.ts +0 -146
  307. package/src/__tests__/config.test.ts +0 -52
  308. package/src/__tests__/ensure-identity-account.test.ts +0 -146
  309. package/src/__tests__/errors.test.ts +0 -349
  310. package/src/__tests__/gen/errors.test.ts +0 -138
  311. package/src/__tests__/gen/invitation-client.test.ts +0 -132
  312. package/src/__tests__/gen/proto-utils.test.ts +0 -99
  313. package/src/__tests__/gen/session-client.test.ts +0 -208
  314. package/src/__tests__/guest-auth.test.ts +0 -287
  315. package/src/__tests__/iam-principal.test.ts +0 -82
  316. package/src/__tests__/manifest.test.ts +0 -362
  317. package/src/__tests__/mcpserver-connect.test.ts +0 -181
  318. package/src/__tests__/node.test.ts +0 -74
  319. package/src/__tests__/platform-client-auth.test.ts +0 -76
  320. package/src/__tests__/platform.test.ts +0 -74
  321. package/src/__tests__/plugin.test.ts +0 -92
  322. package/src/__tests__/resource-availability.test.ts +0 -118
  323. package/src/__tests__/runner-adapter.test.ts +0 -122
  324. package/src/__tests__/session.test.ts +0 -66
  325. package/src/__tests__/sharing.test.ts +0 -159
  326. package/src/__tests__/skill.test.ts +0 -150
  327. package/src/__tests__/stigmer.test.ts +0 -170
  328. package/src/__tests__/update-input-roundtrip.test.ts +0 -1007
  329. package/src/__tests__/update-input.test.ts +0 -250
  330. package/src/execution/__tests__/approval-provenance.test.ts +0 -60
  331. package/src/execution/__tests__/file-review-fold.corpus.test.ts +0 -127
  332. package/src/execution/__tests__/file-review-fold.test.ts +0 -281
  333. package/src/execution/__tests__/to-display-file-change.test.ts +0 -106
  334. package/src/execution/__tests__/tool-view.file-changes.test.ts +0 -100
  335. package/src/execution/__tests__/tool-view.fixtures.test.ts +0 -225
  336. package/src/execution/__tests__/tool-view.output-ref.test.ts +0 -76
  337. package/src/execution/__tests__/tool-view.read.test.ts +0 -71
  338. package/src/execution/__tests__/tool-view.search.test.ts +0 -264
  339. package/src/execution/__tests__/tool-view.shell.test.ts +0 -127
  340. package/src/execution/__tests__/transcript.golden.md +0 -100
  341. package/src/execution/__tests__/transcript.test.ts +0 -697
  342. package/src/node.test.ts +0 -38
@@ -1,99 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { stripUndefined, toTimestamp } from "../../gen/proto-utils";
3
- import { timestampDate } from "@bufbuild/protobuf/wkt";
4
-
5
- describe("stripUndefined", () => {
6
- it("removes keys with undefined values", () => {
7
- const result = stripUndefined({ a: 1, b: undefined, c: "hello" });
8
- expect(result).toEqual({ a: 1, c: "hello" });
9
- expect("b" in result).toBe(false);
10
- });
11
-
12
- it("preserves null values (falsy but defined)", () => {
13
- const result = stripUndefined({ a: null });
14
- expect(result).toEqual({ a: null });
15
- });
16
-
17
- it("preserves 0 (falsy but defined)", () => {
18
- const result = stripUndefined({ count: 0 });
19
- expect(result).toEqual({ count: 0 });
20
- });
21
-
22
- it("preserves empty string (falsy but defined)", () => {
23
- const result = stripUndefined({ name: "" });
24
- expect(result).toEqual({ name: "" });
25
- });
26
-
27
- it("preserves false (falsy but defined)", () => {
28
- const result = stripUndefined({ enabled: false });
29
- expect(result).toEqual({ enabled: false });
30
- });
31
-
32
- it("returns empty object when all values are undefined", () => {
33
- const result = stripUndefined({ a: undefined, b: undefined });
34
- expect(result).toEqual({});
35
- });
36
-
37
- it("returns all keys when nothing is undefined", () => {
38
- const input = { x: 1, y: "two", z: true };
39
- const result = stripUndefined(input);
40
- expect(result).toEqual(input);
41
- });
42
-
43
- it("preserves nested objects without deep-stripping", () => {
44
- const nested = { inner: undefined };
45
- const result = stripUndefined({ outer: nested });
46
- expect(result).toEqual({ outer: nested });
47
- expect((result as Record<string, unknown>).outer).toBe(nested);
48
- });
49
-
50
- it("returns empty object for empty input", () => {
51
- const result = stripUndefined({});
52
- expect(result).toEqual({});
53
- });
54
- });
55
-
56
- describe("toTimestamp", () => {
57
- it("converts a Date to a Timestamp with correct seconds", () => {
58
- const date = new Date("2026-05-19T12:00:00.000Z");
59
- const ts = toTimestamp(date);
60
- expect(ts.seconds).toBe(BigInt(Math.floor(date.getTime() / 1000)));
61
- expect(ts.nanos).toBe(0);
62
- });
63
-
64
- it("converts a Date with milliseconds to a Timestamp with nanos", () => {
65
- const date = new Date("2026-01-15T08:30:00.456Z");
66
- const ts = toTimestamp(date);
67
- const expectedSeconds = BigInt(Math.floor(date.getTime() / 1000));
68
- expect(ts.seconds).toBe(expectedSeconds);
69
- expect(ts.nanos).toBe(456_000_000);
70
- });
71
-
72
- it("converts an ISO string to a Timestamp", () => {
73
- const isoString = "2026-06-01T00:00:00.000Z";
74
- const ts = toTimestamp(isoString);
75
- const expected = new Date(isoString);
76
- expect(ts.seconds).toBe(BigInt(Math.floor(expected.getTime() / 1000)));
77
- });
78
-
79
- it("roundtrips correctly through timestampDate", () => {
80
- const original = new Date("2026-03-10T15:45:30.000Z");
81
- const ts = toTimestamp(original);
82
- const roundtripped = timestampDate(ts);
83
- expect(roundtripped.getTime()).toBe(original.getTime());
84
- });
85
-
86
- it("handles epoch (Unix timestamp 0)", () => {
87
- const epoch = new Date(0);
88
- const ts = toTimestamp(epoch);
89
- expect(ts.seconds).toBe(BigInt(0));
90
- expect(ts.nanos).toBe(0);
91
- });
92
-
93
- it("handles far-future dates", () => {
94
- const future = new Date("2099-12-31T23:59:59.000Z");
95
- const ts = toTimestamp(future);
96
- expect(ts.seconds).toBe(BigInt(Math.floor(future.getTime() / 1000)));
97
- expect(timestampDate(ts).getTime()).toBe(future.getTime());
98
- });
99
- });
@@ -1,208 +0,0 @@
1
- import { describe, it, expect, beforeEach } from "vitest";
2
- import type { Transport } from "@connectrpc/connect";
3
- import type { Session } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
4
- import { ExecutionTarget } from "@stigmer/protos/ai/stigmer/agentic/session/v1/enum_pb";
5
- import { SessionClient, type SessionInput } from "../../gen/session";
6
-
7
- interface CapturedRequest {
8
- methodName: string;
9
- message: unknown;
10
- }
11
-
12
- function createCapturingTransport(): {
13
- transport: Transport;
14
- captured: CapturedRequest[];
15
- } {
16
- const captured: CapturedRequest[] = [];
17
-
18
- const transport = {
19
- unary: async (
20
- method: { name: string },
21
- _signal: unknown,
22
- _timeout: unknown,
23
- _header: unknown,
24
- message: unknown,
25
- ) => ({
26
- header: new Headers(),
27
- trailer: new Headers(),
28
- message,
29
- }),
30
- stream: async () => {
31
- throw new Error("streaming not implemented in test transport");
32
- },
33
- } as unknown as Transport;
34
-
35
- const originalUnary = (transport as unknown as Record<string, unknown>).unary as (
36
- ...args: unknown[]
37
- ) => Promise<unknown>;
38
-
39
- (transport as unknown as Record<string, unknown>).unary = async (
40
- method: { name: string },
41
- signal: unknown,
42
- timeout: unknown,
43
- header: unknown,
44
- message: unknown,
45
- ...rest: unknown[]
46
- ) => {
47
- captured.push({ methodName: method.name, message });
48
- return originalUnary(method, signal, timeout, header, message, ...rest);
49
- };
50
-
51
- return { transport, captured };
52
- }
53
-
54
- describe("SessionClient proto serialization", () => {
55
- let client: SessionClient;
56
- let captured: CapturedRequest[];
57
-
58
- beforeEach(() => {
59
- const ctx = createCapturingTransport();
60
- client = new SessionClient(ctx.transport);
61
- captured = ctx.captured;
62
- });
63
-
64
- it("sets apiVersion and kind on the proto", async () => {
65
- await client.create({ name: "test-session", org: "my-org" });
66
-
67
- const proto = captured[0].message as Session;
68
- expect(proto.apiVersion).toBe("agentic.stigmer.ai/v1");
69
- expect(proto.kind).toBe("Session");
70
- });
71
-
72
- it("sets required fields on metadata", async () => {
73
- await client.create({ name: "my-session", org: "acme" });
74
-
75
- const proto = captured[0].message as Session;
76
- expect(proto.metadata?.name).toBe("my-session");
77
- expect(proto.metadata?.org).toBe("acme");
78
- });
79
-
80
- it("sets optional spec fields when provided", async () => {
81
- const input: SessionInput = {
82
- name: "s1",
83
- org: "o1",
84
- agentInstanceId: "ai-123",
85
- subject: "Help with deployment",
86
- };
87
-
88
- await client.create(input);
89
-
90
- const proto = captured[0].message as Session;
91
- expect(proto.spec?.agentInstanceId).toBe("ai-123");
92
- expect(proto.spec?.subject).toBe("Help with deployment");
93
- });
94
-
95
- it("does not overwrite protobuf defaults when optional fields are omitted", async () => {
96
- await client.create({ name: "minimal", org: "org" });
97
-
98
- const proto = captured[0].message as Session;
99
- expect(proto.spec?.agentInstanceId).toBe("");
100
- expect(proto.spec?.subject).toBe("");
101
- });
102
-
103
- it("serializes executionTarget when provided", async () => {
104
- await client.create({
105
- name: "s1",
106
- org: "o1",
107
- executionTarget: ExecutionTarget.LOCAL,
108
- });
109
-
110
- const proto = captured[0].message as Session;
111
- expect(proto.spec?.executionTarget).toBe(ExecutionTarget.LOCAL);
112
- });
113
-
114
- it("serializes metadata map when provided", async () => {
115
- await client.create({
116
- name: "s1",
117
- org: "o1",
118
- metadata: { env: "production", region: "us-east-1" },
119
- });
120
-
121
- const proto = captured[0].message as Session;
122
- expect(proto.spec?.metadata).toEqual({
123
- env: "production",
124
- region: "us-east-1",
125
- });
126
- });
127
-
128
- it("serializes workspace entries with git repo source", async () => {
129
- await client.create({
130
- name: "s1",
131
- org: "o1",
132
- workspaceEntries: [
133
- {
134
- name: "my-repo",
135
- source: {
136
- gitRepo: {
137
- url: "https://github.com/example/repo.git",
138
- branch: "main",
139
- },
140
- },
141
- },
142
- ],
143
- });
144
-
145
- const proto = captured[0].message as Session;
146
- const entries = proto.spec?.workspaceEntries;
147
- expect(entries).toHaveLength(1);
148
- expect(entries![0].name).toBe("my-repo");
149
-
150
- const source = entries![0].source;
151
- expect(source?.source?.case).toBe("gitRepo");
152
- if (source?.source?.case === "gitRepo") {
153
- expect(source.source.value.url).toBe(
154
- "https://github.com/example/repo.git",
155
- );
156
- expect(source.source.value.branch).toBe("main");
157
- }
158
- });
159
-
160
- it("serializes workspace entries with local path source", async () => {
161
- await client.create({
162
- name: "s1",
163
- org: "o1",
164
- workspaceEntries: [
165
- {
166
- name: "local",
167
- source: {
168
- localPath: { path: "/home/user/project" },
169
- },
170
- },
171
- ],
172
- });
173
-
174
- const proto = captured[0].message as Session;
175
- const entries = proto.spec?.workspaceEntries;
176
- expect(entries).toHaveLength(1);
177
-
178
- const source = entries![0].source;
179
- expect(source?.source?.case).toBe("localPath");
180
- if (source?.source?.case === "localPath") {
181
- expect(source.source.value.path).toBe("/home/user/project");
182
- }
183
- });
184
-
185
- it("routes create through the command controller", async () => {
186
- await client.create({ name: "s1", org: "o1" });
187
- expect(captured[0].methodName).toBe("create");
188
- });
189
-
190
- it("routes apply through the command controller", async () => {
191
- await client.apply({ name: "s1", org: "o1" });
192
- expect(captured[0].methodName).toBe("apply");
193
- });
194
-
195
- it("routes get through the query controller with SessionId", async () => {
196
- await client.get("session-id-123");
197
- const message = captured[0].message as { value: string };
198
- expect(captured[0].methodName).toBe("get");
199
- expect(message.value).toBe("session-id-123");
200
- });
201
-
202
- it("routes delete through the command controller with SessionId", async () => {
203
- await client.delete("session-id-456");
204
- const message = captured[0].message as { value: string };
205
- expect(captured[0].methodName).toBe("delete");
206
- expect(message.value).toBe("session-id-456");
207
- });
208
- });
@@ -1,287 +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
-
6
- // Intercept the token client so no transport is exercised. The mock
7
- // preserves the real module (create/Code/ConnectError) and only stubs
8
- // createClient, which GuestAuth uses to build its RPC client.
9
- const mintGuestToken = vi.fn();
10
- vi.mock("@connectrpc/connect", async (importOriginal) => {
11
- const actual = await importOriginal<typeof import("@connectrpc/connect")>();
12
- return {
13
- ...actual,
14
- createClient: () => ({ mintGuestToken }),
15
- };
16
- });
17
-
18
- import { createGuestAuth, GuestAuth, type GuestIdStorage } from "../guest-auth";
19
-
20
- const CONFIG = {
21
- baseUrl: "https://api.stigmer.ai",
22
- org: "acme",
23
- slug: "support-agent",
24
- };
25
-
26
- function createMemoryStorage(): GuestIdStorage & { store: Map<string, string> } {
27
- const store = new Map<string, string>();
28
- return {
29
- store,
30
- getItem: (key) => store.get(key) ?? null,
31
- setItem: (key, value) => {
32
- store.set(key, value);
33
- },
34
- };
35
- }
36
-
37
- function mintResponse(overrides?: {
38
- accessToken?: string;
39
- expiresIn?: number;
40
- guestCookieId?: string;
41
- }) {
42
- return create(MintGuestTokenResponseSchema, {
43
- accessToken: overrides?.accessToken ?? "guest-jwt-1",
44
- tokenType: "Bearer",
45
- expiresIn: overrides?.expiresIn ?? 900,
46
- guestCookieId: overrides?.guestCookieId ?? "cookie-abc",
47
- });
48
- }
49
-
50
- beforeEach(() => {
51
- mintGuestToken.mockReset();
52
- vi.useFakeTimers();
53
- });
54
-
55
- afterEach(() => {
56
- vi.useRealTimers();
57
- });
58
-
59
- describe("createGuestAuth", () => {
60
- it("throws when baseUrl is missing", () => {
61
- expect(() =>
62
- createGuestAuth({ ...CONFIG, baseUrl: "" }),
63
- ).toThrow("baseUrl is required");
64
- });
65
-
66
- it("throws when org is missing", () => {
67
- expect(() => createGuestAuth({ ...CONFIG, org: "" })).toThrow(
68
- "org is required",
69
- );
70
- });
71
-
72
- it("throws when slug is missing", () => {
73
- expect(() => createGuestAuth({ ...CONFIG, slug: "" })).toThrow(
74
- "slug is required",
75
- );
76
- });
77
-
78
- it("returns a GuestAuth instance with valid config", () => {
79
- expect(createGuestAuth(CONFIG)).toBeInstanceOf(GuestAuth);
80
- });
81
- });
82
-
83
- describe("GuestAuth.getAccessToken", () => {
84
- it("mints on first call and sends an empty guest id", async () => {
85
- mintGuestToken.mockResolvedValue(mintResponse());
86
- const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
87
-
88
- const token = await auth.getAccessToken();
89
-
90
- expect(token).toBe("guest-jwt-1");
91
- expect(mintGuestToken).toHaveBeenCalledTimes(1);
92
- expect(mintGuestToken.mock.calls[0][0]).toMatchObject({
93
- org: "acme",
94
- slug: "support-agent",
95
- guestCookieId: "",
96
- // No embedOrigin configured (the unframed hosted page): the field
97
- // must stay empty so the server's absence-means-exempt rule applies.
98
- embedOrigin: "",
99
- });
100
- });
101
-
102
- it("passes the configured embedOrigin through to every mint", async () => {
103
- mintGuestToken.mockResolvedValue(mintResponse());
104
- const auth = createGuestAuth({
105
- ...CONFIG,
106
- storage: createMemoryStorage(),
107
- embedOrigin: "https://docs.example.com",
108
- });
109
-
110
- await auth.getAccessToken();
111
- // Expire the cached token, forcing a re-mint — the origin must persist.
112
- vi.advanceTimersByTime(900_000);
113
- await auth.getAccessToken();
114
-
115
- expect(mintGuestToken).toHaveBeenCalledTimes(2);
116
- for (const call of mintGuestToken.mock.calls) {
117
- expect(call[0]).toMatchObject({ embedOrigin: "https://docs.example.com" });
118
- }
119
- });
120
-
121
- it("passes the configured linkToken through to every mint", async () => {
122
- mintGuestToken.mockResolvedValue(mintResponse());
123
- const auth = createGuestAuth({
124
- ...CONFIG,
125
- storage: createMemoryStorage(),
126
- linkToken: "tok123",
127
- });
128
-
129
- await auth.getAccessToken();
130
- // Expire the cached token, forcing a re-mint — the token must persist
131
- // so a locked link keeps working across silent re-mints.
132
- vi.advanceTimersByTime(900_000);
133
- await auth.getAccessToken();
134
-
135
- expect(mintGuestToken).toHaveBeenCalledTimes(2);
136
- for (const call of mintGuestToken.mock.calls) {
137
- expect(call[0]).toMatchObject({ linkToken: "tok123" });
138
- }
139
- });
140
-
141
- it("sends an empty linkToken when none is configured (plain link)", async () => {
142
- mintGuestToken.mockResolvedValue(mintResponse());
143
- const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
144
-
145
- await auth.getAccessToken();
146
-
147
- expect(mintGuestToken.mock.calls[0][0]).toMatchObject({ linkToken: "" });
148
- });
149
-
150
- it("rejects with permission-denied when the embed origin is refused", async () => {
151
- mintGuestToken.mockRejectedValue(
152
- new ConnectError(
153
- "This agent can\u2019t be embedded on this site.",
154
- Code.PermissionDenied,
155
- ),
156
- );
157
- const auth = createGuestAuth({
158
- ...CONFIG,
159
- storage: createMemoryStorage(),
160
- embedOrigin: "https://evil.example.com",
161
- });
162
-
163
- await expect(auth.getAccessToken()).rejects.toMatchObject({
164
- code: "permission-denied",
165
- });
166
- });
167
-
168
- it("persists the server-issued guest id and presents it on re-mint", async () => {
169
- const storage = createMemoryStorage();
170
- mintGuestToken.mockResolvedValue(mintResponse({ guestCookieId: "cookie-abc" }));
171
- const auth = createGuestAuth({ ...CONFIG, storage });
172
-
173
- await auth.getAccessToken();
174
- expect(storage.store.get("stigmer:guest-id:acme")).toBe("cookie-abc");
175
- expect(auth.guestCookieId).toBe("cookie-abc");
176
-
177
- // Expire the cached token, forcing a second mint.
178
- vi.advanceTimersByTime(900_000);
179
- await auth.getAccessToken();
180
-
181
- expect(mintGuestToken).toHaveBeenCalledTimes(2);
182
- expect(mintGuestToken.mock.calls[1][0]).toMatchObject({
183
- guestCookieId: "cookie-abc",
184
- });
185
- });
186
-
187
- it("restores a persisted guest id from a prior visit", async () => {
188
- const storage = createMemoryStorage();
189
- storage.setItem("stigmer:guest-id:acme", "cookie-from-last-visit");
190
- mintGuestToken.mockResolvedValue(mintResponse());
191
- const auth = createGuestAuth({ ...CONFIG, storage });
192
-
193
- await auth.getAccessToken();
194
-
195
- expect(mintGuestToken.mock.calls[0][0]).toMatchObject({
196
- guestCookieId: "cookie-from-last-visit",
197
- });
198
- });
199
-
200
- it("returns the cached token while it is fresh", async () => {
201
- mintGuestToken.mockResolvedValue(mintResponse());
202
- const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
203
-
204
- await auth.getAccessToken();
205
- // 13 minutes into a 15-minute token: still beyond the 60s skew.
206
- vi.advanceTimersByTime(13 * 60_000);
207
- const token = await auth.getAccessToken();
208
-
209
- expect(token).toBe("guest-jwt-1");
210
- expect(mintGuestToken).toHaveBeenCalledTimes(1);
211
- });
212
-
213
- it("re-mints when the cached token is within the expiry skew", async () => {
214
- mintGuestToken
215
- .mockResolvedValueOnce(mintResponse({ accessToken: "guest-jwt-1" }))
216
- .mockResolvedValueOnce(mintResponse({ accessToken: "guest-jwt-2" }));
217
- const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
218
-
219
- await auth.getAccessToken();
220
- // 30 seconds of life left — inside the 60s skew window.
221
- vi.advanceTimersByTime(900_000 - 30_000);
222
- const token = await auth.getAccessToken();
223
-
224
- expect(token).toBe("guest-jwt-2");
225
- expect(mintGuestToken).toHaveBeenCalledTimes(2);
226
- });
227
-
228
- it("collapses concurrent callers into a single mint", async () => {
229
- let release!: (value: ReturnType<typeof mintResponse>) => void;
230
- mintGuestToken.mockImplementation(
231
- () => new Promise((resolve) => { release = resolve; }),
232
- );
233
- const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
234
-
235
- const first = auth.getAccessToken();
236
- const second = auth.getAccessToken();
237
- release(mintResponse());
238
-
239
- await expect(first).resolves.toBe("guest-jwt-1");
240
- await expect(second).resolves.toBe("guest-jwt-1");
241
- expect(mintGuestToken).toHaveBeenCalledTimes(1);
242
- });
243
-
244
- it("rejects with a wrapped StigmerError when sharing is revoked", async () => {
245
- mintGuestToken.mockRejectedValue(
246
- new ConnectError("agent not found", Code.NotFound),
247
- );
248
- const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
249
-
250
- try {
251
- await auth.getAccessToken();
252
- expect.fail("should have thrown");
253
- } catch (e: unknown) {
254
- expect(e).toHaveProperty("name", "StigmerError");
255
- expect(e).toHaveProperty("code", "not-found");
256
- }
257
- });
258
-
259
- it("recovers after a failed mint instead of caching the failure", async () => {
260
- mintGuestToken
261
- .mockRejectedValueOnce(new ConnectError("unavailable", Code.Unavailable))
262
- .mockResolvedValueOnce(mintResponse());
263
- const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
264
-
265
- await expect(auth.getAccessToken()).rejects.toMatchObject({
266
- code: "unavailable",
267
- });
268
- await expect(auth.getAccessToken()).resolves.toBe("guest-jwt-1");
269
- expect(mintGuestToken).toHaveBeenCalledTimes(2);
270
- });
271
-
272
- it("still mints when storage throws", async () => {
273
- const brokenStorage: GuestIdStorage = {
274
- getItem: () => {
275
- throw new Error("storage disabled");
276
- },
277
- setItem: () => {
278
- throw new Error("storage disabled");
279
- },
280
- };
281
- mintGuestToken.mockResolvedValue(mintResponse());
282
- const auth = createGuestAuth({ ...CONFIG, storage: brokenStorage });
283
-
284
- await expect(auth.getAccessToken()).resolves.toBe("guest-jwt-1");
285
- expect(auth.guestCookieId).toBeNull();
286
- });
287
- });
@@ -1,82 +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
-
20
- import {
21
- getGrantableRoles,
22
- getTeamGrantableRoles,
23
- hasTeamGrantableRoles,
24
- isRoleTeamGrantable,
25
- } from "../authorization-config";
26
- import { TEAM_GRANTABLE_ROLES } from "../gen/authorization-config";
27
- import {
28
- granteeFromView,
29
- granteeRef,
30
- personGrantee,
31
- teamGrantee,
32
- } from "../iam-principal";
33
-
34
- describe("granteeRef — the one spelling of a grantee on the wire", () => {
35
- it("names a team as its members", () => {
36
- const ref = granteeRef(teamGrantee("tm_sre"));
37
- expect([ref.kind, ref.id, ref.relation]).toEqual(["team", "tm_sre", "member"]);
38
- });
39
-
40
- it("names a person with no relation qualifier", () => {
41
- const ref = granteeRef(personGrantee("ida_alice"));
42
- expect([ref.kind, ref.id, ref.relation]).toEqual(["identity_account", "ida_alice", ""]);
43
- });
44
- });
45
-
46
- describe("granteeFromView — reading an access-list entry back", () => {
47
- it("round-trips both grantees through their wire reference", () => {
48
- for (const grantee of [teamGrantee("tm_sre"), personGrantee("ida_alice")]) {
49
- expect(granteeFromView(granteeRef(grantee))).toEqual(grantee);
50
- }
51
- });
52
-
53
- it("refuses what it would misname: a team without its members qualifier, a qualified person, a structural principal, an empty id", () => {
54
- expect(granteeFromView({ kind: "team", id: "tm_sre", relation: "" })).toBeUndefined();
55
- expect(granteeFromView({ kind: "team", id: "tm_sre", relation: "maintainer" })).toBeUndefined();
56
- expect(granteeFromView({ kind: "identity_account", id: "ida_alice", relation: "member" })).toBeUndefined();
57
- expect(granteeFromView({ kind: "organization", id: "acme", relation: "" })).toBeUndefined();
58
- expect(granteeFromView({ kind: "identity_account", id: "", relation: "" })).toBeUndefined();
59
- });
60
- });
61
-
62
- describe("team grantable roles", () => {
63
- it("are, for every kind, a subset of the person's roles and never owner", () => {
64
- for (const [kind, teamRoles] of TEAM_GRANTABLE_ROLES) {
65
- const personRoles = getGrantableRoles(kind);
66
- for (const role of teamRoles) {
67
- expect(personRoles).toContain(role);
68
- expect(role).not.toBe(IamRole.owner);
69
- }
70
- }
71
- });
72
-
73
- it("list nothing on organization, so an organization is never shared with a team", () => {
74
- expect(hasTeamGrantableRoles(ApiResourceKind.organization)).toBe(false);
75
- expect(getTeamGrantableRoles(ApiResourceKind.organization)).toEqual([]);
76
- });
77
-
78
- it("answer per role on a kind a team may be shared", () => {
79
- expect(isRoleTeamGrantable(ApiResourceKind.agent, IamRole.viewer)).toBe(true);
80
- expect(isRoleTeamGrantable(ApiResourceKind.agent, IamRole.owner)).toBe(false);
81
- });
82
- });