@opengeni/contracts 3.1.0-canary.1 → 3.1.2

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 (434) hide show
  1. package/dist/agent-authored-durable-text.d.ts +9 -9
  2. package/dist/agent-config.d.ts +971 -0
  3. package/dist/agent-instruction-changes.d.ts +110 -0
  4. package/dist/agent-learning.d.ts +243 -0
  5. package/dist/allowance-refusal.d.ts +9 -0
  6. package/dist/allowance-refusal.js +50 -0
  7. package/dist/allowance-refusal.js.map +1 -0
  8. package/dist/analytics-consent-report.d.ts +19 -0
  9. package/dist/analytics-consent-report.js +10 -0
  10. package/dist/analytics-consent-report.js.map +1 -0
  11. package/dist/api-key-presets.d.ts +19 -0
  12. package/dist/artifact-catalog.d.ts +188 -0
  13. package/dist/artifacts.d.ts +86 -0
  14. package/dist/atlassian-native-retirement.d.ts +16 -0
  15. package/dist/atlassian-native-retirement.js +30 -0
  16. package/dist/atlassian-native-retirement.js.map +1 -0
  17. package/dist/atlassian.d.ts +1 -0
  18. package/dist/atlassian.js +34 -19
  19. package/dist/browser-storage.d.ts +5 -0
  20. package/dist/browser-storage.js +9 -0
  21. package/dist/browser-storage.js.map +1 -0
  22. package/dist/bundled-skills.d.ts +24 -1
  23. package/dist/canonical-human-identities.js +2 -1
  24. package/dist/chunk-2ZIHHL72.js +153 -0
  25. package/dist/chunk-2ZIHHL72.js.map +1 -0
  26. package/dist/{chunk-5LYFSZ7O.js → chunk-352X6ENP.js} +31 -31
  27. package/dist/chunk-4JGHSSB7.js +11 -0
  28. package/dist/chunk-4JGHSSB7.js.map +1 -0
  29. package/dist/chunk-4QO6GJUX.js +85 -0
  30. package/dist/chunk-4QO6GJUX.js.map +1 -0
  31. package/dist/chunk-4VDMHLLL.js +49 -0
  32. package/dist/chunk-4VDMHLLL.js.map +1 -0
  33. package/dist/chunk-56SNIMDO.js +9 -0
  34. package/dist/chunk-56SNIMDO.js.map +1 -0
  35. package/dist/chunk-6C2HKFTU.js +207 -0
  36. package/dist/chunk-6C2HKFTU.js.map +1 -0
  37. package/dist/chunk-6IXO76Z6.js +72 -0
  38. package/dist/chunk-6IXO76Z6.js.map +1 -0
  39. package/dist/chunk-7272KVWZ.js +60 -0
  40. package/dist/chunk-7272KVWZ.js.map +1 -0
  41. package/dist/{chunk-7ABONTXE.js → chunk-E3GGUBHS.js} +49 -5
  42. package/dist/chunk-E3GGUBHS.js.map +1 -0
  43. package/dist/chunk-EFZYKUE2.js +767 -0
  44. package/dist/chunk-EFZYKUE2.js.map +1 -0
  45. package/dist/chunk-EKWNTOG3.js +154 -0
  46. package/dist/chunk-EKWNTOG3.js.map +1 -0
  47. package/dist/chunk-HABQ7ADB.js +234 -0
  48. package/dist/chunk-HABQ7ADB.js.map +1 -0
  49. package/dist/chunk-HRRU4QPI.js +91 -0
  50. package/dist/chunk-HRRU4QPI.js.map +1 -0
  51. package/dist/{chunk-3SIZGL3O.js → chunk-IK36LXKC.js} +18 -2
  52. package/dist/chunk-IK36LXKC.js.map +1 -0
  53. package/dist/{chunk-TXTQIYCV.js → chunk-ILJ72KPO.js} +56 -3
  54. package/dist/chunk-ILJ72KPO.js.map +1 -0
  55. package/dist/chunk-J4HQ3UKY.js +93 -0
  56. package/dist/chunk-J4HQ3UKY.js.map +1 -0
  57. package/dist/chunk-KHHZTBP7.js +11 -0
  58. package/dist/chunk-KHHZTBP7.js.map +1 -0
  59. package/dist/{chunk-WYBDERIY.js → chunk-LZ2LAHIX.js} +47 -41
  60. package/dist/chunk-LZ2LAHIX.js.map +1 -0
  61. package/dist/chunk-NDZHPTCL.js +400 -0
  62. package/dist/chunk-NDZHPTCL.js.map +1 -0
  63. package/dist/chunk-OF6OKOBF.js +54793 -0
  64. package/dist/chunk-OF6OKOBF.js.map +1 -0
  65. package/dist/chunk-OL23ARTF.js +94 -0
  66. package/dist/chunk-OL23ARTF.js.map +1 -0
  67. package/dist/chunk-PUIUXIOL.js +189 -0
  68. package/dist/chunk-PUIUXIOL.js.map +1 -0
  69. package/dist/{chunk-WBYTNVIW.js → chunk-RKX3NQYS.js} +1 -1
  70. package/dist/{chunk-Y3KNXVTD.js → chunk-RMWXDZEO.js} +128 -21
  71. package/dist/chunk-RMWXDZEO.js.map +1 -0
  72. package/dist/{chunk-MRWYRAS5.js → chunk-SHO4YO4B.js} +27 -35
  73. package/dist/chunk-SHO4YO4B.js.map +1 -0
  74. package/dist/chunk-SWRN2DJ3.js +153 -0
  75. package/dist/chunk-SWRN2DJ3.js.map +1 -0
  76. package/dist/chunk-TCXCRBPF.js +267 -0
  77. package/dist/chunk-TCXCRBPF.js.map +1 -0
  78. package/dist/chunk-TLU3UEMD.js +324 -0
  79. package/dist/chunk-TLU3UEMD.js.map +1 -0
  80. package/dist/chunk-TSWWZMUS.js +186 -0
  81. package/dist/chunk-TSWWZMUS.js.map +1 -0
  82. package/dist/{chunk-PX3VCKAU.js → chunk-WVCFSOUZ.js} +1 -1
  83. package/dist/{chunk-PX3VCKAU.js.map → chunk-WVCFSOUZ.js.map} +1 -1
  84. package/dist/chunk-XDLAGX66.js +127 -0
  85. package/dist/chunk-XDLAGX66.js.map +1 -0
  86. package/dist/chunk-YKZ4WU4P.js +33 -0
  87. package/dist/chunk-YKZ4WU4P.js.map +1 -0
  88. package/dist/{chunk-O5LEQHDM.js → chunk-Z7WEVGCL.js} +3 -3
  89. package/dist/{chunk-YBW5JSA3.js → chunk-ZDCRWCGZ.js} +119 -101
  90. package/dist/chunk-ZDCRWCGZ.js.map +1 -0
  91. package/dist/claude-provider-account-authority.d.ts +18 -0
  92. package/dist/claude-subscription-oauth.d.ts +42 -0
  93. package/dist/claude-subscription-usage.d.ts +159 -0
  94. package/dist/client-error-report.d.ts +158 -0
  95. package/dist/client-error-report.js +164 -0
  96. package/dist/client-error-report.js.map +1 -0
  97. package/dist/code-search.d.ts +52 -0
  98. package/dist/code-search.js +40 -0
  99. package/dist/code-search.js.map +1 -0
  100. package/dist/codex-provider-account-authority.js +20 -12
  101. package/dist/codex-provider-account-authority.js.map +1 -1
  102. package/dist/company-brain.d.ts +19 -81
  103. package/dist/company-profile.d.ts +144 -6
  104. package/dist/connect.d.ts +37 -0
  105. package/dist/connect.js +216 -159
  106. package/dist/connect.js.map +1 -1
  107. package/dist/connection-account-label.d.ts +2 -0
  108. package/dist/connection-account-label.js +35 -0
  109. package/dist/connection-account-label.js.map +1 -0
  110. package/dist/connection-authority.d.ts +9 -317
  111. package/dist/connection-authority.js +37 -42
  112. package/dist/connector-attachments.js +2 -1
  113. package/dist/connector-destinations.js +2 -1
  114. package/dist/connector-tool-permissions.d.ts +137 -0
  115. package/dist/cua-desktop-tools.d.ts +17 -0
  116. package/dist/define-schema.d.ts +8 -0
  117. package/dist/direct-model-provider.d.ts +36 -0
  118. package/dist/editable-artifact-codec-registry.js +5 -5
  119. package/dist/editable-artifact-committed-transaction.js +3 -2
  120. package/dist/editable-artifact-live.js +5 -5
  121. package/dist/editable-artifact-serialized-commit.js +6 -6
  122. package/dist/editable-artifact-versions.d.ts +7 -1
  123. package/dist/editable-artifact-versions.js +1 -1
  124. package/dist/editable-artifacts.js +62 -56
  125. package/dist/event-preview.d.ts +22 -0
  126. package/dist/external-identities.d.ts +174 -0
  127. package/dist/external-identities.js +15 -4
  128. package/dist/first-party-tool-authorization.d.ts +815 -0
  129. package/dist/github-repository-contracts.js +60 -43
  130. package/dist/github-repository-contracts.js.map +1 -1
  131. package/dist/google-drive.d.ts +2 -1
  132. package/dist/google-drive.js +305 -238
  133. package/dist/google-drive.js.map +1 -1
  134. package/dist/host-mcp-bindings.d.ts +39 -10
  135. package/dist/host-mcp-bindings.js +256 -171
  136. package/dist/host-mcp-bindings.js.map +1 -1
  137. package/dist/image-generation.d.ts +1 -0
  138. package/dist/index.d.ts +15715 -3850
  139. package/dist/index.js +2088 -289
  140. package/dist/insights-usage.d.ts +877 -0
  141. package/dist/insights-usage.js +559 -0
  142. package/dist/insights-usage.js.map +1 -0
  143. package/dist/interaction.d.ts +1176 -829
  144. package/dist/knowledge-entries.d.ts +984 -0
  145. package/dist/knowledge-preparation.d.ts +239 -0
  146. package/dist/managed-auth-session-sets.d.ts +7 -0
  147. package/dist/managed-auth-session-sets.js +198 -132
  148. package/dist/managed-auth-session-sets.js.map +1 -1
  149. package/dist/managed-sign-in-methods.d.ts +56 -0
  150. package/dist/managed-sign-in-methods.js +64 -0
  151. package/dist/managed-sign-in-methods.js.map +1 -0
  152. package/dist/mcp-catalog-limits.d.ts +2 -0
  153. package/dist/mcp-endpoint.js +9 -0
  154. package/dist/mcp-endpoint.js.map +1 -0
  155. package/dist/mcp-oauth.d.ts +2 -2
  156. package/dist/mcp-structured-content.d.ts +25 -0
  157. package/dist/modal-native-proof-v2.d.ts +587 -0
  158. package/dist/modal-native-proof-v2.js +38 -0
  159. package/dist/modal-native-proof-v2.js.map +1 -0
  160. package/dist/model-account-choice.d.ts +235 -0
  161. package/dist/model-account-settings.d.ts +422 -0
  162. package/dist/model-availability.d.ts +15 -0
  163. package/dist/model-connection-access.d.ts +13 -0
  164. package/dist/model-context-inspector.d.ts +98 -0
  165. package/dist/model-display.d.ts +43 -0
  166. package/dist/model-display.js +17 -0
  167. package/dist/model-display.js.map +1 -0
  168. package/dist/model-picker-order.d.ts +3 -1
  169. package/dist/model-picker-order.js +3 -0
  170. package/dist/model-picker-order.js.map +1 -1
  171. package/dist/organization-access.d.ts +412 -0
  172. package/dist/organization-access.js +39 -0
  173. package/dist/organization-access.js.map +1 -0
  174. package/dist/organization-integration-policy.d.ts +27 -0
  175. package/dist/organization-membership-lifecycle.d.ts +38 -0
  176. package/dist/organization-model-usage.d.ts +146 -0
  177. package/dist/organization-model-usage.js +78 -0
  178. package/dist/organization-model-usage.js.map +1 -0
  179. package/dist/organization-recovery.js +2 -1
  180. package/dist/organization-usage.d.ts +138 -0
  181. package/dist/permissions.d.ts +18 -0
  182. package/dist/personal-github.d.ts +1 -0
  183. package/dist/personal-github.js +199 -144
  184. package/dist/personal-github.js.map +1 -1
  185. package/dist/plugin-discovery.js +1 -1
  186. package/dist/prepared-mcp-setup.d.ts +54 -0
  187. package/dist/prepared-mcp-setup.js +12 -0
  188. package/dist/prepared-mcp-setup.js.map +1 -0
  189. package/dist/product-analytics.d.ts +116 -0
  190. package/dist/product-lifecycle-facts.d.ts +73 -0
  191. package/dist/remember.d.ts +98 -6
  192. package/dist/retained-output.d.ts +8 -0
  193. package/dist/sandbox-file-artifacts.d.ts +1 -0
  194. package/dist/sandbox-provider-command.d.ts +91 -1
  195. package/dist/sandbox-recovery.d.ts +146 -0
  196. package/dist/secret-generator.d.ts +44 -0
  197. package/dist/secret-references.d.ts +90 -0
  198. package/dist/secret-resolution.d.ts +111 -0
  199. package/dist/secret-totp.d.ts +41 -0
  200. package/dist/session-final-reply.d.ts +6 -0
  201. package/dist/session-final-reply.js +9 -0
  202. package/dist/session-final-reply.js.map +1 -0
  203. package/dist/session-goal-reports.d.ts +21 -0
  204. package/dist/session-history-import.d.ts +1272 -0
  205. package/dist/session-list-entries.d.ts +4 -0
  206. package/dist/session-list-entries.js +56 -0
  207. package/dist/session-list-entries.js.map +1 -0
  208. package/dist/session-mcp-projections.d.ts +6 -0
  209. package/dist/session-mcp-tool-permissions.d.ts +62 -0
  210. package/dist/session-message-search.d.ts +68 -0
  211. package/dist/session-target.d.ts +18 -0
  212. package/dist/session-titles.d.ts +8 -0
  213. package/dist/session-titles.js +5 -1
  214. package/dist/session-usage-limit-refusal.d.ts +34 -0
  215. package/dist/session-usage-limit-refusal.js +15 -0
  216. package/dist/session-usage-limit-refusal.js.map +1 -0
  217. package/dist/session-usage-limits.d.ts +127 -0
  218. package/dist/session-usage-limits.js +41 -0
  219. package/dist/session-usage-limits.js.map +1 -0
  220. package/dist/signup-attribution.d.ts +39 -0
  221. package/dist/site-data.d.ts +286 -0
  222. package/dist/site-operations.d.ts +39 -0
  223. package/dist/site-publishing.d.ts +778 -0
  224. package/dist/site-session-http.d.ts +89 -4
  225. package/dist/site-session-http.js +25 -1
  226. package/dist/site-sql.d.ts +421 -0
  227. package/dist/skill-catalog-context.d.ts +7 -0
  228. package/dist/skill-files.d.ts +1 -1
  229. package/dist/skill-use.d.ts +61 -0
  230. package/dist/skills.d.ts +15 -0
  231. package/dist/slack-bot-scopes.d.ts +17 -12
  232. package/dist/slack-bot-scopes.js +10 -3
  233. package/dist/slack-rest-mcp.d.ts +36 -0
  234. package/dist/slack-rest-mcp.js +25 -0
  235. package/dist/slack-rest-mcp.js.map +1 -0
  236. package/dist/spreadsheet-artifact-commands.d.ts +14 -1
  237. package/dist/spreadsheet-artifact-commands.js +8 -2
  238. package/dist/spreadsheet-artifact-query.d.ts +13 -6
  239. package/dist/spreadsheet-artifact-query.js +3 -3
  240. package/dist/subscription-account-actions.d.ts +64 -0
  241. package/dist/subscription-account-pools.d.ts +292 -0
  242. package/dist/subscription-personal-authority-v2.d.ts +28 -0
  243. package/dist/subscription-personal-authority-v2.js +12 -0
  244. package/dist/subscription-personal-authority-v2.js.map +1 -0
  245. package/dist/tool-action-review.d.ts +132 -0
  246. package/dist/tool-catalog.d.ts +408 -0
  247. package/dist/tool-policy.d.ts +5 -0
  248. package/dist/tool-review-presentation.d.ts +12 -0
  249. package/dist/tool-review-presentation.js +17 -0
  250. package/dist/tool-review-presentation.js.map +1 -0
  251. package/dist/transcription-recordings.d.ts +21 -0
  252. package/dist/turn-serving-policy.d.ts +221 -0
  253. package/dist/usage-allowances.d.ts +314 -0
  254. package/dist/usage-allowances.js +52 -0
  255. package/dist/usage-allowances.js.map +1 -0
  256. package/dist/vaults.d.ts +1286 -0
  257. package/dist/video-generation.d.ts +3 -0
  258. package/dist/video-generation.js +2 -1
  259. package/dist/workspace-instruction-policies.d.ts +13 -0
  260. package/dist/workspace-integration-wire.d.ts +36 -0
  261. package/dist/workspace-integration-wire.js +23 -0
  262. package/dist/workspace-integration-wire.js.map +1 -0
  263. package/dist/workspace-integrations.d.ts +1028 -0
  264. package/dist/workspace-state.d.ts +85 -416
  265. package/dist/xai-provider-account-authority.js +2 -1
  266. package/package.json +98 -2
  267. package/src/agent-authored-durable-text.ts +14 -11
  268. package/src/agent-config.ts +1698 -0
  269. package/src/agent-instruction-changes.ts +115 -0
  270. package/src/agent-learning.ts +188 -0
  271. package/src/agent-topology.ts +57 -52
  272. package/src/allowance-refusal.ts +81 -0
  273. package/src/analytics-consent-report.ts +20 -0
  274. package/src/api-key-presets.ts +28 -0
  275. package/src/artifact-catalog.ts +82 -0
  276. package/src/artifacts.ts +299 -227
  277. package/src/atlassian-native-retirement.ts +33 -0
  278. package/src/atlassian.ts +135 -108
  279. package/src/browser-storage.ts +10 -0
  280. package/src/bundled-skills.ts +60 -17
  281. package/src/canonical-human-identities.ts +60 -58
  282. package/src/claude-provider-account-authority.ts +12 -0
  283. package/src/claude-subscription-oauth.ts +73 -0
  284. package/src/claude-subscription-usage.ts +68 -0
  285. package/src/client-error-report.ts +343 -0
  286. package/src/code-search.ts +105 -0
  287. package/src/codex-provider-account-authority.ts +21 -16
  288. package/src/company-brain-governed-writes.ts +255 -233
  289. package/src/company-brain.ts +164 -153
  290. package/src/company-profile.ts +365 -292
  291. package/src/connect.ts +212 -173
  292. package/src/connection-account-label.ts +46 -0
  293. package/src/connection-authority.ts +183 -364
  294. package/src/connector-attachments.ts +137 -122
  295. package/src/connector-destinations.ts +46 -42
  296. package/src/connector-tool-permissions.ts +117 -0
  297. package/src/cua-desktop-tools.gen.json +6512 -0
  298. package/src/cua-desktop-tools.linux.gen.json +6600 -0
  299. package/src/cua-desktop-tools.ts +36 -0
  300. package/src/cua-desktop-tools.windows.gen.json +6353 -0
  301. package/src/define-schema.ts +10 -0
  302. package/src/direct-model-provider.ts +108 -0
  303. package/src/editable-artifact-committed-transaction.ts +17 -0
  304. package/src/editable-artifact-versions.ts +7 -1
  305. package/src/event-preview.ts +53 -3
  306. package/src/external-identities.ts +262 -145
  307. package/src/feedback.ts +43 -30
  308. package/src/first-party-tool-authorization.ts +356 -0
  309. package/src/github-repository-contracts.ts +78 -64
  310. package/src/google-drive.ts +285 -234
  311. package/src/governed-learning-activation.ts +152 -131
  312. package/src/governed-learning-evaluator.ts +140 -133
  313. package/src/host-mcp-bindings.ts +292 -198
  314. package/src/image-generation.ts +104 -95
  315. package/src/index.ts +13354 -8654
  316. package/src/insights-usage.ts +727 -0
  317. package/src/interaction.ts +3070 -2326
  318. package/src/knowledge-entries.ts +428 -0
  319. package/src/knowledge-preparation.ts +57 -0
  320. package/src/knowledge.ts +246 -213
  321. package/src/managed-auth-session-sets.ts +220 -144
  322. package/src/managed-sign-in-methods.ts +52 -0
  323. package/src/mcp-catalog-limits.ts +2 -0
  324. package/src/mcp-oauth.ts +43 -34
  325. package/src/mcp-receipts.ts +192 -192
  326. package/src/mcp-structured-content.ts +81 -0
  327. package/src/memory-slack-delivery.ts +171 -142
  328. package/src/modal-native-proof-v2.ts +429 -0
  329. package/src/model-account-choice.ts +177 -0
  330. package/src/model-account-settings.ts +210 -0
  331. package/src/model-availability.ts +22 -0
  332. package/src/model-connection-access.ts +61 -14
  333. package/src/model-context-inspector.ts +133 -99
  334. package/src/model-display.ts +221 -0
  335. package/src/model-picker-order.ts +12 -1
  336. package/src/organization-access.ts +217 -0
  337. package/src/organization-integration-policy.ts +63 -0
  338. package/src/organization-membership-lifecycle.ts +528 -382
  339. package/src/organization-model-usage.ts +81 -0
  340. package/src/organization-recovery.ts +147 -135
  341. package/src/organization-usage.ts +94 -0
  342. package/src/permissions.ts +88 -52
  343. package/src/personal-github.ts +210 -171
  344. package/src/preference-registry.ts +314 -258
  345. package/src/prepared-mcp-setup.ts +189 -0
  346. package/src/product-analytics.ts +261 -0
  347. package/src/product-lifecycle-facts.ts +122 -0
  348. package/src/remember.ts +181 -167
  349. package/src/retained-output.ts +194 -165
  350. package/src/sandbox-file-artifacts.ts +60 -47
  351. package/src/sandbox-provider-command.ts +88 -20
  352. package/src/sandbox-recovery.ts +129 -0
  353. package/src/scoped-knowledge.ts +61 -43
  354. package/src/secret-generator.ts +155 -0
  355. package/src/secret-references.ts +414 -0
  356. package/src/secret-resolution.ts +274 -0
  357. package/src/secret-totp.ts +188 -0
  358. package/src/session-final-reply.ts +16 -0
  359. package/src/session-goal-reports.ts +64 -0
  360. package/src/session-history-import.ts +177 -0
  361. package/src/session-list-entries.ts +96 -0
  362. package/src/session-mcp-projections.ts +11 -0
  363. package/src/session-mcp-tool-permissions.ts +108 -0
  364. package/src/session-message-search.ts +61 -0
  365. package/src/session-target.ts +57 -0
  366. package/src/session-titles.ts +80 -10
  367. package/src/session-topology-primitives.ts +19 -12
  368. package/src/session-usage-limit-refusal.ts +101 -0
  369. package/src/session-usage-limits.ts +171 -0
  370. package/src/signup-attribution.ts +86 -0
  371. package/src/site-data.ts +339 -0
  372. package/src/site-operations.ts +154 -0
  373. package/src/site-publishing.ts +876 -0
  374. package/src/site-session-http.ts +294 -16
  375. package/src/site-sql.ts +1123 -0
  376. package/src/skill-catalog-context.ts +50 -0
  377. package/src/skill-files.ts +3 -3
  378. package/src/skill-use.ts +80 -0
  379. package/src/skills.ts +82 -54
  380. package/src/slack-bot-scopes.ts +31 -39
  381. package/src/slack-rest-mcp.ts +222 -0
  382. package/src/slack-task-policy.ts +96 -73
  383. package/src/spreadsheet-artifact-commands.ts +73 -2
  384. package/src/spreadsheet-artifact-query.ts +187 -39
  385. package/src/subscription-account-actions.ts +84 -0
  386. package/src/subscription-account-pools.ts +53 -0
  387. package/src/subscription-personal-authority-v2.ts +66 -0
  388. package/src/task-notes.ts +55 -51
  389. package/src/tool-action-review.ts +258 -0
  390. package/src/tool-catalog.ts +609 -372
  391. package/src/tool-policy.ts +82 -0
  392. package/src/tool-result-spill.ts +12 -9
  393. package/src/tool-review-presentation.ts +385 -0
  394. package/src/transcription-recordings.ts +145 -131
  395. package/src/turn-serving-policy.ts +166 -0
  396. package/src/usage-allowances.ts +248 -0
  397. package/src/vaults.ts +850 -0
  398. package/src/video-generation.ts +385 -360
  399. package/src/work-claims.ts +173 -149
  400. package/src/workspace-instruction-policies.ts +349 -275
  401. package/src/workspace-integration-wire.ts +101 -0
  402. package/src/workspace-integrations.ts +724 -0
  403. package/src/workspace-learning-administration.ts +57 -44
  404. package/src/workspace-learning-policy.ts +127 -96
  405. package/src/workspace-state.ts +253 -333
  406. package/src/xai-provider-account-authority.ts +22 -17
  407. package/dist/chunk-3SIZGL3O.js.map +0 -1
  408. package/dist/chunk-7ABONTXE.js.map +0 -1
  409. package/dist/chunk-BCS7WHCK.js +0 -139
  410. package/dist/chunk-BCS7WHCK.js.map +0 -1
  411. package/dist/chunk-GRG7PHWQ.js +0 -25
  412. package/dist/chunk-GRG7PHWQ.js.map +0 -1
  413. package/dist/chunk-JUFK3T4Q.js +0 -80
  414. package/dist/chunk-JUFK3T4Q.js.map +0 -1
  415. package/dist/chunk-M5ZGRVIQ.js +0 -719
  416. package/dist/chunk-M5ZGRVIQ.js.map +0 -1
  417. package/dist/chunk-MRWYRAS5.js.map +0 -1
  418. package/dist/chunk-OSBYTE3O.js +0 -348
  419. package/dist/chunk-OSBYTE3O.js.map +0 -1
  420. package/dist/chunk-P3HLDT77.js +0 -59
  421. package/dist/chunk-P3HLDT77.js.map +0 -1
  422. package/dist/chunk-TEMFILR7.js +0 -143
  423. package/dist/chunk-TEMFILR7.js.map +0 -1
  424. package/dist/chunk-TXTQIYCV.js.map +0 -1
  425. package/dist/chunk-UR2GFYIE.js +0 -22598
  426. package/dist/chunk-UR2GFYIE.js.map +0 -1
  427. package/dist/chunk-WYBDERIY.js.map +0 -1
  428. package/dist/chunk-Y3KNXVTD.js.map +0 -1
  429. package/dist/chunk-YBW5JSA3.js.map +0 -1
  430. package/dist/chunk-YRXAWWCU.js +0 -45
  431. package/dist/chunk-YRXAWWCU.js.map +0 -1
  432. /package/dist/{chunk-5LYFSZ7O.js.map → chunk-352X6ENP.js.map} +0 -0
  433. /package/dist/{chunk-WBYTNVIW.js.map → chunk-RKX3NQYS.js.map} +0 -0
  434. /package/dist/{chunk-O5LEQHDM.js.map → chunk-Z7WEVGCL.js.map} +0 -0
@@ -0,0 +1,414 @@
1
+ /**
2
+ * The one secret reference grammar (design §10B.2, normative).
3
+ *
4
+ * ```
5
+ * reference = "{{" kind ":" body "}}" ; no whitespace after "{{" or before "}}"
6
+ * kind = "secret" | "secretfile"
7
+ * body = id-form | path-form
8
+ * id-form = "id:" uuid [ "/" segment ] [ "/otp" ] [ "#previous" ]
9
+ * path-form = segment *2( "/" segment ) [ "/otp" ] [ "#previous" ]
10
+ * segment = 1*120( any char except "/" "{" "}" "#" "\" and control chars ),
11
+ * no leading/trailing whitespace
12
+ * escape = "\" reference ; the reference text, literally
13
+ * ```
14
+ *
15
+ * Text that starts with `{{secret:` or `{{secretfile:` and does not parse is
16
+ * an `invalid` token: callers fail it with `invalid_reference` and never pass
17
+ * it through. References are at most 300 characters long.
18
+ *
19
+ * Pure and isomorphic: no I/O, no runtime imports from `./index`.
20
+ */
21
+ import { isValidSecretName, VAULT_LIMITS } from "./vaults";
22
+
23
+ export type SecretReferenceKind = "secret" | "secretfile";
24
+ export type SecretReferenceTarget =
25
+ | { form: "id"; itemId: string; field: string | null }
26
+ | { form: "path"; segments: [string] | [string, string] | [string, string, string] };
27
+ export interface SecretReference {
28
+ kind: SecretReferenceKind;
29
+ raw: string;
30
+ /** Offsets in the source text; `end` is exclusive. */
31
+ start: number;
32
+ end: number;
33
+ target: SecretReferenceTarget;
34
+ otp: boolean;
35
+ previous: boolean;
36
+ }
37
+ export type SecretTextToken =
38
+ /** Escapes already unescaped. */
39
+ | { type: "text"; value: string }
40
+ | { type: "reference"; reference: SecretReference }
41
+ | { type: "invalid"; raw: string; start: number; end: number; reason: string };
42
+
43
+ /** Fast-path needle; also matches `{{secretfile:`. */
44
+ export const SECRET_REFERENCE_MARKER = "{{secret";
45
+
46
+ export class SecretReferenceSyntaxError extends Error {
47
+ readonly reason: string;
48
+ constructor(reason: string, message?: string) {
49
+ super(message ?? `invalid secret reference: ${reason}`);
50
+ this.name = "SecretReferenceSyntaxError";
51
+ this.reason = reason;
52
+ }
53
+ }
54
+
55
+ const PREFIXES: ReadonlyArray<{ prefix: string; kind: SecretReferenceKind }> = [
56
+ // Longest first: "{{secretfile:" must win over "{{secret".
57
+ { prefix: "{{secretfile:", kind: "secretfile" },
58
+ { prefix: "{{secret:", kind: "secret" },
59
+ ];
60
+ const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
61
+ const PREVIOUS_SUFFIX = "#previous";
62
+ const ID_PREFIX = "id:";
63
+
64
+ export function containsSecretReference(text: string): boolean {
65
+ return text.includes(SECRET_REFERENCE_MARKER);
66
+ }
67
+
68
+ function prefixAt(
69
+ text: string,
70
+ index: number,
71
+ ): { prefix: string; kind: SecretReferenceKind } | null {
72
+ for (const candidate of PREFIXES) {
73
+ if (text.startsWith(candidate.prefix, index)) return candidate;
74
+ }
75
+ return null;
76
+ }
77
+
78
+ function isControl(code: number): boolean {
79
+ return code <= 0x1f || (code >= 0x7f && code <= 0x9f);
80
+ }
81
+
82
+ /** Parse the body (between `kind:` and `}}`). Throws SecretReferenceSyntaxError. */
83
+ function parseBody(body: string): {
84
+ target: SecretReferenceTarget;
85
+ otp: boolean;
86
+ previous: boolean;
87
+ } {
88
+ if (body.length === 0)
89
+ throw new SecretReferenceSyntaxError("empty_body", "secret reference is empty");
90
+ let rest = body;
91
+ let previous = false;
92
+ if (rest.endsWith(PREVIOUS_SUFFIX)) {
93
+ previous = true;
94
+ rest = rest.slice(0, -PREVIOUS_SUFFIX.length);
95
+ }
96
+ if (rest.includes("#")) {
97
+ throw new SecretReferenceSyntaxError(
98
+ "unsupported_version_suffix",
99
+ "only #previous is supported, and it must be last",
100
+ );
101
+ }
102
+ const parts = rest.split("/");
103
+ let otp = false;
104
+ if (parts.length >= 2 && parts[parts.length - 1]!.toLowerCase() === "otp") {
105
+ otp = true;
106
+ parts.pop();
107
+ }
108
+ if (parts[0]!.toLowerCase().startsWith(ID_PREFIX)) {
109
+ const itemId = parts[0]!.slice(ID_PREFIX.length);
110
+ if (!UUID_PATTERN.test(itemId)) {
111
+ throw new SecretReferenceSyntaxError("invalid_id", "id: must be followed by an item UUID");
112
+ }
113
+ if (parts.length > 2) {
114
+ throw new SecretReferenceSyntaxError("too_many_segments", "id form takes at most one field");
115
+ }
116
+ const field = parts[1] ?? null;
117
+ if (field !== null) assertSegment(field);
118
+ return { target: { form: "id", itemId: itemId.toLowerCase(), field }, otp, previous };
119
+ }
120
+ if (parts.length > 3) {
121
+ throw new SecretReferenceSyntaxError(
122
+ "too_many_segments",
123
+ "a reference has at most Vault/Item/field",
124
+ );
125
+ }
126
+ for (const segment of parts) assertSegment(segment);
127
+ return {
128
+ target: {
129
+ form: "path",
130
+ segments: parts as [string] | [string, string] | [string, string, string],
131
+ },
132
+ otp,
133
+ previous,
134
+ };
135
+ }
136
+
137
+ function assertSegment(segment: string): void {
138
+ if (segment.length === 0) {
139
+ throw new SecretReferenceSyntaxError("empty_segment", "a reference has an empty name");
140
+ }
141
+ if (!isValidSecretName(segment)) {
142
+ throw new SecretReferenceSyntaxError(
143
+ "invalid_segment",
144
+ `"${segment.slice(0, 40)}" is not a valid vault, item or field name`,
145
+ );
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Scan one candidate starting at `index` (where a prefix matched). Returns the
151
+ * candidate's end (exclusive) and either the parsed reference or a reason.
152
+ */
153
+ function scanCandidate(
154
+ text: string,
155
+ index: number,
156
+ prefix: { prefix: string; kind: SecretReferenceKind },
157
+ ):
158
+ | { ok: true; end: number; reference: SecretReference }
159
+ | { ok: false; end: number; reason: string } {
160
+ const bodyStart = index + prefix.prefix.length;
161
+ const limit = Math.min(text.length, index + VAULT_LIMITS.referenceMaxChars);
162
+ let cursor = bodyStart;
163
+ while (cursor < text.length) {
164
+ const code = text.charCodeAt(cursor);
165
+ const character = text[cursor]!;
166
+ if (character === "}" && text[cursor + 1] === "}") {
167
+ const end = cursor + 2;
168
+ if (end - index > VAULT_LIMITS.referenceMaxChars) {
169
+ return { ok: false, end, reason: "too_long" };
170
+ }
171
+ const raw = text.slice(index, end);
172
+ try {
173
+ const parsed = parseBody(text.slice(bodyStart, cursor));
174
+ return {
175
+ ok: true,
176
+ end,
177
+ reference: { kind: prefix.kind, raw, start: index, end, ...parsed },
178
+ };
179
+ } catch (error) {
180
+ return {
181
+ ok: false,
182
+ end,
183
+ reason: error instanceof SecretReferenceSyntaxError ? error.reason : "invalid",
184
+ };
185
+ }
186
+ }
187
+ if (character === "{" || character === "}" || isControl(code) || cursor >= limit) {
188
+ // Unterminated: the invalid token stops before the offending character.
189
+ const end = Math.max(cursor, bodyStart);
190
+ return { ok: false, end, reason: cursor >= limit ? "too_long" : "unterminated" };
191
+ }
192
+ cursor += 1;
193
+ }
194
+ return { ok: false, end: text.length, reason: "unterminated" };
195
+ }
196
+
197
+ /**
198
+ * Split text into literal text, references and invalid candidates. Adjacent
199
+ * text is merged; an escaped reference (`\{{secret:…}}`) becomes literal
200
+ * text without the backslash. Never throws.
201
+ */
202
+ export function tokenizeSecretText(text: string): SecretTextToken[] {
203
+ if (!containsSecretReference(text)) return text.length > 0 ? [{ type: "text", value: text }] : [];
204
+ const tokens: SecretTextToken[] = [];
205
+ let buffer = "";
206
+ let cursor = 0;
207
+ const flush = () => {
208
+ if (buffer.length > 0) tokens.push({ type: "text", value: buffer });
209
+ buffer = "";
210
+ };
211
+ while (cursor < text.length) {
212
+ const next = text.indexOf(SECRET_REFERENCE_MARKER, cursor);
213
+ if (next < 0) {
214
+ buffer += text.slice(cursor);
215
+ break;
216
+ }
217
+ const prefix = prefixAt(text, next);
218
+ if (prefix === null) {
219
+ // "{{secret" not followed by ":" or "file:" is ordinary text.
220
+ buffer += text.slice(cursor, next + SECRET_REFERENCE_MARKER.length);
221
+ cursor = next + SECRET_REFERENCE_MARKER.length;
222
+ continue;
223
+ }
224
+ // A backslash immediately before the candidate (and not already consumed)
225
+ // escapes it: the candidate is emitted literally, without the backslash.
226
+ const escaped = next - 1 >= cursor && text[next - 1] === "\\";
227
+ const scanned = scanCandidate(text, next, prefix);
228
+ if (escaped) {
229
+ buffer += text.slice(cursor, next - 1) + text.slice(next, scanned.end);
230
+ cursor = scanned.end;
231
+ continue;
232
+ }
233
+ buffer += text.slice(cursor, next);
234
+ flush();
235
+ if (scanned.ok) {
236
+ tokens.push({ type: "reference", reference: scanned.reference });
237
+ } else {
238
+ tokens.push({
239
+ type: "invalid",
240
+ raw: text.slice(next, scanned.end),
241
+ start: next,
242
+ end: scanned.end,
243
+ reason: scanned.reason,
244
+ });
245
+ }
246
+ cursor = scanned.end;
247
+ }
248
+ flush();
249
+ return tokens;
250
+ }
251
+
252
+ /** Valid references only, in text order. */
253
+ export function findSecretReferences(text: string): SecretReference[] {
254
+ if (!containsSecretReference(text)) return [];
255
+ return tokenizeSecretText(text).flatMap((token) =>
256
+ token.type === "reference" ? [token.reference] : [],
257
+ );
258
+ }
259
+
260
+ /** Invalid candidates only, in text order. */
261
+ export function findInvalidSecretReferences(
262
+ text: string,
263
+ ): Array<Extract<SecretTextToken, { type: "invalid" }>> {
264
+ if (!containsSecretReference(text)) return [];
265
+ return tokenizeSecretText(text).filter(
266
+ (token): token is Extract<SecretTextToken, { type: "invalid" }> => token.type === "invalid",
267
+ );
268
+ }
269
+
270
+ /** Parse exactly one reference (`{{…}}`). Throws SecretReferenceSyntaxError. */
271
+ export function parseSecretReference(raw: string): SecretReference {
272
+ const prefix = prefixAt(raw, 0);
273
+ if (prefix === null) {
274
+ throw new SecretReferenceSyntaxError(
275
+ "missing_prefix",
276
+ "a secret reference starts with {{secret: or {{secretfile:",
277
+ );
278
+ }
279
+ const scanned = scanCandidate(raw, 0, prefix);
280
+ if (!scanned.ok) throw new SecretReferenceSyntaxError(scanned.reason);
281
+ if (scanned.end !== raw.length) {
282
+ throw new SecretReferenceSyntaxError("trailing_text", "unexpected text after the reference");
283
+ }
284
+ return scanned.reference;
285
+ }
286
+
287
+ export type FormatSecretReferenceInput =
288
+ | {
289
+ kind?: SecretReferenceKind;
290
+ vault?: string;
291
+ item: string;
292
+ field?: string;
293
+ otp?: boolean;
294
+ previous?: boolean;
295
+ }
296
+ | {
297
+ kind?: SecretReferenceKind;
298
+ itemId: string;
299
+ field?: string;
300
+ otp?: boolean;
301
+ previous?: boolean;
302
+ };
303
+
304
+ /** Build a reference. Throws SecretReferenceSyntaxError when a name cannot be referenced. */
305
+ export function formatSecretReference(input: FormatSecretReferenceInput): string {
306
+ const kind = input.kind ?? "secret";
307
+ const parts: string[] = [];
308
+ if ("itemId" in input) {
309
+ if (!UUID_PATTERN.test(input.itemId)) throw new SecretReferenceSyntaxError("invalid_id");
310
+ parts.push(`${ID_PREFIX}${input.itemId.toLowerCase()}`);
311
+ } else {
312
+ if (input.vault !== undefined) parts.push(input.vault);
313
+ parts.push(input.item);
314
+ }
315
+ if (input.field !== undefined) parts.push(input.field);
316
+ for (const part of "itemId" in input ? parts.slice(1) : parts) assertSegment(part);
317
+ const body = `${parts.join("/")}${input.otp ? "/otp" : ""}${input.previous ? PREVIOUS_SUFFIX : ""}`;
318
+ const raw = `{{${kind}:${body}}}`;
319
+ if (raw.length > VAULT_LIMITS.referenceMaxChars) throw new SecretReferenceSyntaxError("too_long");
320
+ return raw;
321
+ }
322
+
323
+ /** NFC + trim + lowercase. For UI and dedupe only; SQL `vault_name_key` is authoritative. */
324
+ export function secretNameKey(name: string): string {
325
+ return name.normalize("NFC").trim().toLowerCase();
326
+ }
327
+
328
+ /** Canonical dedupe key within one call (same target and modifiers → same key). */
329
+ export function referenceKey(ref: SecretReference): string {
330
+ const target =
331
+ ref.target.form === "id"
332
+ ? `id:${ref.target.itemId.toLowerCase()}/${ref.target.field === null ? "" : secretNameKey(ref.target.field)}`
333
+ : `path:${ref.target.segments.map(secretNameKey).join("/")}`;
334
+ return `${ref.kind}|${target}|${ref.otp ? "otp" : ""}|${ref.previous ? "previous" : ""}`;
335
+ }
336
+
337
+ /** Remove escapes (`\{{secret:…}}` → `{{secret:…}}`); references stay as written. */
338
+ export function unescapeSecretText(text: string): string {
339
+ if (!containsSecretReference(text)) return text;
340
+ return tokenizeSecretText(text)
341
+ .map((token) =>
342
+ token.type === "text"
343
+ ? token.value
344
+ : token.type === "reference"
345
+ ? token.reference.raw
346
+ : token.raw,
347
+ )
348
+ .join("");
349
+ }
350
+
351
+ function walkStrings(value: unknown, visit: (text: string) => void, seen: Set<object>): void {
352
+ if (typeof value === "string") {
353
+ visit(value);
354
+ return;
355
+ }
356
+ if (value === null || typeof value !== "object") return;
357
+ if (seen.has(value)) return;
358
+ seen.add(value);
359
+ if (Array.isArray(value)) {
360
+ for (const entry of value) walkStrings(entry, visit, seen);
361
+ return;
362
+ }
363
+ for (const entry of Object.values(value as Record<string, unknown>))
364
+ walkStrings(entry, visit, seen);
365
+ }
366
+
367
+ /** Every valid reference in every string value of a JSON-like structure. */
368
+ export function collectReferencesDeep(value: unknown): SecretReference[] {
369
+ const out: SecretReference[] = [];
370
+ walkStrings(value, (text) => out.push(...findSecretReferences(text)), new Set());
371
+ return out;
372
+ }
373
+
374
+ /** Every invalid candidate in every string value of a JSON-like structure. */
375
+ export function collectInvalidReferencesDeep(
376
+ value: unknown,
377
+ ): Array<Extract<SecretTextToken, { type: "invalid" }>> {
378
+ const out: Array<Extract<SecretTextToken, { type: "invalid" }>> = [];
379
+ walkStrings(value, (text) => out.push(...findInvalidSecretReferences(text)), new Set());
380
+ return out;
381
+ }
382
+
383
+ /**
384
+ * Deep copy with each reference replaced by `replace(ref)` and escapes
385
+ * removed. Strings without the marker are copied unchanged; invalid
386
+ * candidates are kept verbatim (callers reject them before replacing).
387
+ * Object keys are not rewritten.
388
+ */
389
+ export function replaceReferencesDeep<T>(value: T, replace: (ref: SecretReference) => string): T {
390
+ const replaceText = (text: string): string => {
391
+ if (!containsSecretReference(text)) return text;
392
+ return tokenizeSecretText(text)
393
+ .map((token) =>
394
+ token.type === "text"
395
+ ? token.value
396
+ : token.type === "reference"
397
+ ? replace(token.reference)
398
+ : token.raw,
399
+ )
400
+ .join("");
401
+ };
402
+ const copy = (input: unknown): unknown => {
403
+ if (typeof input === "string") return replaceText(input);
404
+ if (input === null || typeof input !== "object") return input;
405
+ if (Array.isArray(input)) return input.map(copy);
406
+ if (input instanceof Uint8Array || input instanceof Date) return input;
407
+ const out: Record<string, unknown> = {};
408
+ for (const [key, entry] of Object.entries(input as Record<string, unknown>)) {
409
+ out[key] = copy(entry);
410
+ }
411
+ return out;
412
+ };
413
+ return copy(value) as T;
414
+ }
@@ -0,0 +1,274 @@
1
+ /**
2
+ * Secret resolver contract (design §10B.1.3). Types live here; the hosted
3
+ * implementation is `createSecretResolver` in `@opengeni/core` and a static
4
+ * stub is `createStaticSecretResolver` in `@opengeni/vaults/testing`.
5
+ *
6
+ * Invariants: a call resolves all of its references or fails before
7
+ * dispatch (I2); plaintext only ever lives in `ResolvedSecretValue.material`
8
+ * and in delivery locals (I1); TOTP codes are computed at dispatch (I4).
9
+ */
10
+ import type { RequestHumanInputToolInput } from "./index";
11
+ import { parseSecretReference, secretNameKey, type SecretReference } from "./secret-references";
12
+ import { totpCodeAtDispatch, type SecretClock, type TotpParams } from "./secret-totp";
13
+ import type { VaultSource } from "./vaults";
14
+
15
+ export type SecretPrincipal =
16
+ | {
17
+ kind: "attempt";
18
+ accountId: string;
19
+ workspaceId: string;
20
+ sessionId: string;
21
+ turnId: string;
22
+ attemptId: string;
23
+ executionGeneration: number;
24
+ }
25
+ | {
26
+ kind: "site_viewer";
27
+ accountId: string;
28
+ workspaceId: string;
29
+ subjectId: string;
30
+ siteId: string;
31
+ siteVersion: string;
32
+ }
33
+ | {
34
+ kind: "human";
35
+ accountId: string;
36
+ workspaceId: string;
37
+ subjectId: string;
38
+ verifiedHuman: boolean;
39
+ viaApiKey: boolean;
40
+ };
41
+
42
+ export const SECRET_USE_SURFACES = [
43
+ "shell",
44
+ "stdin",
45
+ "file_write",
46
+ "secretfile",
47
+ "view_image",
48
+ "run_on",
49
+ "mcp",
50
+ "codemode",
51
+ "site",
52
+ "browser",
53
+ "desktop",
54
+ "human_reveal",
55
+ ] as const;
56
+ export type SecretUseSurface = (typeof SECRET_USE_SURFACES)[number];
57
+ export interface SecretUseContext {
58
+ surface: SecretUseSurface;
59
+ toolName: string;
60
+ operationId?: string;
61
+ sourceCallId?: string;
62
+ }
63
+
64
+ export type SecretMaterial =
65
+ | { type: "text"; value: string }
66
+ /** File fields. */
67
+ | { type: "bytes"; value: Uint8Array }
68
+ /** The code is computed at dispatch (I4). */
69
+ | { type: "totp"; params: TotpParams };
70
+
71
+ export interface ResolvedSecretValue {
72
+ /** `referenceKey(reference)` */
73
+ key: string;
74
+ reference: SecretReference;
75
+ source: VaultSource;
76
+ vaultId: string;
77
+ vaultName: string;
78
+ itemId: string;
79
+ itemName: string;
80
+ fieldId: string | null;
81
+ fieldName: string;
82
+ version: number | null;
83
+ material: SecretMaterial;
84
+ }
85
+
86
+ export interface SecretResolver {
87
+ readonly principal: SecretPrincipal;
88
+ /** false when agent.capabilities.secrets is off: adapters must pass references through literally (Q-35). */
89
+ readonly enabled: boolean;
90
+ /** All-or-nothing (I2). Throws SecretReferenceError. Keys are referenceKey(ref). */
91
+ resolve(
92
+ refs: readonly SecretReference[],
93
+ use: SecretUseContext,
94
+ ): Promise<Map<string, ResolvedSecretValue>>;
95
+ }
96
+
97
+ export const SECRET_REFERENCE_FAILURE_CODES = [
98
+ "invalid_reference",
99
+ "not_found",
100
+ "ambiguous",
101
+ "denied",
102
+ "no_primary_field",
103
+ "provider_unavailable",
104
+ "provider_rate_limited",
105
+ "provider_auth_expired",
106
+ "too_large",
107
+ "binary_value",
108
+ "unsupported_shell",
109
+ "secretfile_not_allowed",
110
+ ] as const;
111
+ export type SecretReferenceFailureCode = (typeof SECRET_REFERENCE_FAILURE_CODES)[number];
112
+
113
+ export interface SecretReferenceFailure {
114
+ raw: string;
115
+ code: SecretReferenceFailureCode;
116
+ message: string;
117
+ /** ambiguous: ready references to choose from (Q-49). */
118
+ candidates?: string[];
119
+ }
120
+
121
+ export const SECRET_REFERENCE_ERROR_CODE = "secret_reference_error" as const;
122
+
123
+ function failureHint(
124
+ failures: readonly SecretReferenceFailure[],
125
+ askCard: RequestHumanInputToolInput | null,
126
+ ): string {
127
+ const hints: string[] = [];
128
+ if (askCard !== null) {
129
+ hints.push(
130
+ "Nothing was run. A secret is missing: call request_human_input with askCard exactly as given, then retry with the returned references.",
131
+ );
132
+ }
133
+ if (failures.some((failure) => failure.code === "ambiguous")) {
134
+ hints.push("Nothing was run. Retry with one of the candidate references.");
135
+ }
136
+ if (failures.some((failure) => failure.code === "invalid_reference")) {
137
+ hints.push(
138
+ "Nothing was run. Fix the reference syntax: {{secret:Item}}, {{secret:Item/field}}, {{secret:Vault/Item/field}}, {{secret:id:<uuid>}}, optional /otp and #previous. Escape a literal reference as \\{{secret:…}}.",
139
+ );
140
+ }
141
+ if (hints.length === 0) hints.push("Nothing was run. See each failure's message.");
142
+ return hints.join(" ");
143
+ }
144
+
145
+ /** Thrown by `SecretResolver.resolve` and by delivery adapters before dispatch. */
146
+ export class SecretReferenceError extends Error {
147
+ readonly code = SECRET_REFERENCE_ERROR_CODE;
148
+ readonly failures: SecretReferenceFailure[];
149
+ readonly askCard: RequestHumanInputToolInput | null;
150
+
151
+ constructor(
152
+ failures: SecretReferenceFailure[],
153
+ askCard: RequestHumanInputToolInput | null = null,
154
+ ) {
155
+ const first = failures[0];
156
+ super(
157
+ first === undefined
158
+ ? "secret reference error"
159
+ : `${first.code}: ${first.message}${failures.length > 1 ? ` (+${failures.length - 1} more)` : ""}`,
160
+ );
161
+ this.name = "SecretReferenceError";
162
+ this.failures = failures;
163
+ this.askCard = askCard;
164
+ }
165
+
166
+ /** JSON string for tool output: {error, failures, askCard, hint}. Never contains values. */
167
+ toModelOutput(): string {
168
+ return JSON.stringify({
169
+ error: this.code,
170
+ failures: this.failures.map((failure) => ({
171
+ raw: failure.raw,
172
+ code: failure.code,
173
+ message: failure.message,
174
+ ...(failure.candidates ? { candidates: failure.candidates } : {}),
175
+ })),
176
+ askCard: this.askCard,
177
+ hint: failureHint(this.failures, this.askCard),
178
+ });
179
+ }
180
+ }
181
+
182
+ export function isSecretReferenceError(error: unknown): error is SecretReferenceError {
183
+ return (
184
+ error instanceof SecretReferenceError ||
185
+ (typeof error === "object" &&
186
+ error !== null &&
187
+ (error as { code?: unknown }).code === SECRET_REFERENCE_ERROR_CODE &&
188
+ Array.isArray((error as { failures?: unknown }).failures))
189
+ );
190
+ }
191
+
192
+ /** Materialize at dispatch: text/bytes as-is; TOTP via totpCodeAtDispatch (waits when < 3 s remain). */
193
+ export async function secretValueAtDispatch(
194
+ v: ResolvedSecretValue,
195
+ clock?: SecretClock,
196
+ ): Promise<string | Uint8Array> {
197
+ switch (v.material.type) {
198
+ case "text":
199
+ return v.material.value;
200
+ case "bytes":
201
+ return v.material.value;
202
+ case "totp":
203
+ return (await totpCodeAtDispatch(v.material.params, clock)).code;
204
+ }
205
+ }
206
+
207
+ const TEXT_FIELD_NAMES = new Set(["username", "user", "email", "login", "account"]);
208
+
209
+ /**
210
+ * The ready-made ask card for `not_found` failures (§10B.1.3, D11): one
211
+ * secret question per missing item. Path references name the item in their
212
+ * last item segment (`Item`, `Item/field` read as Item/field, `Vault/Item/field`);
213
+ * ID references cannot be asked for by name and are skipped. Returns null
214
+ * when nothing can be asked. The model submits it unchanged.
215
+ */
216
+ export function buildMissingSecretAskCard(
217
+ failures: readonly SecretReferenceFailure[],
218
+ ctx: { hasActingHuman: boolean },
219
+ ): RequestHumanInputToolInput | null {
220
+ const saveTo = ctx.hasActingHuman ? "user" : "workspace";
221
+ const questions: RequestHumanInputToolInput["questions"] = [];
222
+ const seen = new Set<string>();
223
+ for (const failure of failures) {
224
+ if (failure.code !== "not_found") continue;
225
+ let reference: SecretReference;
226
+ try {
227
+ reference = parseSecretReference(failure.raw);
228
+ } catch {
229
+ continue;
230
+ }
231
+ if (reference.target.form !== "path") continue;
232
+ const segments = reference.target.segments;
233
+ const item = segments.length === 3 ? segments[1] : segments[0];
234
+ const requestedField = segments.length === 3 ? segments[2] : segments[1];
235
+ const totp = reference.otp && requestedField === undefined;
236
+ const field = requestedField ?? (totp ? "totp" : "password");
237
+ const key = `${secretNameKey(item)}/${secretNameKey(field)}`;
238
+ if (seen.has(key) || questions.length >= 20) continue;
239
+ seen.add(key);
240
+ const fieldKind =
241
+ totp || reference.otp
242
+ ? "totp"
243
+ : TEXT_FIELD_NAMES.has(secretNameKey(field))
244
+ ? "text"
245
+ : "concealed";
246
+ const prompt =
247
+ fieldKind === "totp"
248
+ ? `Enter the two-factor setup key (or otpauth link) for ${item}. It is saved to a vault, never shown in chat.`
249
+ : `Enter the ${field} for ${item}. It is saved to a vault, never shown in chat.`;
250
+ questions.push({
251
+ id: `secret_${questions.length + 1}`,
252
+ kind: "secret",
253
+ prompt,
254
+ label: item.slice(0, 128),
255
+ helpText: null,
256
+ skillReview: null,
257
+ options: [],
258
+ required: true,
259
+ allowOther: false,
260
+ validation: null,
261
+ secret: {
262
+ item,
263
+ field,
264
+ fieldKind,
265
+ itemType: "login",
266
+ saveTo,
267
+ allowGenerate: false,
268
+ autocomplete: fieldKind === "concealed" ? "current-password" : "off",
269
+ },
270
+ });
271
+ }
272
+ if (questions.length === 0) return null;
273
+ return { questions, allowSkip: true, expiresInSeconds: null };
274
+ }