@opengeni/db 1.0.1 → 3.1.0-canary.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 (265) hide show
  1. package/dist/attached-browser-devices.d.ts +7 -0
  2. package/dist/automations.d.ts +154 -0
  3. package/dist/canonical-human-identities.js +3 -3
  4. package/dist/capability-integrations.d.ts +13 -0
  5. package/dist/child-lifecycle-notices.d.ts +68 -0
  6. package/dist/{chunk-LTG3S6ZY.js → chunk-EULAN2NP.js} +2 -2
  7. package/dist/{chunk-CUPM3FGB.js → chunk-NJVZPWXY.js} +3 -3
  8. package/dist/{chunk-4SR4HKKA.js → chunk-NMUBV7Z5.js} +19 -11
  9. package/dist/chunk-NMUBV7Z5.js.map +1 -0
  10. package/dist/chunk-OF5OBB76.js +4457 -0
  11. package/dist/chunk-OF5OBB76.js.map +1 -0
  12. package/dist/{chunk-6ZYKCRFO.js → chunk-PR2WMLOQ.js} +7580 -4417
  13. package/dist/chunk-PR2WMLOQ.js.map +1 -0
  14. package/dist/{chunk-ZWREYEWA.js → chunk-SCPUJS53.js} +41 -4
  15. package/dist/chunk-SCPUJS53.js.map +1 -0
  16. package/dist/{chunk-SK7YYHBI.js → chunk-SIBYBA2D.js} +46 -1
  17. package/dist/chunk-SIBYBA2D.js.map +1 -0
  18. package/dist/chunk-TIKF3KTI.js +383 -0
  19. package/dist/chunk-TIKF3KTI.js.map +1 -0
  20. package/dist/chunk-ZZ5LJEFX.js +516 -0
  21. package/dist/chunk-ZZ5LJEFX.js.map +1 -0
  22. package/dist/codemode-operations.d.ts +1 -6
  23. package/dist/company-brain-context-selection-schema.d.ts +705 -0
  24. package/dist/company-brain-context-selection.d.ts +94 -0
  25. package/dist/company-brain-governed-writes.d.ts +24 -0
  26. package/dist/company-brain.d.ts +55 -0
  27. package/dist/company-profile-agent-admin.d.ts +15 -0
  28. package/dist/company-profile-schema.d.ts +619 -2
  29. package/dist/company-profile.d.ts +9 -4
  30. package/dist/connection-authority.d.ts +95 -0
  31. package/dist/connection-scopes.d.ts +8 -0
  32. package/dist/connection-tenancy-backfill.d.ts +41 -0
  33. package/dist/connection-token-resolver.d.ts +30 -1
  34. package/dist/database.d.ts +19 -0
  35. package/dist/editable-artifact-durable-export.js +2 -2
  36. package/dist/editable-artifacts.d.ts +2 -2
  37. package/dist/editable-artifacts.js +3 -3
  38. package/dist/governed-learning-activation-schema.d.ts +984 -0
  39. package/dist/governed-learning-activation.d.ts +98 -0
  40. package/dist/governed-learning-evaluator-schema.d.ts +633 -0
  41. package/dist/governed-learning-evaluator.d.ts +28 -0
  42. package/dist/index.d.ts +1595 -81
  43. package/dist/index.js +21571 -8126
  44. package/dist/index.js.map +1 -1
  45. package/dist/insights.d.ts +18 -0
  46. package/dist/integration-bindings.d.ts +1 -0
  47. package/dist/integration-facets.d.ts +30 -0
  48. package/dist/interaction-placement-loss.d.ts +22 -0
  49. package/dist/managed-human-provisioning.d.ts +25 -0
  50. package/dist/memory-domain.d.ts +3 -3
  51. package/dist/migrate.d.ts +11 -1
  52. package/dist/migrate.js +1 -1
  53. package/dist/new-session-drafts.d.ts +43 -5
  54. package/dist/organization-membership-backfill.d.ts +174 -0
  55. package/dist/organization-membership-lifecycle.d.ts +162 -0
  56. package/dist/pr-review.d.ts +107 -0
  57. package/dist/preference-registry-schema.d.ts +2 -0
  58. package/dist/preference-registry.d.ts +2 -0
  59. package/dist/provision-roles.js +1 -1
  60. package/dist/runtime-posture.d.ts +22 -8
  61. package/dist/schema.d.ts +24914 -13703
  62. package/dist/schema.js +99 -1
  63. package/dist/scoped-knowledge-schema.d.ts +52 -1
  64. package/dist/session-background-commands.d.ts +125 -0
  65. package/dist/session-background-commands.js +34 -0
  66. package/dist/session-background-commands.js.map +1 -0
  67. package/dist/session-control.d.ts +156 -3
  68. package/dist/session-goal-pacing.d.ts +68 -0
  69. package/dist/session-queue-commands.d.ts +41 -4
  70. package/dist/session-realtime-ledger.d.ts +2 -0
  71. package/dist/session-tenancy.d.ts +71 -1
  72. package/dist/session-tenancy.js +25 -3
  73. package/dist/session-tool-call-settlement.d.ts +9 -4
  74. package/dist/slack-routing-personal-workspace.d.ts +23 -0
  75. package/dist/slack-routing.d.ts +153 -0
  76. package/dist/slack-task-policy-schema.d.ts +34 -0
  77. package/dist/slack-task-policy.d.ts +8 -0
  78. package/dist/slack-user-link-access.d.ts +1 -0
  79. package/dist/task-notes-schema.d.ts +594 -0
  80. package/dist/task-notes.d.ts +39 -0
  81. package/dist/turn-initiator.d.ts +2 -0
  82. package/dist/user-resource-authority.d.ts +109 -0
  83. package/dist/video-generation.js +3 -3
  84. package/dist/workspace-authority.d.ts +81 -0
  85. package/dist/workspace-instruction-policies-schema.d.ts +279 -0
  86. package/dist/workspace-instruction-policies.d.ts +62 -0
  87. package/dist/workspace-learning-policy.d.ts +1 -0
  88. package/dist/workspace-membership-permissions.d.ts +2 -0
  89. package/drizzle/0240_enrollment_connection_authority.sql +39 -0
  90. package/drizzle/0241_atomic_personal_resource_delegation.sql +1000 -0
  91. package/drizzle/0241_enrollment_agent_runtime.sql +70 -0
  92. package/drizzle/0244_slack_app_home_refresh_queue.sql +120 -0
  93. package/drizzle/0245_model_context_contribution_facts.sql +88 -0
  94. package/drizzle/0246_integration_personal_instance_authority.sql +70 -0
  95. package/drizzle/0247_terraform_stacks_provenance_repair.sql +428 -0
  96. package/drizzle/0248_terraform_stacks_component_resolution_fence.sql +83 -0
  97. package/drizzle/0249_personal_resource_delegation_authority_correction.sql +662 -0
  98. package/drizzle/0250_direct_retained_process_owner_liveness.sql +199 -0
  99. package/drizzle/0251_connected_machine_operation_policy.sql +45 -0
  100. package/drizzle/0252_scheduled_personal_resource_delegation.sql +1867 -0
  101. package/drizzle/0253_common_user_resource_authority_lifecycle.sql +1555 -0
  102. package/drizzle/0254_scoped_variable_set_authority.sql +1255 -0
  103. package/drizzle/0255_company_brain_governed_write_proposals.sql +524 -0
  104. package/drizzle/0256_connection_authority_delegation.sql +703 -0
  105. package/drizzle/0257_goal_revision_decisions_and_root_constraints.sql +436 -0
  106. package/drizzle/0258_three_scope_document_knowledge_authority.sql +1273 -0
  107. package/drizzle/0259_company_brain_context_selection_receipts.sql +869 -0
  108. package/drizzle/0260_task_note_knowledge_promotion.sql +820 -0
  109. package/drizzle/0261_preference_knowledge_proposal_actor_binding.sql +471 -0
  110. package/drizzle/0262_scoped_connected_machines_and_rigs.sql +1700 -0
  111. package/drizzle/0263_organization_membership_lifecycle.sql +3284 -0
  112. package/drizzle/0264_connection_authority_runtime_activation.sql +1084 -0
  113. package/drizzle/0266_company_brain_context_receipt_inspection.sql +156 -0
  114. package/drizzle/0268_governed_learning_decision_receipts.sql +825 -0
  115. package/drizzle/0269_governed_learning_activation_controller.sql +1874 -0
  116. package/drizzle/0270_governed_learning_history_inspection.sql +170 -0
  117. package/drizzle/0271_company_brain_retrieval_only_default.sql +524 -0
  118. package/drizzle/0272_human_confirmed_learning_activation.sql +591 -0
  119. package/drizzle/0273_scheduled_variable_set_materialization.sql +268 -0
  120. package/drizzle/0274_human_confirmed_knowledge_review.sql +310 -0
  121. package/drizzle/0275_scheduled_connection_authority.sql +5527 -0
  122. package/drizzle/0276_onboarding_proposal_initiating_human_guc.sql +198 -0
  123. package/drizzle/0277_workspace_writer_authority_attribution.sql +393 -0
  124. package/drizzle/0278_workspace_membership_removal_fencing.sql +1174 -0
  125. package/drizzle/0279_workspace_connection_use_lane.sql +343 -0
  126. package/drizzle/0280_connection_and_variable_set_audit_attribution.sql +773 -0
  127. package/drizzle/0281_viewer_holder_authority_claims.sql +52 -0
  128. package/drizzle/0282_variable_set_session_attach_attribution.sql +178 -0
  129. package/drizzle/0283_editable_spreadsheet_authored_state.sql +82 -0
  130. package/drizzle/0284_truthful_human_confirmed_review_reason.sql +930 -0
  131. package/drizzle/0285_organization_tenancy_inventory.sql +329 -0
  132. package/drizzle/0286_widen_task_note_expiry_ceiling.sql +391 -0
  133. package/drizzle/0287_open_suffix_pending_tool_calls.sql +18 -0
  134. package/drizzle/0288_attached_browser_reenrollment.sql +64 -0
  135. package/drizzle/0289_session_composer_policy_authority.sql +597 -0
  136. package/drizzle/0290_organization_membership_backfill.sql +268 -0
  137. package/drizzle/0291_resource_authority_classification_assertion.sql +371 -0
  138. package/drizzle/0292_truthful_tenancy_inventory_counters.sql +291 -0
  139. package/drizzle/0293_confirm_time_rule_rebaseline.sql +615 -0
  140. package/drizzle/0294_preference_activation_authority.sql +237 -0
  141. package/drizzle/0295_retire_legacy_standing_memory_mode.sql +476 -0
  142. package/drizzle/0296_force_rls_backfill_noop_repair.sql +215 -0
  143. package/drizzle/0297_session_ownership_classification_and_backfill.sql +752 -0
  144. package/drizzle/0298_organization_tenancy_parity.sql +609 -0
  145. package/drizzle/0299_organization_membership_lock_order.sql +291 -0
  146. package/drizzle/0300_tenancy_backfill_ledger.sql +459 -0
  147. package/drizzle/0301_session_snapshot_and_pin_visibility.sql +181 -0
  148. package/drizzle/0302_personal_workspace_session_ownership.sql +303 -0
  149. package/drizzle/0303_session_tenancy_product_activation.sql +919 -0
  150. package/drizzle/0304_personal_workspace_private_session_reads.sql +97 -0
  151. package/drizzle/0305_personal_resource_grant_management.sql +584 -0
  152. package/drizzle/0306_atomic_personal_resource_attachments.sql +1374 -0
  153. package/drizzle/0307_session_attention_state.sql +51 -0
  154. package/drizzle/0308_session_archives.sql +35 -0
  155. package/drizzle/0309_channel_project_pins.sql +6 -0
  156. package/drizzle/0310_channel_project_order.sql +27 -0
  157. package/drizzle/0311_company_scope_and_private_session_create.sql +656 -0
  158. package/drizzle/0312_quiescent_session_tree_deletion.sql +39 -0
  159. package/drizzle/0313_private_child_session_authority.sql +365 -0
  160. package/drizzle/0314_unregistered_organization_invitations.sql +606 -0
  161. package/drizzle/0315_personal_github_repository_selection.sql +624 -0
  162. package/drizzle/0316_human_confirmed_activation_resumed_generation.sql +869 -0
  163. package/drizzle/0317_session_goal_continuation_hold.sql +64 -0
  164. package/drizzle/0318_session_turn_startup_milestones.sql +115 -0
  165. package/drizzle/0319_event_triggered_automations.sql +254 -0
  166. package/drizzle/0320_pr_review_pack.sql +113 -0
  167. package/drizzle/0321_slack_bot_environment_display_name.sql +15 -0
  168. package/drizzle/0322_session_turns_unclaimed_prompt_trigger_index.sql +5 -0
  169. package/drizzle/0323_organization_private_session_enablement.sql +489 -0
  170. package/drizzle/0324_human_confirmed_company_profile_agent_admin.sql +856 -0
  171. package/drizzle/0325_child_lifecycle_notices.sql +44 -0
  172. package/drizzle/0326_interaction_operation_error_codes.sql +62 -0
  173. package/drizzle/0327_slack_first_task_hint.sql +29 -0
  174. package/drizzle/0328_session_background_commands.sql +590 -0
  175. package/drizzle/0329_slack_orchestration_delivery_events.sql +91 -0
  176. package/drizzle/0330_api_key_descriptions.sql +20 -0
  177. package/drizzle/0331_managed_organization_creation.sql +163 -0
  178. package/drizzle/0332_organization_shared_workspace_control_plane.sql +539 -0
  179. package/drizzle/0333_session_turn_prompt_routing.sql +45 -0
  180. package/drizzle/0334_connected_machine_workspace_root.sql +99 -0
  181. package/drizzle/0335_slack_workspace_routing.sql +460 -0
  182. package/drizzle/0336_atomic_session_fork_visibility.sql +667 -0
  183. package/drizzle/0337_slack_routed_action_handles.sql +189 -0
  184. package/drizzle/0338_atomic_connected_machine_attachments.sql +410 -0
  185. package/drizzle/0339_document_authority_reclassification.sql +1153 -0
  186. package/drizzle/0340_tenancy_backfill_activation_evidence.sql +1347 -0
  187. package/drizzle/0341_slack_routing_probe_organization_fence.sql +109 -0
  188. package/package.json +10 -6
  189. package/src/attached-browser-devices.ts +233 -5
  190. package/src/automations.ts +911 -0
  191. package/src/browser-sessions.ts +10 -0
  192. package/src/capability-integrations.ts +175 -1
  193. package/src/child-lifecycle-notices.ts +241 -0
  194. package/src/codemode-operations.ts +1 -35
  195. package/src/company-brain-context-selection-schema.ts +100 -0
  196. package/src/company-brain-context-selection.ts +359 -0
  197. package/src/company-brain-governed-writes.ts +1170 -0
  198. package/src/company-brain.ts +309 -0
  199. package/src/company-profile-agent-admin.ts +225 -0
  200. package/src/company-profile-schema.ts +121 -1
  201. package/src/company-profile.ts +21 -0
  202. package/src/computer-sessions.ts +10 -1
  203. package/src/connection-authority.ts +290 -0
  204. package/src/connection-scopes.ts +20 -0
  205. package/src/connection-tenancy-backfill.ts +81 -0
  206. package/src/connection-token-resolver.ts +263 -31
  207. package/src/database.ts +75 -2
  208. package/src/editable-artifacts-schema.ts +10 -5
  209. package/src/editable-artifacts.ts +21 -11
  210. package/src/governed-learning-activation-schema.ts +121 -0
  211. package/src/governed-learning-activation.ts +588 -0
  212. package/src/governed-learning-evaluator-schema.ts +72 -0
  213. package/src/governed-learning-evaluator.ts +217 -0
  214. package/src/index.ts +11651 -1548
  215. package/src/insights.ts +107 -0
  216. package/src/integration-bindings.ts +88 -6
  217. package/src/integration-facets.ts +287 -84
  218. package/src/interaction-placement-loss.ts +234 -0
  219. package/src/managed-human-provisioning.ts +116 -0
  220. package/src/memory-domain.ts +27 -32
  221. package/src/migrate.ts +77 -1
  222. package/src/new-session-drafts.ts +229 -35
  223. package/src/organization-membership-backfill.ts +735 -0
  224. package/src/organization-membership-lifecycle.ts +985 -0
  225. package/src/pr-review.ts +890 -0
  226. package/src/preference-registry.ts +31 -1
  227. package/src/provision-roles.ts +877 -6
  228. package/src/runtime-posture-cli.ts +2 -0
  229. package/src/runtime-posture.ts +1291 -76
  230. package/src/schema.ts +3303 -428
  231. package/src/scoped-knowledge-schema.ts +16 -8
  232. package/src/scoped-knowledge.ts +1 -1
  233. package/src/session-background-commands.ts +759 -0
  234. package/src/session-control.ts +640 -74
  235. package/src/session-goal-pacing.ts +126 -0
  236. package/src/session-queue-commands.ts +437 -84
  237. package/src/session-realtime-context.ts +3 -3
  238. package/src/session-realtime-ledger.ts +22 -11
  239. package/src/session-realtime-mirror.ts +1 -1
  240. package/src/session-tenancy.ts +403 -49
  241. package/src/session-tool-call-settlement.ts +38 -29
  242. package/src/slack-routing-personal-workspace.ts +67 -0
  243. package/src/slack-routing.ts +469 -0
  244. package/src/slack-task-policy-schema.ts +5 -0
  245. package/src/slack-task-policy.ts +18 -0
  246. package/src/slack-user-link-access.ts +17 -1
  247. package/src/task-notes-schema.ts +74 -0
  248. package/src/task-notes.ts +124 -2
  249. package/src/turn-initiator.ts +8 -0
  250. package/src/user-resource-authority.ts +377 -0
  251. package/src/workspace-authority.ts +160 -0
  252. package/src/workspace-instruction-policies-schema.ts +53 -1
  253. package/src/workspace-instruction-policies.ts +528 -77
  254. package/src/workspace-learning-policy.ts +21 -5
  255. package/src/workspace-membership-permissions.ts +9 -0
  256. package/dist/chunk-4SR4HKKA.js.map +0 -1
  257. package/dist/chunk-6ZYKCRFO.js.map +0 -1
  258. package/dist/chunk-NXAFLCQX.js +0 -2468
  259. package/dist/chunk-NXAFLCQX.js.map +0 -1
  260. package/dist/chunk-SK7YYHBI.js.map +0 -1
  261. package/dist/chunk-WD5ROSLL.js +0 -117
  262. package/dist/chunk-WD5ROSLL.js.map +0 -1
  263. package/dist/chunk-ZWREYEWA.js.map +0 -1
  264. /package/dist/{chunk-LTG3S6ZY.js.map → chunk-EULAN2NP.js.map} +0 -0
  265. /package/dist/{chunk-CUPM3FGB.js.map → chunk-NJVZPWXY.js.map} +0 -0
@@ -0,0 +1,516 @@
1
+ import {
2
+ withRlsContext
3
+ } from "./chunk-SCPUJS53.js";
4
+ import {
5
+ sandboxRetainedProcesses,
6
+ sessionBackgroundCommands,
7
+ sessions
8
+ } from "./chunk-PR2WMLOQ.js";
9
+
10
+ // src/session-background-commands.ts
11
+ import { and, desc, eq, inArray, sql } from "drizzle-orm";
12
+ function commandPreview(value) {
13
+ const normalized = value.replace(/\s+/g, " ").trim();
14
+ return Array.from(normalized).slice(0, 512).join("");
15
+ }
16
+ function mapCommand(row) {
17
+ return {
18
+ id: row.id,
19
+ workspaceId: row.workspaceId,
20
+ sessionId: row.sessionId,
21
+ provider: row.provider,
22
+ state: row.state,
23
+ commandPreview: row.commandPreview,
24
+ cancelRequestedAt: row.cancelRequestedAt?.toISOString() ?? null,
25
+ exitCode: row.exitCode ?? null,
26
+ settlementReason: row.settlementReason ?? null,
27
+ startedAt: row.startedAt.toISOString(),
28
+ settledAt: row.settledAt?.toISOString() ?? null,
29
+ updatedAt: row.updatedAt.toISOString()
30
+ };
31
+ }
32
+ async function backgroundCommandActivityForSessions(db, input) {
33
+ if (input.sessionIds.length === 0) return /* @__PURE__ */ new Map();
34
+ return await withRlsContext(
35
+ db,
36
+ { accountId: input.accountId, workspaceId: input.workspaceId },
37
+ async (scopedDb) => {
38
+ const rows = await scopedDb.select({
39
+ sessionId: sessionBackgroundCommands.sessionId,
40
+ count: sql`count(*)::int`,
41
+ stoppingCount: sql`count(*) filter (where ${sessionBackgroundCommands.state} = 'stopping')::int`
42
+ }).from(sessionBackgroundCommands).where(
43
+ and(
44
+ eq(sessionBackgroundCommands.workspaceId, input.workspaceId),
45
+ inArray(sessionBackgroundCommands.sessionId, input.sessionIds),
46
+ inArray(sessionBackgroundCommands.state, ["running", "stopping"])
47
+ )
48
+ ).groupBy(sessionBackgroundCommands.sessionId);
49
+ return new Map(
50
+ rows.map((row) => [
51
+ row.sessionId,
52
+ {
53
+ state: Number(row.stoppingCount) > 0 ? "stopping" : "running",
54
+ count: Number(row.count)
55
+ }
56
+ ])
57
+ );
58
+ }
59
+ );
60
+ }
61
+ async function listSessionBackgroundCommands(db, input) {
62
+ return await withRlsContext(
63
+ db,
64
+ { accountId: input.accountId, workspaceId: input.workspaceId },
65
+ async (scopedDb) => {
66
+ const rows = await scopedDb.select().from(sessionBackgroundCommands).where(
67
+ and(
68
+ eq(sessionBackgroundCommands.workspaceId, input.workspaceId),
69
+ eq(sessionBackgroundCommands.sessionId, input.sessionId)
70
+ )
71
+ ).orderBy(
72
+ desc(sessionBackgroundCommands.startedAt),
73
+ desc(sessionBackgroundCommands.id)
74
+ ).limit(1e3);
75
+ return rows.map(mapCommand);
76
+ }
77
+ );
78
+ }
79
+ async function insertManagedSessionBackgroundCommandInTransaction(db, input) {
80
+ const [process] = await db.select({
81
+ accountId: sandboxRetainedProcesses.accountId,
82
+ workspaceId: sandboxRetainedProcesses.workspaceId,
83
+ sessionId: sandboxRetainedProcesses.sessionId,
84
+ state: sandboxRetainedProcesses.state
85
+ }).from(sandboxRetainedProcesses).where(eq(sandboxRetainedProcesses.id, input.retainedProcessId)).for("update").limit(1);
86
+ if (!process || process.accountId !== input.accountId || process.workspaceId !== input.workspaceId || process.sessionId !== input.sessionId || process.state !== "active") {
87
+ throw new Error("Managed background command requires its exact active retained process");
88
+ }
89
+ const [row] = await db.insert(sessionBackgroundCommands).values({
90
+ id: input.commandId,
91
+ accountId: input.accountId,
92
+ workspaceId: input.workspaceId,
93
+ sessionId: input.sessionId,
94
+ provider: "managed",
95
+ state: "running",
96
+ retainedProcessId: input.retainedProcessId,
97
+ commandPreview: commandPreview(input.command)
98
+ }).onConflictDoUpdate({
99
+ target: sessionBackgroundCommands.retainedProcessId,
100
+ targetWhere: sql`${sessionBackgroundCommands.retainedProcessId} is not null`,
101
+ set: { updatedAt: /* @__PURE__ */ new Date() }
102
+ }).returning();
103
+ if (!row) throw new Error("Managed background command adoption returned no row");
104
+ if (row.accountId !== input.accountId || row.workspaceId !== input.workspaceId || row.sessionId !== input.sessionId || row.provider !== "managed" || row.retainedProcessId !== input.retainedProcessId) {
105
+ throw new Error("Managed background command adoption conflicted with another identity");
106
+ }
107
+ return mapCommand(row);
108
+ }
109
+ async function insertConnectedMachineSessionBackgroundCommandInTransaction(db, input) {
110
+ const [row] = await db.insert(sessionBackgroundCommands).values({
111
+ id: input.commandId,
112
+ accountId: input.accountId,
113
+ workspaceId: input.workspaceId,
114
+ sessionId: input.sessionId,
115
+ provider: "connected_machine",
116
+ state: "running",
117
+ controlWorkspaceId: input.controlWorkspaceId,
118
+ enrollmentId: input.enrollmentId,
119
+ connectionInstanceId: input.connectionInstanceId,
120
+ opId: input.opId,
121
+ commandPreview: commandPreview(input.command)
122
+ }).onConflictDoUpdate({
123
+ target: [
124
+ sessionBackgroundCommands.controlWorkspaceId,
125
+ sessionBackgroundCommands.enrollmentId,
126
+ sessionBackgroundCommands.connectionInstanceId,
127
+ sessionBackgroundCommands.opId
128
+ ],
129
+ targetWhere: sql`${sessionBackgroundCommands.provider} = 'connected_machine'`,
130
+ set: { updatedAt: /* @__PURE__ */ new Date() }
131
+ }).returning();
132
+ if (!row) throw new Error("Connected Machine background command adoption returned no row");
133
+ if (row.accountId !== input.accountId || row.workspaceId !== input.workspaceId || row.sessionId !== input.sessionId || row.provider !== "connected_machine" || row.controlWorkspaceId !== input.controlWorkspaceId || row.enrollmentId !== input.enrollmentId || row.connectionInstanceId !== input.connectionInstanceId || row.opId !== input.opId) {
134
+ throw new Error(
135
+ "Connected Machine background command adoption conflicted with another identity"
136
+ );
137
+ }
138
+ return mapCommand(row);
139
+ }
140
+ async function claimConnectedMachineSessionBackgroundCommands(db, input) {
141
+ if (!Number.isSafeInteger(input.limit) || input.limit < 1 || input.limit > 100) {
142
+ throw new Error("Connected command reconciliation limit must be between 1 and 100");
143
+ }
144
+ if (!Number.isSafeInteger(input.claimTtlMs) || input.claimTtlMs < 0 || input.claimTtlMs > 36e5) {
145
+ throw new Error("Connected command reconciliation claim TTL is invalid");
146
+ }
147
+ const rows = await db.execute(sql`
148
+ select account_id as "accountId",
149
+ workspace_id as "workspaceId",
150
+ session_id as "sessionId",
151
+ command_id as "commandId",
152
+ claim_id as "claimId",
153
+ command_state as "commandState",
154
+ control_workspace_id as "controlWorkspaceId",
155
+ enrollment_id as "enrollmentId",
156
+ connection_instance_id as "connectionInstanceId",
157
+ op_id as "opId",
158
+ reconcile_attempts as "reconcileAttempts",
159
+ reconcile_proof_outcome as "reconcileProofOutcome",
160
+ reconcile_proof_exit_code as "reconcileProofExitCode",
161
+ reconcile_proof_reason as "reconcileProofReason",
162
+ reconcile_proof_observed_at as "reconcileProofObservedAt"
163
+ from opengeni_private.claim_connected_machine_background_commands(
164
+ ${input.claimId}::uuid, ${input.limit}::integer, ${input.claimTtlMs}::bigint
165
+ )
166
+ `);
167
+ return rows.map((row) => {
168
+ if (row.commandState !== "running" && row.commandState !== "stopping") {
169
+ throw new Error(`Connected command claim returned invalid state ${row.commandState}`);
170
+ }
171
+ const proof = row.reconcileProofOutcome === null ? null : row.reconcileProofOutcome === "exited" || row.reconcileProofOutcome === "lost" ? {
172
+ outcome: row.reconcileProofOutcome,
173
+ exitCode: row.reconcileProofExitCode === null ? null : Number(row.reconcileProofExitCode),
174
+ reason: row.reconcileProofReason,
175
+ observedAt: row.reconcileProofObservedAt instanceof Date ? row.reconcileProofObservedAt : new Date(row.reconcileProofObservedAt)
176
+ } : (() => {
177
+ throw new Error(
178
+ `Connected command claim returned invalid proof ${row.reconcileProofOutcome}`
179
+ );
180
+ })();
181
+ return {
182
+ commandId: row.commandId,
183
+ accountId: row.accountId,
184
+ workspaceId: row.workspaceId,
185
+ sessionId: row.sessionId,
186
+ claimId: row.claimId,
187
+ state: row.commandState,
188
+ controlWorkspaceId: row.controlWorkspaceId,
189
+ enrollmentId: row.enrollmentId,
190
+ connectionInstanceId: row.connectionInstanceId,
191
+ opId: row.opId,
192
+ reconcileAttempts: Number(row.reconcileAttempts),
193
+ proof
194
+ };
195
+ });
196
+ }
197
+ function connectedClaimIdentityWhere(claim) {
198
+ return and(
199
+ eq(sessionBackgroundCommands.id, claim.commandId),
200
+ eq(sessionBackgroundCommands.accountId, claim.accountId),
201
+ eq(sessionBackgroundCommands.workspaceId, claim.workspaceId),
202
+ eq(sessionBackgroundCommands.sessionId, claim.sessionId),
203
+ eq(sessionBackgroundCommands.provider, "connected_machine"),
204
+ eq(sessionBackgroundCommands.controlWorkspaceId, claim.controlWorkspaceId),
205
+ eq(sessionBackgroundCommands.enrollmentId, claim.enrollmentId),
206
+ eq(sessionBackgroundCommands.connectionInstanceId, claim.connectionInstanceId),
207
+ eq(sessionBackgroundCommands.opId, claim.opId),
208
+ eq(sessionBackgroundCommands.reconcileClaimId, claim.claimId),
209
+ inArray(sessionBackgroundCommands.state, ["running", "stopping"])
210
+ );
211
+ }
212
+ async function recordConnectedMachineBackgroundCommandProof(db, input) {
213
+ const reason = input.proof.reason.trim().slice(0, 512);
214
+ if (!reason) throw new Error("Connected command proof reason must not be empty");
215
+ if (input.proof.outcome === "exited" && input.proof.exitCode === null) {
216
+ throw new Error("Connected command exit proof requires an exit code");
217
+ }
218
+ if (input.proof.outcome === "lost" && input.proof.exitCode !== null) {
219
+ throw new Error("Connected command loss proof cannot carry an exit code");
220
+ }
221
+ await withRlsContext(
222
+ db,
223
+ { accountId: input.claim.accountId, workspaceId: input.claim.workspaceId },
224
+ async (scopedDb) => {
225
+ const [current] = await scopedDb.select().from(sessionBackgroundCommands).where(connectedClaimIdentityWhere(input.claim)).for("update").limit(1);
226
+ if (!current) throw new Error("Connected command proof was fenced by newer lifecycle state");
227
+ if (current.reconcileProofOutcome !== null) {
228
+ const observedAt = current.reconcileProofObservedAt?.getTime() ?? null;
229
+ if (current.reconcileProofOutcome !== input.proof.outcome || current.reconcileProofExitCode !== input.proof.exitCode || current.reconcileProofReason !== reason || observedAt !== input.proof.observedAt.getTime()) {
230
+ throw new Error("Connected command reconciliation proof conflicts with durable proof");
231
+ }
232
+ return;
233
+ }
234
+ const rows = await scopedDb.update(sessionBackgroundCommands).set({
235
+ reconcileProofOutcome: input.proof.outcome,
236
+ reconcileProofExitCode: input.proof.exitCode,
237
+ reconcileProofReason: reason,
238
+ reconcileProofObservedAt: input.proof.observedAt,
239
+ lastReconcileOutcome: `proof_${input.proof.outcome}`,
240
+ updatedAt: /* @__PURE__ */ new Date()
241
+ }).where(connectedClaimIdentityWhere(input.claim)).returning({ id: sessionBackgroundCommands.id });
242
+ if (rows.length !== 1) {
243
+ throw new Error("Connected command proof lost its exact claim during checkpoint");
244
+ }
245
+ }
246
+ );
247
+ }
248
+ async function deferConnectedMachineBackgroundCommandReconciliation(db, input) {
249
+ if (!Number.isSafeInteger(input.retryAfterMs) || input.retryAfterMs < 0) {
250
+ throw new Error("Connected command reconciliation retry delay is invalid");
251
+ }
252
+ const outcome = input.outcome.trim().slice(0, 64);
253
+ if (!outcome) throw new Error("Connected command reconciliation outcome must not be empty");
254
+ return await withRlsContext(
255
+ db,
256
+ { accountId: input.claim.accountId, workspaceId: input.claim.workspaceId },
257
+ async (scopedDb) => {
258
+ const rows = await scopedDb.update(sessionBackgroundCommands).set({
259
+ reconcileAfter: new Date(Date.now() + input.retryAfterMs),
260
+ reconcileClaimId: null,
261
+ reconcileClaimedAt: null,
262
+ lastReconcileOutcome: outcome,
263
+ updatedAt: /* @__PURE__ */ new Date()
264
+ }).where(connectedClaimIdentityWhere(input.claim)).returning({ id: sessionBackgroundCommands.id });
265
+ return rows.length === 1;
266
+ }
267
+ );
268
+ }
269
+ async function settleClaimedConnectedMachineBackgroundCommand(db, input) {
270
+ return await withRlsContext(
271
+ db,
272
+ { accountId: input.claim.accountId, workspaceId: input.claim.workspaceId },
273
+ async (scopedDb) => {
274
+ const rows = await scopedDb.execute(sql`
275
+ update ${sessionBackgroundCommands} command set
276
+ state = command.reconcile_proof_outcome,
277
+ exit_code = case
278
+ when command.reconcile_proof_outcome = 'exited'
279
+ then command.reconcile_proof_exit_code
280
+ else null
281
+ end,
282
+ settlement_reason = command.reconcile_proof_reason,
283
+ settled_at = command.reconcile_proof_observed_at,
284
+ reconcile_claim_id = null,
285
+ reconcile_claimed_at = null,
286
+ last_reconcile_outcome = 'settled_' || command.reconcile_proof_outcome,
287
+ updated_at = clock_timestamp()
288
+ where command.id = ${input.claim.commandId}
289
+ and command.account_id = ${input.claim.accountId}
290
+ and command.workspace_id = ${input.claim.workspaceId}
291
+ and command.session_id = ${input.claim.sessionId}
292
+ and command.provider = 'connected_machine'
293
+ and command.control_workspace_id = ${input.claim.controlWorkspaceId}
294
+ and command.enrollment_id = ${input.claim.enrollmentId}
295
+ and command.connection_instance_id = ${input.claim.connectionInstanceId}
296
+ and command.op_id = ${input.claim.opId}
297
+ and command.reconcile_claim_id = ${input.claim.claimId}
298
+ and command.state in ('running', 'stopping')
299
+ and command.reconcile_proof_outcome in ('exited', 'lost')
300
+ and command.reconcile_proof_observed_at is not null
301
+ returning command.id
302
+ `);
303
+ return rows.length === 1;
304
+ }
305
+ );
306
+ }
307
+ async function requestSessionBackgroundCommandCancellation(db, input) {
308
+ return await withRlsContext(
309
+ db,
310
+ { accountId: input.accountId, workspaceId: input.workspaceId },
311
+ async (scopedDb) => await scopedDb.transaction(async (tx) => {
312
+ const [current] = await tx.select().from(sessionBackgroundCommands).where(
313
+ and(
314
+ eq(sessionBackgroundCommands.workspaceId, input.workspaceId),
315
+ eq(sessionBackgroundCommands.sessionId, input.sessionId),
316
+ eq(sessionBackgroundCommands.id, input.commandId)
317
+ )
318
+ ).for("update").limit(1);
319
+ if (!current) return { command: null, accepted: false };
320
+ if (current.state !== "running") {
321
+ return { command: mapCommand(current), accepted: false };
322
+ }
323
+ const [updated] = await tx.update(sessionBackgroundCommands).set({
324
+ state: "stopping",
325
+ cancelRequestedAt: /* @__PURE__ */ new Date(),
326
+ cancelRequestedBy: input.subjectId.slice(0, 1024),
327
+ reconcileAfter: /* @__PURE__ */ new Date(),
328
+ reconcileClaimId: null,
329
+ reconcileClaimedAt: null,
330
+ updatedAt: /* @__PURE__ */ new Date()
331
+ }).where(eq(sessionBackgroundCommands.id, current.id)).returning();
332
+ if (current.retainedProcessId) {
333
+ await tx.update(sandboxRetainedProcesses).set({ reconcileAfter: /* @__PURE__ */ new Date(), lastReconcileOutcome: "cancel_requested" }).where(
334
+ and(
335
+ eq(sandboxRetainedProcesses.id, current.retainedProcessId),
336
+ eq(sandboxRetainedProcesses.state, "active"),
337
+ sql`${sandboxRetainedProcesses.reconcileClaimId} is null`
338
+ )
339
+ );
340
+ }
341
+ return { command: mapCommand(updated), accepted: true };
342
+ })
343
+ );
344
+ }
345
+ async function requestSessionBackgroundCommandCancellationsInTransaction(db, input) {
346
+ const rootSessionIds = [...new Set(input.rootSessionIds)];
347
+ if (rootSessionIds.length === 0) return 0;
348
+ const rows = await db.execute(sql`
349
+ with recursive roots(id) as (
350
+ values ${sql.join(
351
+ rootSessionIds.map((sessionId) => sql`(${sessionId}::uuid)`),
352
+ sql`, `
353
+ )}
354
+ ), subtree(id, path, cycle) as (
355
+ select session.id, array[session.id]::uuid[], false
356
+ from roots root
357
+ join ${sessions} session
358
+ on session.workspace_id = ${input.workspaceId}
359
+ and session.id = root.id
360
+ union all
361
+ select child.id, parent.path || child.id, child.id = any(parent.path)
362
+ from subtree parent
363
+ join ${sessions} child
364
+ on child.workspace_id = ${input.workspaceId}
365
+ and child.parent_session_id = parent.id
366
+ where not parent.cycle
367
+ ), stopped as (
368
+ update ${sessionBackgroundCommands} command set
369
+ state = 'stopping',
370
+ cancel_requested_at = clock_timestamp(),
371
+ cancel_requested_by = left(${input.subjectId}, 1024),
372
+ reconcile_after = clock_timestamp(),
373
+ reconcile_claim_id = null,
374
+ reconcile_claimed_at = null,
375
+ updated_at = clock_timestamp()
376
+ where command.workspace_id = ${input.workspaceId}
377
+ and command.session_id in (select id from subtree where not cycle)
378
+ and command.state = 'running'
379
+ returning command.retained_process_id
380
+ ), nudged as (
381
+ update ${sandboxRetainedProcesses} process set
382
+ reconcile_after = clock_timestamp(),
383
+ reconcile_claim_id = null,
384
+ reconcile_claimed_at = null,
385
+ last_reconcile_outcome = 'cancel_requested'
386
+ where process.id in (
387
+ select stopped.retained_process_id
388
+ from stopped
389
+ where stopped.retained_process_id is not null
390
+ )
391
+ and process.state = 'active'
392
+ returning process.id
393
+ )
394
+ select count(*)::integer as "commandCount" from stopped
395
+ `);
396
+ return Number(rows[0]?.commandCount ?? 0);
397
+ }
398
+ async function requestWorkspaceBackgroundCommandCancellationsInTransaction(db, input) {
399
+ const rows = await db.execute(sql`
400
+ with stopped as (
401
+ update ${sessionBackgroundCommands} command set
402
+ state = 'stopping',
403
+ cancel_requested_at = clock_timestamp(),
404
+ cancel_requested_by = left(${input.subjectId}, 1024),
405
+ reconcile_after = clock_timestamp(),
406
+ reconcile_claim_id = null,
407
+ reconcile_claimed_at = null,
408
+ updated_at = clock_timestamp()
409
+ where command.workspace_id = ${input.workspaceId}
410
+ and command.state = 'running'
411
+ returning command.retained_process_id
412
+ ), nudged as (
413
+ update ${sandboxRetainedProcesses} process set
414
+ reconcile_after = clock_timestamp(),
415
+ reconcile_claim_id = null,
416
+ reconcile_claimed_at = null,
417
+ last_reconcile_outcome = 'cancel_requested'
418
+ where process.id in (
419
+ select stopped.retained_process_id
420
+ from stopped
421
+ where stopped.retained_process_id is not null
422
+ )
423
+ and process.state = 'active'
424
+ returning process.id
425
+ )
426
+ select count(*)::integer as "commandCount" from stopped
427
+ `);
428
+ return Number(rows[0]?.commandCount ?? 0);
429
+ }
430
+ async function settleSessionBackgroundCommandForRetainedProcess(db, input) {
431
+ return await withRlsContext(
432
+ db,
433
+ { accountId: input.accountId, workspaceId: input.workspaceId },
434
+ async (scopedDb) => {
435
+ const [row] = await scopedDb.update(sessionBackgroundCommands).set({
436
+ state: input.outcome,
437
+ exitCode: input.outcome === "exited" ? input.exitCode : null,
438
+ settlementReason: input.reason.slice(0, 512),
439
+ settledAt: /* @__PURE__ */ new Date(),
440
+ reconcileClaimId: null,
441
+ reconcileClaimedAt: null,
442
+ lastReconcileOutcome: `settled_${input.outcome}`,
443
+ updatedAt: /* @__PURE__ */ new Date()
444
+ }).where(
445
+ and(
446
+ eq(sessionBackgroundCommands.workspaceId, input.workspaceId),
447
+ eq(sessionBackgroundCommands.sessionId, input.sessionId),
448
+ eq(sessionBackgroundCommands.retainedProcessId, input.retainedProcessId),
449
+ inArray(sessionBackgroundCommands.state, ["running", "stopping"])
450
+ )
451
+ ).returning();
452
+ return row ? mapCommand(row) : null;
453
+ }
454
+ );
455
+ }
456
+ async function settleConnectedMachineSessionBackgroundCommand(db, input) {
457
+ return await withRlsContext(
458
+ db,
459
+ { accountId: input.accountId, workspaceId: input.workspaceId },
460
+ async (scopedDb) => {
461
+ const settledAt = /* @__PURE__ */ new Date();
462
+ const reason = input.reason.trim().slice(0, 512);
463
+ if (!reason) throw new Error("Connected command settlement reason must not be empty");
464
+ if (input.outcome === "exited" && input.exitCode === null) {
465
+ throw new Error("Connected command exit settlement requires an exit code");
466
+ }
467
+ if (input.outcome === "lost" && input.exitCode !== null) {
468
+ throw new Error("Connected command loss settlement cannot carry an exit code");
469
+ }
470
+ const [row] = await scopedDb.update(sessionBackgroundCommands).set({
471
+ state: input.outcome,
472
+ exitCode: input.outcome === "exited" ? input.exitCode : null,
473
+ settlementReason: reason,
474
+ settledAt,
475
+ reconcileClaimId: null,
476
+ reconcileClaimedAt: null,
477
+ reconcileProofOutcome: input.outcome,
478
+ reconcileProofExitCode: input.outcome === "exited" ? input.exitCode : null,
479
+ reconcileProofReason: reason,
480
+ reconcileProofObservedAt: settledAt,
481
+ lastReconcileOutcome: `settled_${input.outcome}`,
482
+ updatedAt: /* @__PURE__ */ new Date()
483
+ }).where(
484
+ and(
485
+ eq(sessionBackgroundCommands.workspaceId, input.workspaceId),
486
+ eq(sessionBackgroundCommands.sessionId, input.sessionId),
487
+ eq(sessionBackgroundCommands.id, input.commandId),
488
+ eq(sessionBackgroundCommands.provider, "connected_machine"),
489
+ eq(sessionBackgroundCommands.controlWorkspaceId, input.controlWorkspaceId),
490
+ eq(sessionBackgroundCommands.enrollmentId, input.enrollmentId),
491
+ eq(sessionBackgroundCommands.connectionInstanceId, input.connectionInstanceId),
492
+ eq(sessionBackgroundCommands.opId, input.opId),
493
+ inArray(sessionBackgroundCommands.state, ["running", "stopping"])
494
+ )
495
+ ).returning();
496
+ return row ? mapCommand(row) : null;
497
+ }
498
+ );
499
+ }
500
+
501
+ export {
502
+ backgroundCommandActivityForSessions,
503
+ listSessionBackgroundCommands,
504
+ insertManagedSessionBackgroundCommandInTransaction,
505
+ insertConnectedMachineSessionBackgroundCommandInTransaction,
506
+ claimConnectedMachineSessionBackgroundCommands,
507
+ recordConnectedMachineBackgroundCommandProof,
508
+ deferConnectedMachineBackgroundCommandReconciliation,
509
+ settleClaimedConnectedMachineBackgroundCommand,
510
+ requestSessionBackgroundCommandCancellation,
511
+ requestSessionBackgroundCommandCancellationsInTransaction,
512
+ requestWorkspaceBackgroundCommandCancellationsInTransaction,
513
+ settleSessionBackgroundCommandForRetainedProcess,
514
+ settleConnectedMachineSessionBackgroundCommand
515
+ };
516
+ //# sourceMappingURL=chunk-ZZ5LJEFX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/session-background-commands.ts"],"sourcesContent":["import type {\n SessionBackgroundCommand,\n SessionBackgroundCommandActivity,\n} from \"@opengeni/contracts\";\nimport { and, desc, eq, inArray, sql } from \"drizzle-orm\";\n\nimport type { Database } from \"./database\";\nimport { withRlsContext } from \"./database\";\nimport * as schema from \"./schema\";\n\nexport type ConnectedMachineBackgroundCommandProof = {\n outcome: \"exited\" | \"lost\";\n exitCode: number | null;\n reason: string;\n observedAt: Date;\n};\n\nexport type ConnectedMachineBackgroundCommandClaim = {\n commandId: string;\n accountId: string;\n workspaceId: string;\n sessionId: string;\n claimId: string;\n state: \"running\" | \"stopping\";\n controlWorkspaceId: string;\n enrollmentId: string;\n connectionInstanceId: string;\n opId: string;\n reconcileAttempts: number;\n proof: ConnectedMachineBackgroundCommandProof | null;\n};\n\ntype ConnectedMachineBackgroundCommandClaimRow = {\n accountId: string;\n workspaceId: string;\n sessionId: string;\n commandId: string;\n claimId: string;\n commandState: string;\n controlWorkspaceId: string;\n enrollmentId: string;\n connectionInstanceId: string;\n opId: string;\n reconcileAttempts: number | string;\n reconcileProofOutcome: string | null;\n reconcileProofExitCode: number | string | null;\n reconcileProofReason: string | null;\n reconcileProofObservedAt: Date | string | null;\n};\n\nfunction commandPreview(value: string): string {\n const normalized = value.replace(/\\s+/g, \" \").trim();\n return Array.from(normalized).slice(0, 512).join(\"\");\n}\n\nfunction mapCommand(\n row: typeof schema.sessionBackgroundCommands.$inferSelect,\n): SessionBackgroundCommand {\n return {\n id: row.id,\n workspaceId: row.workspaceId,\n sessionId: row.sessionId,\n provider: row.provider,\n state: row.state,\n commandPreview: row.commandPreview,\n cancelRequestedAt: row.cancelRequestedAt?.toISOString() ?? null,\n exitCode: row.exitCode ?? null,\n settlementReason: row.settlementReason ?? null,\n startedAt: row.startedAt.toISOString(),\n settledAt: row.settledAt?.toISOString() ?? null,\n updatedAt: row.updatedAt.toISOString(),\n };\n}\n\nexport async function backgroundCommandActivityForSessions(\n db: Database,\n input: { accountId: string; workspaceId: string; sessionIds: string[] },\n): Promise<Map<string, SessionBackgroundCommandActivity>> {\n if (input.sessionIds.length === 0) return new Map();\n return await withRlsContext(\n db,\n { accountId: input.accountId, workspaceId: input.workspaceId },\n async (scopedDb) => {\n const rows = await scopedDb\n .select({\n sessionId: schema.sessionBackgroundCommands.sessionId,\n count: sql<number>`count(*)::int`,\n stoppingCount: sql<number>`count(*) filter (where ${schema.sessionBackgroundCommands.state} = 'stopping')::int`,\n })\n .from(schema.sessionBackgroundCommands)\n .where(\n and(\n eq(schema.sessionBackgroundCommands.workspaceId, input.workspaceId),\n inArray(schema.sessionBackgroundCommands.sessionId, input.sessionIds),\n inArray(schema.sessionBackgroundCommands.state, [\"running\", \"stopping\"]),\n ),\n )\n .groupBy(schema.sessionBackgroundCommands.sessionId);\n return new Map(\n rows.map((row) => [\n row.sessionId,\n {\n state: Number(row.stoppingCount) > 0 ? (\"stopping\" as const) : (\"running\" as const),\n count: Number(row.count),\n },\n ]),\n );\n },\n );\n}\n\nexport async function listSessionBackgroundCommands(\n db: Database,\n input: { accountId: string; workspaceId: string; sessionId: string },\n): Promise<SessionBackgroundCommand[]> {\n return await withRlsContext(\n db,\n { accountId: input.accountId, workspaceId: input.workspaceId },\n async (scopedDb) => {\n const rows = await scopedDb\n .select()\n .from(schema.sessionBackgroundCommands)\n .where(\n and(\n eq(schema.sessionBackgroundCommands.workspaceId, input.workspaceId),\n eq(schema.sessionBackgroundCommands.sessionId, input.sessionId),\n ),\n )\n .orderBy(\n desc(schema.sessionBackgroundCommands.startedAt),\n desc(schema.sessionBackgroundCommands.id),\n )\n .limit(1000);\n return rows.map(mapCommand);\n },\n );\n}\n\n/** @internal Caller must already hold the canonical session/control fence. */\nexport async function insertManagedSessionBackgroundCommandInTransaction(\n db: Database,\n input: {\n accountId: string;\n workspaceId: string;\n sessionId: string;\n commandId: string;\n retainedProcessId: string;\n command: string;\n },\n): Promise<SessionBackgroundCommand> {\n const [process] = await db\n .select({\n accountId: schema.sandboxRetainedProcesses.accountId,\n workspaceId: schema.sandboxRetainedProcesses.workspaceId,\n sessionId: schema.sandboxRetainedProcesses.sessionId,\n state: schema.sandboxRetainedProcesses.state,\n })\n .from(schema.sandboxRetainedProcesses)\n .where(eq(schema.sandboxRetainedProcesses.id, input.retainedProcessId))\n .for(\"update\")\n .limit(1);\n if (\n !process ||\n process.accountId !== input.accountId ||\n process.workspaceId !== input.workspaceId ||\n process.sessionId !== input.sessionId ||\n process.state !== \"active\"\n ) {\n throw new Error(\"Managed background command requires its exact active retained process\");\n }\n const [row] = await db\n .insert(schema.sessionBackgroundCommands)\n .values({\n id: input.commandId,\n accountId: input.accountId,\n workspaceId: input.workspaceId,\n sessionId: input.sessionId,\n provider: \"managed\",\n state: \"running\",\n retainedProcessId: input.retainedProcessId,\n commandPreview: commandPreview(input.command),\n })\n .onConflictDoUpdate({\n target: schema.sessionBackgroundCommands.retainedProcessId,\n targetWhere: sql`${schema.sessionBackgroundCommands.retainedProcessId} is not null`,\n set: { updatedAt: new Date() },\n })\n .returning();\n if (!row) throw new Error(\"Managed background command adoption returned no row\");\n if (\n row.accountId !== input.accountId ||\n row.workspaceId !== input.workspaceId ||\n row.sessionId !== input.sessionId ||\n row.provider !== \"managed\" ||\n row.retainedProcessId !== input.retainedProcessId\n ) {\n throw new Error(\"Managed background command adoption conflicted with another identity\");\n }\n return mapCommand(row);\n}\n\n/** @internal Caller must already hold the canonical exact-attempt fence. */\nexport async function insertConnectedMachineSessionBackgroundCommandInTransaction(\n db: Database,\n input: {\n accountId: string;\n workspaceId: string;\n sessionId: string;\n commandId: string;\n controlWorkspaceId: string;\n enrollmentId: string;\n connectionInstanceId: string;\n opId: string;\n command: string;\n },\n): Promise<SessionBackgroundCommand> {\n const [row] = await db\n .insert(schema.sessionBackgroundCommands)\n .values({\n id: input.commandId,\n accountId: input.accountId,\n workspaceId: input.workspaceId,\n sessionId: input.sessionId,\n provider: \"connected_machine\",\n state: \"running\",\n controlWorkspaceId: input.controlWorkspaceId,\n enrollmentId: input.enrollmentId,\n connectionInstanceId: input.connectionInstanceId,\n opId: input.opId,\n commandPreview: commandPreview(input.command),\n })\n .onConflictDoUpdate({\n target: [\n schema.sessionBackgroundCommands.controlWorkspaceId,\n schema.sessionBackgroundCommands.enrollmentId,\n schema.sessionBackgroundCommands.connectionInstanceId,\n schema.sessionBackgroundCommands.opId,\n ],\n targetWhere: sql`${schema.sessionBackgroundCommands.provider} = 'connected_machine'`,\n set: { updatedAt: new Date() },\n })\n .returning();\n if (!row) throw new Error(\"Connected Machine background command adoption returned no row\");\n if (\n row.accountId !== input.accountId ||\n row.workspaceId !== input.workspaceId ||\n row.sessionId !== input.sessionId ||\n row.provider !== \"connected_machine\" ||\n row.controlWorkspaceId !== input.controlWorkspaceId ||\n row.enrollmentId !== input.enrollmentId ||\n row.connectionInstanceId !== input.connectionInstanceId ||\n row.opId !== input.opId\n ) {\n throw new Error(\n \"Connected Machine background command adoption conflicted with another identity\",\n );\n }\n return mapCommand(row);\n}\n\n/** Claim exact Connected Machine locators globally for provider reconciliation.\n * The SECURITY DEFINER SQL function owns the bounded SKIP LOCKED inventory;\n * claim expiry is coordination recovery only and never implies command loss. */\nexport async function claimConnectedMachineSessionBackgroundCommands(\n db: Database,\n input: { claimId: string; limit: number; claimTtlMs: number },\n): Promise<ConnectedMachineBackgroundCommandClaim[]> {\n if (!Number.isSafeInteger(input.limit) || input.limit < 1 || input.limit > 100) {\n throw new Error(\"Connected command reconciliation limit must be between 1 and 100\");\n }\n if (\n !Number.isSafeInteger(input.claimTtlMs) ||\n input.claimTtlMs < 0 ||\n input.claimTtlMs > 3_600_000\n ) {\n throw new Error(\"Connected command reconciliation claim TTL is invalid\");\n }\n const rows = await db.execute<ConnectedMachineBackgroundCommandClaimRow>(sql`\n select account_id as \"accountId\",\n workspace_id as \"workspaceId\",\n session_id as \"sessionId\",\n command_id as \"commandId\",\n claim_id as \"claimId\",\n command_state as \"commandState\",\n control_workspace_id as \"controlWorkspaceId\",\n enrollment_id as \"enrollmentId\",\n connection_instance_id as \"connectionInstanceId\",\n op_id as \"opId\",\n reconcile_attempts as \"reconcileAttempts\",\n reconcile_proof_outcome as \"reconcileProofOutcome\",\n reconcile_proof_exit_code as \"reconcileProofExitCode\",\n reconcile_proof_reason as \"reconcileProofReason\",\n reconcile_proof_observed_at as \"reconcileProofObservedAt\"\n from opengeni_private.claim_connected_machine_background_commands(\n ${input.claimId}::uuid, ${input.limit}::integer, ${input.claimTtlMs}::bigint\n )\n `);\n return rows.map((row: ConnectedMachineBackgroundCommandClaimRow) => {\n if (row.commandState !== \"running\" && row.commandState !== \"stopping\") {\n throw new Error(`Connected command claim returned invalid state ${row.commandState}`);\n }\n const proof =\n row.reconcileProofOutcome === null\n ? null\n : row.reconcileProofOutcome === \"exited\" || row.reconcileProofOutcome === \"lost\"\n ? {\n outcome: row.reconcileProofOutcome,\n exitCode:\n row.reconcileProofExitCode === null ? null : Number(row.reconcileProofExitCode),\n reason: row.reconcileProofReason!,\n observedAt:\n row.reconcileProofObservedAt instanceof Date\n ? row.reconcileProofObservedAt\n : new Date(row.reconcileProofObservedAt!),\n }\n : (() => {\n throw new Error(\n `Connected command claim returned invalid proof ${row.reconcileProofOutcome}`,\n );\n })();\n return {\n commandId: row.commandId,\n accountId: row.accountId,\n workspaceId: row.workspaceId,\n sessionId: row.sessionId,\n claimId: row.claimId,\n state: row.commandState,\n controlWorkspaceId: row.controlWorkspaceId,\n enrollmentId: row.enrollmentId,\n connectionInstanceId: row.connectionInstanceId,\n opId: row.opId,\n reconcileAttempts: Number(row.reconcileAttempts),\n proof,\n };\n });\n}\n\nfunction connectedClaimIdentityWhere(claim: ConnectedMachineBackgroundCommandClaim) {\n return and(\n eq(schema.sessionBackgroundCommands.id, claim.commandId),\n eq(schema.sessionBackgroundCommands.accountId, claim.accountId),\n eq(schema.sessionBackgroundCommands.workspaceId, claim.workspaceId),\n eq(schema.sessionBackgroundCommands.sessionId, claim.sessionId),\n eq(schema.sessionBackgroundCommands.provider, \"connected_machine\"),\n eq(schema.sessionBackgroundCommands.controlWorkspaceId, claim.controlWorkspaceId),\n eq(schema.sessionBackgroundCommands.enrollmentId, claim.enrollmentId),\n eq(schema.sessionBackgroundCommands.connectionInstanceId, claim.connectionInstanceId),\n eq(schema.sessionBackgroundCommands.opId, claim.opId),\n eq(schema.sessionBackgroundCommands.reconcileClaimId, claim.claimId),\n inArray(schema.sessionBackgroundCommands.state, [\"running\", \"stopping\"]),\n );\n}\n\n/** Checkpoint one exact terminal provider observation before lifecycle settlement.\n * A retry may reuse an identical proof; a divergent proof is a hard identity fault. */\nexport async function recordConnectedMachineBackgroundCommandProof(\n db: Database,\n input: {\n claim: ConnectedMachineBackgroundCommandClaim;\n proof: ConnectedMachineBackgroundCommandProof;\n },\n): Promise<void> {\n const reason = input.proof.reason.trim().slice(0, 512);\n if (!reason) throw new Error(\"Connected command proof reason must not be empty\");\n if (input.proof.outcome === \"exited\" && input.proof.exitCode === null) {\n throw new Error(\"Connected command exit proof requires an exit code\");\n }\n if (input.proof.outcome === \"lost\" && input.proof.exitCode !== null) {\n throw new Error(\"Connected command loss proof cannot carry an exit code\");\n }\n await withRlsContext(\n db,\n { accountId: input.claim.accountId, workspaceId: input.claim.workspaceId },\n async (scopedDb) => {\n const [current] = await scopedDb\n .select()\n .from(schema.sessionBackgroundCommands)\n .where(connectedClaimIdentityWhere(input.claim))\n .for(\"update\")\n .limit(1);\n if (!current) throw new Error(\"Connected command proof was fenced by newer lifecycle state\");\n if (current.reconcileProofOutcome !== null) {\n const observedAt = current.reconcileProofObservedAt?.getTime() ?? null;\n if (\n current.reconcileProofOutcome !== input.proof.outcome ||\n current.reconcileProofExitCode !== input.proof.exitCode ||\n current.reconcileProofReason !== reason ||\n observedAt !== input.proof.observedAt.getTime()\n ) {\n throw new Error(\"Connected command reconciliation proof conflicts with durable proof\");\n }\n return;\n }\n const rows = await scopedDb\n .update(schema.sessionBackgroundCommands)\n .set({\n reconcileProofOutcome: input.proof.outcome,\n reconcileProofExitCode: input.proof.exitCode,\n reconcileProofReason: reason,\n reconcileProofObservedAt: input.proof.observedAt,\n lastReconcileOutcome: `proof_${input.proof.outcome}`,\n updatedAt: new Date(),\n })\n .where(connectedClaimIdentityWhere(input.claim))\n .returning({ id: schema.sessionBackgroundCommands.id });\n if (rows.length !== 1) {\n throw new Error(\"Connected command proof lost its exact claim during checkpoint\");\n }\n },\n );\n}\n\nexport async function deferConnectedMachineBackgroundCommandReconciliation(\n db: Database,\n input: {\n claim: ConnectedMachineBackgroundCommandClaim;\n outcome: string;\n retryAfterMs: number;\n },\n): Promise<boolean> {\n if (!Number.isSafeInteger(input.retryAfterMs) || input.retryAfterMs < 0) {\n throw new Error(\"Connected command reconciliation retry delay is invalid\");\n }\n const outcome = input.outcome.trim().slice(0, 64);\n if (!outcome) throw new Error(\"Connected command reconciliation outcome must not be empty\");\n return await withRlsContext(\n db,\n { accountId: input.claim.accountId, workspaceId: input.claim.workspaceId },\n async (scopedDb) => {\n const rows = await scopedDb\n .update(schema.sessionBackgroundCommands)\n .set({\n reconcileAfter: new Date(Date.now() + input.retryAfterMs),\n reconcileClaimId: null,\n reconcileClaimedAt: null,\n lastReconcileOutcome: outcome,\n updatedAt: new Date(),\n })\n .where(connectedClaimIdentityWhere(input.claim))\n .returning({ id: schema.sessionBackgroundCommands.id });\n return rows.length === 1;\n },\n );\n}\n\n/** Settle only from the proof already checkpointed under this exact claim. */\nexport async function settleClaimedConnectedMachineBackgroundCommand(\n db: Database,\n input: { claim: ConnectedMachineBackgroundCommandClaim },\n): Promise<boolean> {\n return await withRlsContext(\n db,\n { accountId: input.claim.accountId, workspaceId: input.claim.workspaceId },\n async (scopedDb) => {\n const rows = await scopedDb.execute<{ id: string }>(sql`\n update ${schema.sessionBackgroundCommands} command set\n state = command.reconcile_proof_outcome,\n exit_code = case\n when command.reconcile_proof_outcome = 'exited'\n then command.reconcile_proof_exit_code\n else null\n end,\n settlement_reason = command.reconcile_proof_reason,\n settled_at = command.reconcile_proof_observed_at,\n reconcile_claim_id = null,\n reconcile_claimed_at = null,\n last_reconcile_outcome = 'settled_' || command.reconcile_proof_outcome,\n updated_at = clock_timestamp()\n where command.id = ${input.claim.commandId}\n and command.account_id = ${input.claim.accountId}\n and command.workspace_id = ${input.claim.workspaceId}\n and command.session_id = ${input.claim.sessionId}\n and command.provider = 'connected_machine'\n and command.control_workspace_id = ${input.claim.controlWorkspaceId}\n and command.enrollment_id = ${input.claim.enrollmentId}\n and command.connection_instance_id = ${input.claim.connectionInstanceId}\n and command.op_id = ${input.claim.opId}\n and command.reconcile_claim_id = ${input.claim.claimId}\n and command.state in ('running', 'stopping')\n and command.reconcile_proof_outcome in ('exited', 'lost')\n and command.reconcile_proof_observed_at is not null\n returning command.id\n `);\n return rows.length === 1;\n },\n );\n}\n\nexport async function requestSessionBackgroundCommandCancellation(\n db: Database,\n input: {\n accountId: string;\n workspaceId: string;\n sessionId: string;\n commandId: string;\n subjectId: string;\n },\n): Promise<{ command: SessionBackgroundCommand | null; accepted: boolean }> {\n return await withRlsContext(\n db,\n { accountId: input.accountId, workspaceId: input.workspaceId },\n async (scopedDb) =>\n await scopedDb.transaction(async (tx) => {\n const [current] = await tx\n .select()\n .from(schema.sessionBackgroundCommands)\n .where(\n and(\n eq(schema.sessionBackgroundCommands.workspaceId, input.workspaceId),\n eq(schema.sessionBackgroundCommands.sessionId, input.sessionId),\n eq(schema.sessionBackgroundCommands.id, input.commandId),\n ),\n )\n .for(\"update\")\n .limit(1);\n if (!current) return { command: null, accepted: false };\n if (current.state !== \"running\") {\n return { command: mapCommand(current), accepted: false };\n }\n const [updated] = await tx\n .update(schema.sessionBackgroundCommands)\n .set({\n state: \"stopping\",\n cancelRequestedAt: new Date(),\n cancelRequestedBy: input.subjectId.slice(0, 1024),\n reconcileAfter: new Date(),\n reconcileClaimId: null,\n reconcileClaimedAt: null,\n updatedAt: new Date(),\n })\n .where(eq(schema.sessionBackgroundCommands.id, current.id))\n .returning();\n if (current.retainedProcessId) {\n await tx\n .update(schema.sandboxRetainedProcesses)\n .set({ reconcileAfter: new Date(), lastReconcileOutcome: \"cancel_requested\" })\n .where(\n and(\n eq(schema.sandboxRetainedProcesses.id, current.retainedProcessId),\n eq(schema.sandboxRetainedProcesses.state, \"active\"),\n sql`${schema.sandboxRetainedProcesses.reconcileClaimId} is null`,\n ),\n );\n }\n return { command: mapCommand(updated!), accepted: true };\n }),\n );\n}\n\n/**\n * Transfer every active command in one or more session subtrees to the\n * provider-neutral stopping state inside the caller's existing control\n * transaction. The workspace-control mutation already excludes concurrent\n * session-tree changes, so the recursive walk and state transition are one\n * atomic Pause/Cancel effect. Steer deliberately never calls this seam.\n */\nexport async function requestSessionBackgroundCommandCancellationsInTransaction(\n db: Database,\n input: {\n workspaceId: string;\n rootSessionIds: string[];\n subjectId: string;\n },\n): Promise<number> {\n const rootSessionIds = [...new Set(input.rootSessionIds)];\n if (rootSessionIds.length === 0) return 0;\n const rows = await db.execute<{ commandCount: number | string }>(sql`\n with recursive roots(id) as (\n values ${sql.join(\n rootSessionIds.map((sessionId) => sql`(${sessionId}::uuid)`),\n sql`, `,\n )}\n ), subtree(id, path, cycle) as (\n select session.id, array[session.id]::uuid[], false\n from roots root\n join ${schema.sessions} session\n on session.workspace_id = ${input.workspaceId}\n and session.id = root.id\n union all\n select child.id, parent.path || child.id, child.id = any(parent.path)\n from subtree parent\n join ${schema.sessions} child\n on child.workspace_id = ${input.workspaceId}\n and child.parent_session_id = parent.id\n where not parent.cycle\n ), stopped as (\n update ${schema.sessionBackgroundCommands} command set\n state = 'stopping',\n cancel_requested_at = clock_timestamp(),\n cancel_requested_by = left(${input.subjectId}, 1024),\n reconcile_after = clock_timestamp(),\n reconcile_claim_id = null,\n reconcile_claimed_at = null,\n updated_at = clock_timestamp()\n where command.workspace_id = ${input.workspaceId}\n and command.session_id in (select id from subtree where not cycle)\n and command.state = 'running'\n returning command.retained_process_id\n ), nudged as (\n update ${schema.sandboxRetainedProcesses} process set\n reconcile_after = clock_timestamp(),\n reconcile_claim_id = null,\n reconcile_claimed_at = null,\n last_reconcile_outcome = 'cancel_requested'\n where process.id in (\n select stopped.retained_process_id\n from stopped\n where stopped.retained_process_id is not null\n )\n and process.state = 'active'\n returning process.id\n )\n select count(*)::integer as \"commandCount\" from stopped\n `);\n return Number(rows[0]?.commandCount ?? 0);\n}\n\n/** Workspace Pause owns every active command in that workspace. */\nexport async function requestWorkspaceBackgroundCommandCancellationsInTransaction(\n db: Database,\n input: { workspaceId: string; subjectId: string },\n): Promise<number> {\n const rows = await db.execute<{ commandCount: number | string }>(sql`\n with stopped as (\n update ${schema.sessionBackgroundCommands} command set\n state = 'stopping',\n cancel_requested_at = clock_timestamp(),\n cancel_requested_by = left(${input.subjectId}, 1024),\n reconcile_after = clock_timestamp(),\n reconcile_claim_id = null,\n reconcile_claimed_at = null,\n updated_at = clock_timestamp()\n where command.workspace_id = ${input.workspaceId}\n and command.state = 'running'\n returning command.retained_process_id\n ), nudged as (\n update ${schema.sandboxRetainedProcesses} process set\n reconcile_after = clock_timestamp(),\n reconcile_claim_id = null,\n reconcile_claimed_at = null,\n last_reconcile_outcome = 'cancel_requested'\n where process.id in (\n select stopped.retained_process_id\n from stopped\n where stopped.retained_process_id is not null\n )\n and process.state = 'active'\n returning process.id\n )\n select count(*)::integer as \"commandCount\" from stopped\n `);\n return Number(rows[0]?.commandCount ?? 0);\n}\n\nexport async function settleSessionBackgroundCommandForRetainedProcess(\n db: Database,\n input: {\n accountId: string;\n workspaceId: string;\n sessionId: string;\n retainedProcessId: string;\n outcome: \"exited\" | \"lost\";\n exitCode: number | null;\n reason: string;\n },\n): Promise<SessionBackgroundCommand | null> {\n return await withRlsContext(\n db,\n { accountId: input.accountId, workspaceId: input.workspaceId },\n async (scopedDb) => {\n const [row] = await scopedDb\n .update(schema.sessionBackgroundCommands)\n .set({\n state: input.outcome,\n exitCode: input.outcome === \"exited\" ? input.exitCode : null,\n settlementReason: input.reason.slice(0, 512),\n settledAt: new Date(),\n reconcileClaimId: null,\n reconcileClaimedAt: null,\n lastReconcileOutcome: `settled_${input.outcome}`,\n updatedAt: new Date(),\n })\n .where(\n and(\n eq(schema.sessionBackgroundCommands.workspaceId, input.workspaceId),\n eq(schema.sessionBackgroundCommands.sessionId, input.sessionId),\n eq(schema.sessionBackgroundCommands.retainedProcessId, input.retainedProcessId),\n inArray(schema.sessionBackgroundCommands.state, [\"running\", \"stopping\"]),\n ),\n )\n .returning();\n return row ? mapCommand(row) : null;\n },\n );\n}\n\nexport async function settleConnectedMachineSessionBackgroundCommand(\n db: Database,\n input: {\n accountId: string;\n workspaceId: string;\n sessionId: string;\n commandId: string;\n controlWorkspaceId: string;\n enrollmentId: string;\n connectionInstanceId: string;\n opId: string;\n outcome: \"exited\" | \"lost\";\n exitCode: number | null;\n reason: string;\n },\n): Promise<SessionBackgroundCommand | null> {\n return await withRlsContext(\n db,\n { accountId: input.accountId, workspaceId: input.workspaceId },\n async (scopedDb) => {\n const settledAt = new Date();\n const reason = input.reason.trim().slice(0, 512);\n if (!reason) throw new Error(\"Connected command settlement reason must not be empty\");\n if (input.outcome === \"exited\" && input.exitCode === null) {\n throw new Error(\"Connected command exit settlement requires an exit code\");\n }\n if (input.outcome === \"lost\" && input.exitCode !== null) {\n throw new Error(\"Connected command loss settlement cannot carry an exit code\");\n }\n const [row] = await scopedDb\n .update(schema.sessionBackgroundCommands)\n .set({\n state: input.outcome,\n exitCode: input.outcome === \"exited\" ? input.exitCode : null,\n settlementReason: reason,\n settledAt,\n reconcileClaimId: null,\n reconcileClaimedAt: null,\n reconcileProofOutcome: input.outcome,\n reconcileProofExitCode: input.outcome === \"exited\" ? input.exitCode : null,\n reconcileProofReason: reason,\n reconcileProofObservedAt: settledAt,\n lastReconcileOutcome: `settled_${input.outcome}`,\n updatedAt: new Date(),\n })\n .where(\n and(\n eq(schema.sessionBackgroundCommands.workspaceId, input.workspaceId),\n eq(schema.sessionBackgroundCommands.sessionId, input.sessionId),\n eq(schema.sessionBackgroundCommands.id, input.commandId),\n eq(schema.sessionBackgroundCommands.provider, \"connected_machine\"),\n eq(schema.sessionBackgroundCommands.controlWorkspaceId, input.controlWorkspaceId),\n eq(schema.sessionBackgroundCommands.enrollmentId, input.enrollmentId),\n eq(schema.sessionBackgroundCommands.connectionInstanceId, input.connectionInstanceId),\n eq(schema.sessionBackgroundCommands.opId, input.opId),\n inArray(schema.sessionBackgroundCommands.state, [\"running\", \"stopping\"]),\n ),\n )\n .returning();\n return row ? mapCommand(row) : null;\n },\n );\n}\n"],"mappings":"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","names":[]}
@@ -16,10 +16,6 @@ export declare class CodemodeToolApprovalRequiredError extends Error {
16
16
  readonly code = "codemode_tool_approval_required";
17
17
  constructor();
18
18
  }
19
- export declare class CodemodeCallBudgetExceededError extends Error {
20
- readonly code = "codemode_call_budget_exhausted";
21
- constructor();
22
- }
23
19
  export declare class CodemodePayloadTooLargeError extends Error {
24
20
  readonly code = "codemode_payload_too_large";
25
21
  constructor(kind: "arguments" | "result");
@@ -32,12 +28,11 @@ export type SubmitCodemodeOperationInput = {
32
28
  attemptId: string;
33
29
  executionGeneration: number;
34
30
  call: AttemptToolCallValue;
35
- callLimit: number;
36
31
  };
37
32
  /**
38
33
  * Bind one caller-provided operation id to one exact catalog call. Duplicate
39
34
  * submission of identical bytes is free and returns the same row; repurposing
40
- * the id fails. Admission, budget reservation and insert share one turn lock.
35
+ * the id fails. Admission and insert share one turn lock.
41
36
  */
42
37
  export declare function submitCodemodeOperation(db: Database, input: SubmitCodemodeOperationInput): Promise<{
43
38
  operation: CodemodeOperationValue;