@opengeni/core 3.0.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 (257) hide show
  1. package/README.md +4 -4
  2. package/dist/access/index.d.ts +131 -7
  3. package/dist/access/service-initiator.d.ts +3 -0
  4. package/dist/application/archived-session-imports.d.ts +6 -0
  5. package/dist/application/composer-submit.d.ts +1 -1
  6. package/dist/application/connect-operation.d.ts +6 -0
  7. package/dist/application/external-workspace-members.d.ts +13 -1
  8. package/dist/application/modal-native-live-declaration-join.d.ts +37 -0
  9. package/dist/application/modal-native-original-configuration.d.ts +79 -0
  10. package/dist/application/modal-native-worker-host-transport.d.ts +297 -0
  11. package/dist/application/new-session-drafts.d.ts +29 -2
  12. package/dist/application/organization-privacy.d.ts +57 -0
  13. package/dist/application/prepared-mcp-connection.d.ts +31 -0
  14. package/dist/application/sandbox-recovery.d.ts +58 -0
  15. package/dist/application/session-commands.d.ts +3 -0
  16. package/dist/application/session-tenancy.d.ts +13 -4
  17. package/dist/billing/agent-run-admission.d.ts +21 -0
  18. package/dist/billing/limits.d.ts +27 -1
  19. package/dist/billing/model-call-admission.d.ts +34 -0
  20. package/dist/billing/model-usage-settlement.d.ts +112 -0
  21. package/dist/canonical-human-identities.js +1 -1
  22. package/dist/{chunk-VCZFFEPB.js → chunk-7T2SZ7BI.js} +16 -2
  23. package/dist/chunk-7T2SZ7BI.js.map +1 -0
  24. package/dist/{chunk-ZYCNLYGH.js → chunk-OMJFIIWK.js} +178 -12
  25. package/dist/chunk-OMJFIIWK.js.map +1 -0
  26. package/dist/{chunk-H7X52RI2.js → chunk-QI2M2B2K.js} +83 -8
  27. package/dist/chunk-QI2M2B2K.js.map +1 -0
  28. package/dist/{chunk-OF65T3PM.js → chunk-TTWTXQB2.js} +94 -6
  29. package/dist/chunk-TTWTXQB2.js.map +1 -0
  30. package/dist/codex-model-availability.d.ts +55 -0
  31. package/dist/default-session-model.d.ts +192 -0
  32. package/dist/dependencies.d.ts +41 -7
  33. package/dist/developer-setup-credential-ceiling.d.ts +10 -0
  34. package/dist/domain/agent-config-resolution.d.ts +49 -0
  35. package/dist/domain/automations.d.ts +8 -1
  36. package/dist/domain/capabilities.d.ts +112 -8
  37. package/dist/domain/connection-account-selection-error.d.ts +8 -0
  38. package/dist/domain/connector-tool-permissions.d.ts +62 -0
  39. package/dist/domain/direct-model-provider.d.ts +3 -0
  40. package/dist/domain/editable-artifacts/agent-application.d.ts +10 -1
  41. package/dist/domain/editable-artifacts/durable-export.d.ts +22 -1
  42. package/dist/domain/editable-artifacts/ports.d.ts +10 -0
  43. package/dist/domain/editable-artifacts/service.d.ts +3 -1
  44. package/dist/domain/editable-artifacts/types.d.ts +1 -1
  45. package/dist/domain/encryption-key.d.ts +12 -0
  46. package/dist/domain/insights-timing.d.ts +16 -0
  47. package/dist/domain/insights-usage.d.ts +27 -0
  48. package/dist/domain/insights.d.ts +21 -3
  49. package/dist/domain/knowledge-files.d.ts +1 -1
  50. package/dist/domain/knowledge-preparation.d.ts +10 -0
  51. package/dist/domain/knowledge-preparation.test.d.ts +1 -0
  52. package/dist/domain/knowledge-search.d.ts +15 -76
  53. package/dist/domain/mcp-account-bindings.d.ts +17 -0
  54. package/dist/domain/mcp-account-routes.d.ts +21 -0
  55. package/dist/domain/native-mcp-connection-admission.d.ts +3 -0
  56. package/dist/domain/organization-integration-catalog.d.ts +15 -0
  57. package/dist/domain/personal-connection-delegations.d.ts +73 -12
  58. package/dist/domain/pr-review.d.ts +121 -6
  59. package/dist/domain/realtime-voice-billing.d.ts +103 -0
  60. package/dist/domain/resources.d.ts +17 -1
  61. package/dist/domain/scheduled-task-access.d.ts +265 -0
  62. package/dist/domain/scheduled-task-account-audit.d.ts +27 -0
  63. package/dist/domain/scheduled-task-audience.d.ts +70 -0
  64. package/dist/domain/scheduled-tasks.d.ts +61 -18
  65. package/dist/domain/session-connection-accounts.d.ts +53 -0
  66. package/dist/domain/session-file-access.d.ts +4 -0
  67. package/dist/domain/session-native-connection-replacement.d.ts +14 -0
  68. package/dist/domain/session-start-timing.d.ts +7 -0
  69. package/dist/domain/session-tool-policy.d.ts +102 -4
  70. package/dist/domain/sessions.d.ts +179 -15
  71. package/dist/domain/site-audience.d.ts +52 -0
  72. package/dist/domain/skills.d.ts +29 -1
  73. package/dist/domain/slack-bot.d.ts +46 -1
  74. package/dist/domain/slack-publication-secret-safety.d.ts +1 -1
  75. package/dist/domain/vaults/index.d.ts +7 -0
  76. package/dist/domain/vaults/mapping.d.ts +25 -0
  77. package/dist/domain/vaults/provider-registry.d.ts +72 -0
  78. package/dist/domain/vaults/provider-sync.d.ts +176 -0
  79. package/dist/domain/vaults/provider-writes.d.ts +57 -0
  80. package/dist/domain/vaults/secret-resolver.d.ts +34 -0
  81. package/dist/domain/vaults/types.d.ts +24 -0
  82. package/dist/domain/vaults/vault-service.d.ts +35 -0
  83. package/dist/domain/voice-input-billing.d.ts +77 -0
  84. package/dist/domain/web-search-billing.d.ts +51 -0
  85. package/dist/domain/workspace-credits.d.ts +7 -0
  86. package/dist/editable-artifact-live/application.d.ts +2 -1
  87. package/dist/editable-artifact-live/server.d.ts +5 -1
  88. package/dist/editable-artifact-live/ticket.d.ts +2 -1
  89. package/dist/editable-artifact-live/types.d.ts +9 -0
  90. package/dist/editable-artifact-live.js +2 -2
  91. package/dist/editable-artifacts.js +10 -2
  92. package/dist/goal-admission.d.ts +627 -0
  93. package/dist/host-session-usage-limit.d.ts +15 -0
  94. package/dist/index.d.ts +43 -8
  95. package/dist/index.js +22682 -11743
  96. package/dist/index.js.map +1 -1
  97. package/dist/managed-session.d.ts +110 -7
  98. package/dist/model-call.d.ts +58 -0
  99. package/dist/model-catalog.d.ts +29 -3
  100. package/dist/model-provider-credentials.d.ts +43 -0
  101. package/dist/product-usage-metrics.d.ts +30 -0
  102. package/dist/rigs/index.d.ts +1 -13
  103. package/dist/sandbox/fleet.d.ts +58 -4
  104. package/dist/sandbox/routing.d.ts +42 -2
  105. package/dist/sandbox/runtime-settings.d.ts +27 -17
  106. package/dist/session-authorization.d.ts +10 -0
  107. package/dist/session-usage-limit-metrics.d.ts +60 -0
  108. package/dist/session-usage-limits.d.ts +89 -0
  109. package/dist/site-agent-clamp.d.ts +71 -0
  110. package/dist/site-session-origin.d.ts +39 -2
  111. package/dist/transcription.d.ts +120 -3
  112. package/dist/turn-surface.d.ts +20 -0
  113. package/dist/user-presence.d.ts +32 -0
  114. package/dist/workflow-wake-contract.d.ts +13 -1
  115. package/package.json +15 -22
  116. package/src/access/index.ts +961 -38
  117. package/src/access/service-initiator.ts +50 -0
  118. package/src/application/api-integration-servers.ts +9 -0
  119. package/src/application/archived-session-imports.ts +161 -0
  120. package/src/application/composer-submit.ts +3 -2
  121. package/src/application/connect-authority.ts +3 -3
  122. package/src/application/connect-operation.ts +37 -3
  123. package/src/application/external-continuation.ts +20 -3
  124. package/src/application/external-link-work-admission.ts +3 -0
  125. package/src/application/external-workspace-members.ts +51 -3
  126. package/src/application/modal-native-live-declaration-join.ts +196 -0
  127. package/src/application/modal-native-original-configuration.ts +261 -0
  128. package/src/application/modal-native-worker-host-transport.ts +263 -0
  129. package/src/application/new-session-drafts.ts +172 -55
  130. package/src/application/organization-privacy.ts +161 -0
  131. package/src/application/prepared-mcp-connection.ts +133 -0
  132. package/src/application/sandbox-recovery.ts +78 -0
  133. package/src/application/session-commands.ts +73 -1
  134. package/src/application/session-mcp-credential-rotation.ts +61 -18
  135. package/src/application/session-tenancy.ts +262 -44
  136. package/src/application/user-resource-grants.ts +1 -29
  137. package/src/billing/agent-run-admission.ts +117 -0
  138. package/src/billing/limits.ts +138 -14
  139. package/src/billing/model-call-admission.ts +118 -0
  140. package/src/billing/model-usage-settlement.ts +472 -0
  141. package/src/codex-model-availability.ts +264 -0
  142. package/src/default-session-model.ts +692 -0
  143. package/src/dependencies.ts +48 -6
  144. package/src/developer-setup-credential-ceiling.ts +60 -0
  145. package/src/domain/agent-config-resolution.ts +148 -0
  146. package/src/domain/automations.ts +76 -2
  147. package/src/domain/capabilities.ts +830 -181
  148. package/src/domain/connection-account-selection-error.ts +19 -0
  149. package/src/domain/connector-tool-permissions.ts +572 -0
  150. package/src/domain/direct-model-provider.ts +62 -0
  151. package/src/domain/editable-artifacts/agent-application.ts +44 -6
  152. package/src/domain/editable-artifacts/durable-export.ts +100 -5
  153. package/src/domain/editable-artifacts/in-memory.ts +6 -0
  154. package/src/domain/editable-artifacts/ports.ts +11 -0
  155. package/src/domain/editable-artifacts/service.ts +20 -0
  156. package/src/domain/editable-artifacts/types.ts +1 -1
  157. package/src/domain/encryption-key.ts +26 -0
  158. package/src/domain/file-owner.ts +16 -1
  159. package/src/domain/github-action-policies.ts +1 -1
  160. package/src/domain/github-skill-source.ts +3 -1
  161. package/src/domain/insights-timing.ts +95 -0
  162. package/src/domain/insights-usage.ts +67 -0
  163. package/src/domain/insights.ts +167 -43
  164. package/src/domain/knowledge-files.ts +10 -3
  165. package/src/domain/knowledge-messages.ts +1 -0
  166. package/src/domain/knowledge-preparation.test.ts +276 -0
  167. package/src/domain/knowledge-preparation.ts +147 -0
  168. package/src/domain/knowledge-search.test.ts +617 -5
  169. package/src/domain/knowledge-search.ts +240 -23
  170. package/src/domain/mcp-account-bindings.ts +169 -0
  171. package/src/domain/mcp-account-routes.ts +152 -0
  172. package/src/domain/native-mcp-connection-admission.ts +14 -0
  173. package/src/domain/organization-integration-catalog.ts +88 -0
  174. package/src/domain/personal-connection-delegations.ts +399 -257
  175. package/src/domain/pr-review.ts +24 -8
  176. package/src/domain/realtime-voice-billing.ts +425 -0
  177. package/src/domain/resources.ts +50 -4
  178. package/src/domain/scheduled-task-access.ts +1089 -0
  179. package/src/domain/scheduled-task-account-audit.ts +90 -0
  180. package/src/domain/scheduled-task-audience.ts +249 -0
  181. package/src/domain/scheduled-tasks.ts +1313 -374
  182. package/src/domain/session-connection-accounts.ts +239 -0
  183. package/src/domain/session-file-access.ts +47 -0
  184. package/src/domain/session-native-connection-replacement.ts +64 -0
  185. package/src/domain/session-start-timing.ts +60 -0
  186. package/src/domain/session-tool-policy.ts +489 -14
  187. package/src/domain/sessions.ts +2254 -717
  188. package/src/domain/site-audience.ts +130 -0
  189. package/src/domain/skills.ts +9 -0
  190. package/src/domain/slack-bot.ts +141 -4
  191. package/src/domain/slack-publication-secret-safety.ts +1 -1
  192. package/src/domain/vaults/index.ts +19 -0
  193. package/src/domain/vaults/mapping.ts +190 -0
  194. package/src/domain/vaults/provider-registry.ts +201 -0
  195. package/src/domain/vaults/provider-sync.ts +531 -0
  196. package/src/domain/vaults/provider-writes.ts +288 -0
  197. package/src/domain/vaults/secret-resolver.ts +464 -0
  198. package/src/domain/vaults/types.ts +26 -0
  199. package/src/domain/vaults/vault-service.ts +1316 -0
  200. package/src/domain/voice-input-billing.ts +330 -0
  201. package/src/domain/web-search-billing.ts +169 -0
  202. package/src/domain/workspace-credits.ts +13 -0
  203. package/src/editable-artifact-live/application.ts +8 -1
  204. package/src/editable-artifact-live/server.ts +154 -6
  205. package/src/editable-artifact-live/ticket.ts +86 -1
  206. package/src/editable-artifact-live/types.ts +10 -0
  207. package/src/goal-admission.ts +220 -0
  208. package/src/host-session-usage-limit.ts +25 -0
  209. package/src/index.ts +75 -11
  210. package/src/managed-session.ts +137 -6
  211. package/src/model-call.ts +79 -0
  212. package/src/model-catalog.ts +345 -91
  213. package/src/model-provider-credentials.ts +394 -0
  214. package/src/product-usage-metrics.ts +101 -0
  215. package/src/rigs/index.ts +23 -111
  216. package/src/sandbox/fleet.ts +253 -28
  217. package/src/sandbox/routing.ts +204 -43
  218. package/src/sandbox/runtime-settings.ts +159 -85
  219. package/src/session-authorization.ts +172 -23
  220. package/src/session-usage-limit-metrics.ts +95 -0
  221. package/src/session-usage-limits.ts +415 -0
  222. package/src/site-agent-clamp.ts +226 -0
  223. package/src/site-session-origin.ts +84 -5
  224. package/src/transcription.ts +123 -4
  225. package/src/turn-surface.ts +47 -0
  226. package/src/user-presence.ts +134 -0
  227. package/src/workflow-wake-contract.ts +14 -1
  228. package/dist/application/host-mcp-owner.d.ts +0 -6
  229. package/dist/application/host-mcp-resolvers.d.ts +0 -13
  230. package/dist/chunk-5WZYFL45.js +0 -266
  231. package/dist/chunk-5WZYFL45.js.map +0 -1
  232. package/dist/chunk-H7X52RI2.js.map +0 -1
  233. package/dist/chunk-OF65T3PM.js.map +0 -1
  234. package/dist/chunk-VCZFFEPB.js.map +0 -1
  235. package/dist/chunk-ZYCNLYGH.js.map +0 -1
  236. package/dist/domain/connection-authority.d.ts +0 -97
  237. package/dist/domain/connection-authority.js +0 -169
  238. package/dist/domain/connection-authority.js.map +0 -1
  239. package/dist/domain/environments.d.ts +0 -33
  240. package/dist/domain/host-mcp-authority-source-admission.d.ts +0 -10
  241. package/dist/domain/host-mcp-task-admission.d.ts +0 -18
  242. package/dist/domain/packs.d.ts +0 -59
  243. package/dist/domain/product-integration-pack.d.ts +0 -44
  244. package/dist/domain/product-integration-skill.gen.d.ts +0 -5
  245. package/dist/remote-mcp-credentials.d.ts +0 -23
  246. package/dist/remote-mcp-credentials.js +0 -11
  247. package/dist/remote-mcp-credentials.js.map +0 -1
  248. package/src/application/host-mcp-owner.ts +0 -41
  249. package/src/application/host-mcp-resolvers.ts +0 -84
  250. package/src/domain/connection-authority.ts +0 -329
  251. package/src/domain/environments.ts +0 -120
  252. package/src/domain/host-mcp-authority-source-admission.ts +0 -25
  253. package/src/domain/host-mcp-task-admission.ts +0 -121
  254. package/src/domain/packs.ts +0 -699
  255. package/src/domain/product-integration-pack.ts +0 -42
  256. package/src/domain/product-integration-skill.gen.ts +0 -52
  257. package/src/remote-mcp-credentials.ts +0 -361
@@ -0,0 +1,288 @@
1
+ import {
2
+ generatePassword,
3
+ isValidTotpInput,
4
+ secretNameKey,
5
+ type VaultFieldInput,
6
+ type VaultFieldKind,
7
+ type VaultItemType,
8
+ } from "@opengeni/contracts";
9
+ import {
10
+ getProviderVaultItemRef,
11
+ VaultError,
12
+ type Database,
13
+ type VaultDbContext,
14
+ type VaultFieldRow,
15
+ type VaultRow,
16
+ } from "@opengeni/db";
17
+ import {
18
+ isVaultProviderError,
19
+ type ProviderCallBudget,
20
+ type ProviderWriteField,
21
+ type VaultProvider,
22
+ type VaultProviderRegistry,
23
+ } from "@opengeni/vaults";
24
+ import { vaultErrorCodeForProvider } from "./provider-registry";
25
+ import { syncLinkedProviderVault } from "./provider-sync";
26
+
27
+ /**
28
+ * Edits of items in a read-write connected vault (OP-3): the change is written
29
+ * to the provider (1Password `items.get` → patch → `items.put`, with the
30
+ * mirrored version as the expected version), then the metadata mirror is
31
+ * refreshed. Values never touch Opengeni storage.
32
+ */
33
+
34
+ /** One field change; the REST `VaultFieldInput` and the agent `secret_save` field both fit. */
35
+ export interface ProviderFieldChange {
36
+ fieldId?: string | undefined;
37
+ name: string;
38
+ kind?: VaultFieldKind | undefined;
39
+ value?: string | undefined;
40
+ generate?: VaultFieldInput["generate"] | undefined;
41
+ fromReference?: string | undefined;
42
+ fileBase64?: string | undefined;
43
+ restoreVersion?: number | undefined;
44
+ remove?: true | undefined;
45
+ }
46
+
47
+ export interface ProviderItemChange {
48
+ name?: string | undefined;
49
+ type?: VaultItemType | undefined;
50
+ websites?: string[] | undefined;
51
+ fields?: readonly ProviderFieldChange[] | undefined;
52
+ }
53
+
54
+ export interface ProviderWriteDeps {
55
+ db: Database;
56
+ context: VaultDbContext;
57
+ providers: VaultProviderRegistry;
58
+ /** Resolves `fromReference` field inputs (audited as a use by the caller). */
59
+ resolveReference: (raw: string) => Promise<string>;
60
+ budget?: ProviderCallBudget;
61
+ }
62
+
63
+ const TEXT_FIELD_NAMES = ["username", "user", "email", "login", "account"];
64
+
65
+ function defaultKind(name: string): VaultFieldKind {
66
+ return TEXT_FIELD_NAMES.includes(secretNameKey(name)) ? "text" : "concealed";
67
+ }
68
+
69
+ /** A connected vault the caller may change items in. */
70
+ export function assertProviderVaultWritable(vault: VaultRow): void {
71
+ if (vault.source === "opengeni") {
72
+ throw new VaultError("vault_permission_denied", "not a connected vault");
73
+ }
74
+ if (vault.mode !== "read_write") {
75
+ throw new VaultError("vault_read_only", "vault is read-only", { vaultId: vault.id });
76
+ }
77
+ if (vault.ownerKind === "user" && !vault.ownedByCaller) {
78
+ throw new VaultError("vault_not_found", "vault not found", { vaultId: vault.id });
79
+ }
80
+ }
81
+
82
+ async function providerFieldWrites(
83
+ fields: readonly ProviderFieldChange[],
84
+ existing: readonly VaultFieldRow[],
85
+ resolveReference: (raw: string) => Promise<string>,
86
+ generated: string[],
87
+ ): Promise<ProviderWriteField[]> {
88
+ const writes: ProviderWriteField[] = [];
89
+ for (const input of fields) {
90
+ const current = existing.find(
91
+ (field) =>
92
+ (input.fieldId !== undefined && field.id === input.fieldId) ||
93
+ secretNameKey(field.name) === secretNameKey(input.name),
94
+ );
95
+ const kind: VaultFieldKind = input.kind ?? current?.kind ?? defaultKind(input.name);
96
+ const base: ProviderWriteField = {
97
+ ...(current?.providerFieldRef ? { externalFieldId: current.providerFieldRef } : {}),
98
+ name: input.name,
99
+ kind,
100
+ };
101
+ if (input.remove) {
102
+ writes.push({ ...base, remove: true });
103
+ continue;
104
+ }
105
+ if (input.restoreVersion !== undefined) {
106
+ throw new VaultError(
107
+ "provider_unavailable",
108
+ "connected vaults keep their history in the provider; restore it there",
109
+ { field: input.name },
110
+ );
111
+ }
112
+ if (input.fileBase64 !== undefined || kind === "file") {
113
+ throw new VaultError(
114
+ "provider_unavailable",
115
+ "files in connected vaults are read-only in Opengeni",
116
+ { field: input.name },
117
+ );
118
+ }
119
+ let value: string;
120
+ if (input.generate !== undefined) {
121
+ value = generatePassword(input.generate);
122
+ generated.push(input.name);
123
+ } else if (input.fromReference !== undefined)
124
+ value = await resolveReference(input.fromReference);
125
+ else value = input.value ?? "";
126
+ if (kind === "totp") {
127
+ if (!isValidTotpInput(value)) {
128
+ throw new VaultError(
129
+ "invalid_secret_name",
130
+ `${input.name} is not a valid two-factor setup key or otpauth:// link`,
131
+ { field: input.name },
132
+ );
133
+ }
134
+ value = value.trim();
135
+ }
136
+ writes.push({ ...base, value });
137
+ }
138
+ return writes;
139
+ }
140
+
141
+ function providerFailure(error: unknown): never {
142
+ if (isVaultProviderError(error)) {
143
+ throw new VaultError(vaultErrorCodeForProvider(error.code, "write"), error.message, {
144
+ ...(error.retryAfterMs ? { retryAfterMs: error.retryAfterMs } : {}),
145
+ });
146
+ }
147
+ throw error;
148
+ }
149
+
150
+ async function providerFor(deps: ProviderWriteDeps, vault: VaultRow): Promise<VaultProvider> {
151
+ try {
152
+ return await deps.providers.forVault({
153
+ source: vault.source,
154
+ providerConnectionId: vault.providerConnectionId,
155
+ });
156
+ } catch (error) {
157
+ return providerFailure(error);
158
+ }
159
+ }
160
+
161
+ async function refreshAndFind(
162
+ deps: ProviderWriteDeps,
163
+ vault: VaultRow,
164
+ providerItemRef: string,
165
+ ): Promise<string> {
166
+ await syncLinkedProviderVault({
167
+ db: deps.db,
168
+ context: deps.context,
169
+ vaultId: vault.id,
170
+ providers: deps.providers,
171
+ force: true,
172
+ ...(deps.budget ? { budget: deps.budget } : {}),
173
+ });
174
+ try {
175
+ const ref = await getProviderVaultItemRef(deps.db, deps.context, {
176
+ vaultId: vault.id,
177
+ providerItemRef,
178
+ });
179
+ return ref.itemId;
180
+ } catch (error) {
181
+ if (error instanceof VaultError && error.code === "vault_item_not_found") {
182
+ throw new VaultError(
183
+ "provider_unavailable",
184
+ "saved in the provider; Opengeni will show it after the next sync",
185
+ { vaultId: vault.id },
186
+ );
187
+ }
188
+ throw error;
189
+ }
190
+ }
191
+
192
+ /** Create (existing = null) or update an item in a connected read-write vault; returns its item id. */
193
+ export async function writeProviderVaultItem(
194
+ deps: ProviderWriteDeps,
195
+ input: {
196
+ vault: VaultRow;
197
+ existing: {
198
+ itemId: string;
199
+ name: string;
200
+ type: VaultItemType;
201
+ websites: string[];
202
+ fields: VaultFieldRow[];
203
+ expectedGeneration?: number | undefined;
204
+ } | null;
205
+ change: ProviderItemChange;
206
+ /** Receives the names of fields whose values were generated. */
207
+ generated?: string[];
208
+ },
209
+ ): Promise<string> {
210
+ const { vault, existing, change } = input;
211
+ assertProviderVaultWritable(vault);
212
+ if ((change.type ?? existing?.type) === "passkey") {
213
+ throw new VaultError("vault_permission_denied", "passkeys live only in Opengeni vaults");
214
+ }
215
+ let externalItemId: string | undefined;
216
+ let expectedVersion: string | null | undefined;
217
+ if (existing) {
218
+ const ref = await getProviderVaultItemRef(deps.db, deps.context, {
219
+ vaultId: vault.id,
220
+ itemId: existing.itemId,
221
+ });
222
+ if (
223
+ existing.expectedGeneration !== undefined &&
224
+ existing.expectedGeneration !== ref.generation
225
+ ) {
226
+ throw new VaultError("vault_generation_conflict", "the item changed; reload and retry", {
227
+ itemId: existing.itemId,
228
+ generation: ref.generation,
229
+ });
230
+ }
231
+ externalItemId = ref.providerItemRef;
232
+ expectedVersion = ref.providerVersion;
233
+ }
234
+ const fields = await providerFieldWrites(
235
+ change.fields ?? [],
236
+ existing?.fields ?? [],
237
+ deps.resolveReference,
238
+ input.generated ?? [],
239
+ );
240
+ const provider = await providerFor(deps, vault);
241
+ let written;
242
+ try {
243
+ written = await provider.writeItem(
244
+ { connectionId: vault.providerConnectionId, budget: deps.budget ?? { take() {} } },
245
+ vault.providerVaultRef ?? "",
246
+ {
247
+ ...(externalItemId ? { externalItemId, expectedVersion: expectedVersion ?? null } : {}),
248
+ name: change.name ?? existing?.name ?? "",
249
+ type: change.type ?? existing?.type ?? "login",
250
+ websites: change.websites ?? existing?.websites ?? [],
251
+ fields,
252
+ },
253
+ );
254
+ } catch (error) {
255
+ return providerFailure(error);
256
+ }
257
+ return await refreshAndFind(deps, vault, written.externalItemId);
258
+ }
259
+
260
+ /** Archive an item in a connected read-write vault (the provider keeps it recoverable). */
261
+ export async function archiveProviderVaultItem(
262
+ deps: ProviderWriteDeps,
263
+ input: { vault: VaultRow; itemId: string },
264
+ ): Promise<void> {
265
+ assertProviderVaultWritable(input.vault);
266
+ const ref = await getProviderVaultItemRef(deps.db, deps.context, {
267
+ vaultId: input.vault.id,
268
+ itemId: input.itemId,
269
+ });
270
+ const provider = await providerFor(deps, input.vault);
271
+ try {
272
+ await provider.archiveItem(
273
+ { connectionId: input.vault.providerConnectionId, budget: deps.budget ?? { take() {} } },
274
+ input.vault.providerVaultRef ?? "",
275
+ ref.providerItemRef,
276
+ );
277
+ } catch (error) {
278
+ providerFailure(error);
279
+ }
280
+ await syncLinkedProviderVault({
281
+ db: deps.db,
282
+ context: deps.context,
283
+ vaultId: input.vault.id,
284
+ providers: deps.providers,
285
+ force: true,
286
+ ...(deps.budget ? { budget: deps.budget } : {}),
287
+ });
288
+ }