@opengeni/db 0.28.9 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/dist/attached-browser-devices.d.ts +42 -0
  2. package/dist/attempt-tool-catalogs.d.ts +16 -0
  3. package/dist/browser-auth.d.ts +299 -0
  4. package/dist/browser-downloads.d.ts +51 -0
  5. package/dist/browser-identities.d.ts +137 -0
  6. package/dist/browser-sessions.d.ts +354 -0
  7. package/dist/browser-state-artifacts.d.ts +91 -0
  8. package/dist/canonical-human-identities.d.ts +48 -0
  9. package/dist/canonical-human-identities.js +28 -0
  10. package/dist/canonical-human-identities.js.map +1 -0
  11. package/dist/capability-components.d.ts +37 -0
  12. package/dist/capability-integrations.d.ts +194 -0
  13. package/dist/chunk-5KTIEDX7.js +13200 -0
  14. package/dist/chunk-5KTIEDX7.js.map +1 -0
  15. package/dist/chunk-CQZ4QSP5.js +995 -0
  16. package/dist/chunk-CQZ4QSP5.js.map +1 -0
  17. package/dist/chunk-F32YT7MP.js +117 -0
  18. package/dist/chunk-F32YT7MP.js.map +1 -0
  19. package/dist/chunk-JC5QPLUM.js +666 -0
  20. package/dist/chunk-JC5QPLUM.js.map +1 -0
  21. package/dist/chunk-P3RE4D2B.js +3535 -0
  22. package/dist/chunk-P3RE4D2B.js.map +1 -0
  23. package/dist/chunk-TAUTWOS5.js +259 -0
  24. package/dist/chunk-TAUTWOS5.js.map +1 -0
  25. package/dist/chunk-VKLB2ZGI.js +2389 -0
  26. package/dist/chunk-VKLB2ZGI.js.map +1 -0
  27. package/dist/codemode-operations.d.ts +117 -0
  28. package/dist/codex-token-resolver.d.ts +2 -2
  29. package/dist/company-profile-schema.d.ts +798 -0
  30. package/dist/company-profile.d.ts +268 -0
  31. package/dist/computer-sessions.d.ts +109 -0
  32. package/dist/connection-token-resolver.d.ts +9 -4
  33. package/dist/database.d.ts +57 -3
  34. package/dist/editable-artifact-durable-export.d.ts +153 -0
  35. package/dist/editable-artifact-durable-export.js +788 -0
  36. package/dist/editable-artifact-durable-export.js.map +1 -0
  37. package/dist/editable-artifact-materialization.d.ts +123 -0
  38. package/dist/editable-artifacts-schema.d.ts +4152 -0
  39. package/dist/editable-artifacts.d.ts +610 -0
  40. package/dist/editable-artifacts.js +26 -0
  41. package/dist/editable-artifacts.js.map +1 -0
  42. package/dist/generated-images.d.ts +139 -0
  43. package/dist/index.d.ts +1122 -126
  44. package/dist/index.js +42329 -18407
  45. package/dist/index.js.map +1 -1
  46. package/dist/insights.d.ts +73 -10
  47. package/dist/integration-bindings.d.ts +70 -0
  48. package/dist/integration-facets.d.ts +99 -0
  49. package/dist/interaction-revisions.d.ts +14 -0
  50. package/dist/interaction-schema.d.ts +6036 -0
  51. package/dist/knowledge-source-sync-schema.d.ts +1679 -0
  52. package/dist/knowledge-source-sync.d.ts +274 -0
  53. package/dist/memory-governance.d.ts +2 -2
  54. package/dist/memory-slack-delivery.d.ts +101 -0
  55. package/dist/new-session-drafts.d.ts +2 -2
  56. package/dist/pack-components.d.ts +76 -0
  57. package/dist/pack-installations.d.ts +86 -0
  58. package/dist/persistence-errors.d.ts +3 -3
  59. package/dist/plugin-packages.d.ts +126 -0
  60. package/dist/preference-registry.d.ts +1 -1
  61. package/dist/provision-roles.d.ts +9 -1
  62. package/dist/provision-roles.js +1 -1
  63. package/dist/runtime-posture.d.ts +19 -6
  64. package/dist/schema.d.ts +22654 -9359
  65. package/dist/schema.js +209 -3
  66. package/dist/scoped-knowledge.d.ts +97 -1
  67. package/dist/session-control.d.ts +33 -7
  68. package/dist/session-queue-commands.d.ts +19 -11
  69. package/dist/session-realtime-context.d.ts +2 -2
  70. package/dist/session-realtime-ledger.d.ts +4 -4
  71. package/dist/session-realtime-mirror.d.ts +2 -2
  72. package/dist/session-realtime-state.d.ts +1 -1
  73. package/dist/session-realtime-terminal.d.ts +1 -1
  74. package/dist/session-realtime.d.ts +7 -7
  75. package/dist/session-tenancy.d.ts +44 -0
  76. package/dist/session-tenancy.js +16 -0
  77. package/dist/session-tenancy.js.map +1 -0
  78. package/dist/session-tool-call-settlement.d.ts +1 -1
  79. package/dist/slack-task-policy-schema.d.ts +847 -0
  80. package/dist/slack-task-policy.d.ts +65 -0
  81. package/dist/slack-user-link-access.d.ts +54 -0
  82. package/dist/task-notes-schema.d.ts +924 -0
  83. package/dist/task-notes.d.ts +85 -0
  84. package/dist/transcription-recordings.d.ts +2 -2
  85. package/dist/turn-initiator.d.ts +2 -2
  86. package/dist/video-generation.d.ts +225 -0
  87. package/dist/video-generation.js +68 -0
  88. package/dist/video-generation.js.map +1 -0
  89. package/dist/workspace-artifacts.d.ts +1 -1
  90. package/dist/workspace-instruction-policies.d.ts +1 -1
  91. package/dist/workspace-learning-policy-schema.d.ts +932 -0
  92. package/dist/workspace-learning-policy.d.ts +161 -0
  93. package/dist/xai-subscription.d.ts +326 -0
  94. package/drizzle/0183_model_call_provider_cost_estimates.sql +39 -0
  95. package/drizzle/0184_sandbox_drain_teardown_fence.sql +682 -0
  96. package/drizzle/0185_temporal_schedule_cleanup_outbox.sql +168 -0
  97. package/drizzle/0186_sandbox_capture_provider_contract.sql +400 -0
  98. package/drizzle/0187_generated_image_artifacts.sql +173 -0
  99. package/drizzle/0188_image_generation_retention_failure.sql +25 -0
  100. package/drizzle/0189_retained_session_image_formats.sql +13 -0
  101. package/drizzle/0190_timeline_annotations.sql +31 -0
  102. package/drizzle/0191_editable_artifact_engine.sql +3853 -0
  103. package/drizzle/0192_editable_artifact_live_tickets.sql +338 -0
  104. package/drizzle/0193_editable_artifact_authorization.sql +190 -0
  105. package/drizzle/0194_editable_artifact_durable_exports.sql +160 -0
  106. package/drizzle/0195_editable_artifact_import_authorization.sql +203 -0
  107. package/drizzle/0196_rig_provider_images.sql +152 -0
  108. package/drizzle/0197_knowledge_source_sync_schedules.sql +523 -0
  109. package/drizzle/0198_memory_slack_publication_delivery.sql +393 -0
  110. package/drizzle/0199_workspace_learning_policy.sql +980 -0
  111. package/drizzle/0201_company_profile_authority.sql +849 -0
  112. package/drizzle/0202_document_index_checkpoints.sql +85 -0
  113. package/drizzle/0203_durable_video_generation.sql +353 -0
  114. package/drizzle/0204_video_generation_funding.sql +44 -0
  115. package/drizzle/0205_attempt_tool_catalogs.sql +230 -0
  116. package/drizzle/0206_browser_sessions.sql +646 -0
  117. package/drizzle/0207_browser_identities.sql +379 -0
  118. package/drizzle/0208_attached_browser_devices.sql +165 -0
  119. package/drizzle/0209_computer_sessions.sql +575 -0
  120. package/drizzle/0210_browser_auth_network_interventions.sql +441 -0
  121. package/drizzle/0211_editable_artifact_session_links.sql +58 -0
  122. package/drizzle/0212_browser_state_transfer_hardening.sql +560 -0
  123. package/drizzle/0212_slack_installation_bindings.sql +348 -0
  124. package/drizzle/0213_browser_interaction_authority.sql +67 -0
  125. package/drizzle/0213_slack_user_link_access_requests.sql +177 -0
  126. package/drizzle/0214_browser_download_saves.sql +34 -0
  127. package/drizzle/0214_session_activity_commit_gate.sql +262 -0
  128. package/drizzle/0215_browser_controller_host.sql +385 -0
  129. package/drizzle/0215_capabilities_platform.sql +980 -0
  130. package/drizzle/0216_browser_auth_health_evidence.sql +137 -0
  131. package/drizzle/0216_pack_component_ownership.sql +235 -0
  132. package/drizzle/0217_capability_definition_delete_authority.sql +32 -0
  133. package/drizzle/0217_external_browser_auth_operations.sql +22 -0
  134. package/drizzle/0218_organization_tenancy_foundation.sql +299 -0
  135. package/drizzle/0219_organization_tenancy_managed_human_provisioning.sql +317 -0
  136. package/drizzle/0219_site_auth_maintenance_sessions.sql +234 -0
  137. package/drizzle/0220_memory_slack_append_only_cascade.sql +38 -0
  138. package/drizzle/0220_session_channels.sql +54 -0
  139. package/drizzle/0221_sessions_channel_index.sql +5 -0
  140. package/drizzle/0222_session_visibility_authority_epochs.sql +158 -0
  141. package/drizzle/0222_sessions_channel_fk.sql +89 -0
  142. package/drizzle/0223_pending_tool_event_output.sql +55 -0
  143. package/drizzle/0223_sessions_channel_fk_validate.sql +118 -0
  144. package/drizzle/0224_slack_post_outcome_reconciliation.sql +123 -0
  145. package/drizzle/0225_session_visibility_fork_activation.sql +1363 -0
  146. package/drizzle/0226_personal_codex_authority_foundation.sql +365 -0
  147. package/drizzle/0227_slack_native_actions.sql +145 -0
  148. package/drizzle/0228_interaction_controller_data_plane.sql +14 -0
  149. package/drizzle/0228_slack_task_policy.sql +400 -0
  150. package/drizzle/0229_slack_inbox_file_fact.sql +10 -0
  151. package/drizzle/0230_user_scoped_variable_sets_rigs.sql +84 -0
  152. package/drizzle/0231_integration_definition_identity_cutover.sql +271 -0
  153. package/drizzle/0232_integration_facet_authority_cutover.sql +610 -0
  154. package/drizzle/0233_skill_and_integration_authority_cutover.sql +1162 -0
  155. package/drizzle/0234_xai_subscription_authority.sql +1139 -0
  156. package/drizzle/0235_canonical_human_login_bindings.sql +920 -0
  157. package/drizzle/0236_browser_identity_lifecycle.sql +39 -0
  158. package/drizzle/0236_session_visibility_slack_policy.sql +72 -0
  159. package/drizzle/0237_interaction_transition_reaper.sql +263 -0
  160. package/drizzle/0238_goal_persistence_policy.sql +471 -0
  161. package/drizzle/0238_supergrok_realtime_model.sql +29 -0
  162. package/drizzle/0239_supergrok_video_funding.sql +50 -0
  163. package/drizzle/0239_task_tree_notes.sql +990 -0
  164. package/package.json +26 -5
  165. package/src/attached-browser-devices.ts +371 -0
  166. package/src/attempt-tool-catalogs.ts +131 -0
  167. package/src/browser-auth.ts +4373 -0
  168. package/src/browser-downloads.ts +517 -0
  169. package/src/browser-identities.ts +1385 -0
  170. package/src/browser-sessions.ts +2294 -0
  171. package/src/browser-state-artifacts.ts +449 -0
  172. package/src/canonical-human-identities.ts +317 -0
  173. package/src/capability-components.ts +166 -0
  174. package/src/capability-integrations.ts +1571 -0
  175. package/src/codemode-operations.ts +674 -0
  176. package/src/company-profile-schema.ts +143 -0
  177. package/src/company-profile.ts +968 -0
  178. package/src/computer-sessions.ts +1130 -0
  179. package/src/connection-token-resolver.ts +270 -25
  180. package/src/database.ts +468 -24
  181. package/src/editable-artifact-durable-export.ts +1201 -0
  182. package/src/editable-artifact-materialization.ts +893 -0
  183. package/src/editable-artifacts-schema.ts +879 -0
  184. package/src/editable-artifacts.ts +5404 -0
  185. package/src/generated-images.ts +740 -0
  186. package/src/index.ts +9963 -1465
  187. package/src/insights.ts +251 -23
  188. package/src/integration-bindings.ts +455 -0
  189. package/src/integration-facets.ts +862 -0
  190. package/src/interaction-revisions.ts +70 -0
  191. package/src/interaction-schema.ts +1606 -0
  192. package/src/knowledge-source-sync-schema.ts +192 -0
  193. package/src/knowledge-source-sync.ts +1922 -0
  194. package/src/memory-slack-delivery.ts +801 -0
  195. package/src/pack-components.ts +954 -0
  196. package/src/pack-installations.ts +886 -0
  197. package/src/persistence-errors.ts +4 -7
  198. package/src/plugin-packages.ts +1186 -0
  199. package/src/provision-roles.ts +534 -1
  200. package/src/runtime-posture-cli.ts +9 -0
  201. package/src/runtime-posture.ts +721 -5
  202. package/src/schema.ts +6270 -3159
  203. package/src/scoped-knowledge-schema.ts +1 -1
  204. package/src/scoped-knowledge.ts +655 -3
  205. package/src/session-control.ts +130 -42
  206. package/src/session-queue-commands.ts +265 -15
  207. package/src/session-realtime-context.ts +2 -2
  208. package/src/session-realtime-ledger.ts +3 -3
  209. package/src/session-realtime.ts +7 -7
  210. package/src/session-tenancy.ts +188 -0
  211. package/src/session-tool-call-settlement.ts +18 -3
  212. package/src/slack-task-policy-schema.ts +130 -0
  213. package/src/slack-task-policy.ts +341 -0
  214. package/src/slack-user-link-access.ts +702 -0
  215. package/src/task-notes-schema.ts +135 -0
  216. package/src/task-notes.ts +178 -0
  217. package/src/video-generation.ts +1530 -0
  218. package/src/workspace-artifacts.ts +1 -1
  219. package/src/workspace-learning-policy-schema.ts +139 -0
  220. package/src/workspace-learning-policy.ts +595 -0
  221. package/src/xai-subscription.ts +1887 -0
  222. package/dist/chunk-P6CUHXQZ.js +0 -7248
  223. package/dist/chunk-P6CUHXQZ.js.map +0 -1
  224. package/dist/chunk-VHBFHMPC.js +0 -1219
  225. package/dist/chunk-VHBFHMPC.js.map +0 -1
@@ -0,0 +1,135 @@
1
+ import {
2
+ customType,
3
+ index,
4
+ integer,
5
+ pgTable,
6
+ text,
7
+ timestamp,
8
+ uniqueIndex,
9
+ uuid,
10
+ } from "drizzle-orm/pg-core";
11
+ import { sql } from "drizzle-orm";
12
+
13
+ const xid8 = customType<{ data: string; driverData: string }>({
14
+ dataType: () => "xid8",
15
+ });
16
+
17
+ // Cross-row validation, lifecycle-only mutation, exact-attempt authority,
18
+ // restrictive session-visibility RLS, and grants are owned by migration 0239.
19
+ export const taskNotes = pgTable(
20
+ "task_notes",
21
+ {
22
+ id: uuid("id").primaryKey().defaultRandom(),
23
+ accountId: uuid("account_id").notNull(),
24
+ workspaceId: uuid("workspace_id").notNull(),
25
+ rootSessionId: uuid("root_session_id").notNull(),
26
+ kind: text("kind").notNull(),
27
+ text: text("text").notNull(),
28
+ textHash: text("text_hash").notNull(),
29
+ status: text("status").notNull().default("active"),
30
+ version: integer("version").notNull().default(1),
31
+ expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
32
+ createOperationId: uuid("create_operation_id").notNull(),
33
+ createInputHash: text("create_input_hash").notNull(),
34
+ createdByActorKind: text("created_by_actor_kind").notNull(),
35
+ createdByActorSubjectId: text("created_by_actor_subject_id").notNull(),
36
+ createdByInitiatingHumanSubjectId: text("created_by_initiating_human_subject_id"),
37
+ createdBySessionId: uuid("created_by_session_id").notNull(),
38
+ createdByTurnId: uuid("created_by_turn_id").notNull(),
39
+ createdByAttemptId: uuid("created_by_attempt_id").notNull(),
40
+ createdByExecutionGeneration: integer("created_by_execution_generation").notNull(),
41
+ archiveOperationId: uuid("archive_operation_id"),
42
+ archiveInputHash: text("archive_input_hash"),
43
+ archivedByActorKind: text("archived_by_actor_kind"),
44
+ archivedByActorSubjectId: text("archived_by_actor_subject_id"),
45
+ archivedByInitiatingHumanSubjectId: text("archived_by_initiating_human_subject_id"),
46
+ archivedBySessionId: uuid("archived_by_session_id"),
47
+ archivedByTurnId: uuid("archived_by_turn_id"),
48
+ archivedByAttemptId: uuid("archived_by_attempt_id"),
49
+ archivedByExecutionGeneration: integer("archived_by_execution_generation"),
50
+ archivedAt: timestamp("archived_at", { withTimezone: true }),
51
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
52
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
53
+ },
54
+ (table) => ({
55
+ workspaceIdentity: uniqueIndex("task_notes_workspace_id_uq").on(table.workspaceId, table.id),
56
+ workspaceRootIdentity: uniqueIndex("task_notes_workspace_root_id_uq").on(
57
+ table.workspaceId,
58
+ table.rootSessionId,
59
+ table.id,
60
+ ),
61
+ createOperation: uniqueIndex("task_notes_workspace_create_operation_uq").on(
62
+ table.workspaceId,
63
+ table.createOperationId,
64
+ ),
65
+ archiveOperation: uniqueIndex("task_notes_workspace_archive_operation_uq")
66
+ .on(table.workspaceId, table.archiveOperationId)
67
+ .where(sql`${table.archiveOperationId} is not null`),
68
+ rootActive: index("task_notes_root_active_idx").on(
69
+ table.workspaceId,
70
+ table.rootSessionId,
71
+ table.status,
72
+ table.expiresAt,
73
+ table.updatedAt,
74
+ table.id,
75
+ ),
76
+ }),
77
+ );
78
+
79
+ export const taskNoteEvents = pgTable(
80
+ "task_note_events",
81
+ {
82
+ id: uuid("id").primaryKey().defaultRandom(),
83
+ accountId: uuid("account_id").notNull(),
84
+ workspaceId: uuid("workspace_id").notNull(),
85
+ rootSessionId: uuid("root_session_id").notNull(),
86
+ noteId: uuid("note_id").notNull(),
87
+ eventType: text("event_type").notNull(),
88
+ noteVersion: integer("note_version").notNull(),
89
+ operationId: uuid("operation_id").notNull(),
90
+ inputHash: text("input_hash").notNull(),
91
+ textHash: text("text_hash").notNull(),
92
+ reason: text("reason"),
93
+ actorKind: text("actor_kind").notNull(),
94
+ actorSubjectId: text("actor_subject_id").notNull(),
95
+ initiatingHumanSubjectId: text("initiating_human_subject_id"),
96
+ actorSessionId: uuid("actor_session_id").notNull(),
97
+ actorTurnId: uuid("actor_turn_id").notNull(),
98
+ actorAttemptId: uuid("actor_attempt_id").notNull(),
99
+ actorExecutionGeneration: integer("actor_execution_generation").notNull(),
100
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
101
+ },
102
+ (table) => ({
103
+ operation: uniqueIndex("task_note_events_workspace_operation_uq").on(
104
+ table.workspaceId,
105
+ table.operationId,
106
+ ),
107
+ noteVersion: uniqueIndex("task_note_events_note_version_uq").on(
108
+ table.workspaceId,
109
+ table.noteId,
110
+ table.noteVersion,
111
+ ),
112
+ rootTimeline: index("task_note_events_root_timeline_idx").on(
113
+ table.workspaceId,
114
+ table.rootSessionId,
115
+ table.createdAt,
116
+ table.id,
117
+ ),
118
+ }),
119
+ );
120
+
121
+ export const taskNoteWriteCapabilities = pgTable(
122
+ "task_note_write_capabilities",
123
+ {
124
+ backendPid: integer("backend_pid").notNull(),
125
+ transactionId: xid8("transaction_id").notNull(),
126
+ capabilityId: uuid("capability_id").notNull(),
127
+ },
128
+ (table) => ({
129
+ identity: uniqueIndex("task_note_write_capabilities_identity_uq").on(
130
+ table.backendPid,
131
+ table.transactionId,
132
+ table.capabilityId,
133
+ ),
134
+ }),
135
+ );
@@ -0,0 +1,178 @@
1
+ import {
2
+ TASK_NOTE_LIST_DEFAULT_LIMIT,
3
+ TASK_NOTE_LIST_MAX_LIMIT,
4
+ TaskNote,
5
+ TaskNoteKind,
6
+ TaskNoteListResponse,
7
+ TaskNoteMutationResult,
8
+ TaskNoteReason,
9
+ TaskNoteText,
10
+ type TaskNoteKind as TaskNoteKindType,
11
+ } from "@opengeni/contracts";
12
+ import { sql } from "drizzle-orm";
13
+ import type { Database } from "./database";
14
+ import { rawRows, withRlsContext } from "./database";
15
+
16
+ export type TaskNoteAttemptClaims = {
17
+ accountId: string;
18
+ workspaceId: string;
19
+ sessionId: string;
20
+ turnId: string;
21
+ attemptId: string;
22
+ executionGeneration: number;
23
+ };
24
+
25
+ export type CreateTaskNoteInput = TaskNoteAttemptClaims & {
26
+ operationId: string;
27
+ kind: TaskNoteKindType;
28
+ text: string;
29
+ expiresInDays: number;
30
+ };
31
+
32
+ export type ArchiveTaskNoteInput = TaskNoteAttemptClaims & {
33
+ operationId: string;
34
+ noteId: string;
35
+ expectedVersion: number;
36
+ reason: string;
37
+ };
38
+
39
+ export type ListTaskNotesInput = TaskNoteAttemptClaims & {
40
+ includeArchived?: boolean;
41
+ limit?: number;
42
+ };
43
+
44
+ type TaskNoteRow = {
45
+ note_id: string;
46
+ root_session_id: string;
47
+ kind: string;
48
+ note_text: string;
49
+ status: string;
50
+ version: number;
51
+ expires_at: Date | string;
52
+ created_at: Date | string;
53
+ updated_at: Date | string;
54
+ archived_at: Date | string | null;
55
+ actor_kind: string;
56
+ source_session_id: string;
57
+ source_turn_id: string;
58
+ replayed?: boolean;
59
+ };
60
+
61
+ function iso(value: Date | string): string {
62
+ return (value instanceof Date ? value : new Date(value)).toISOString();
63
+ }
64
+
65
+ function noteFromRow(row: TaskNoteRow) {
66
+ return TaskNote.parse({
67
+ id: row.note_id,
68
+ rootSessionId: row.root_session_id,
69
+ kind: row.kind,
70
+ text: row.note_text,
71
+ status: row.status,
72
+ version: row.version,
73
+ expiresAt: iso(row.expires_at),
74
+ createdAt: iso(row.created_at),
75
+ updatedAt: iso(row.updated_at),
76
+ archivedAt: row.archived_at === null ? null : iso(row.archived_at),
77
+ provenance: {
78
+ actorKind: row.actor_kind,
79
+ sourceSessionId: row.source_session_id,
80
+ sourceTurnId: row.source_turn_id,
81
+ },
82
+ });
83
+ }
84
+
85
+ function assertAttemptClaims(claims: TaskNoteAttemptClaims): void {
86
+ if (!Number.isSafeInteger(claims.executionGeneration) || claims.executionGeneration < 1) {
87
+ throw new Error("Task notes require a positive exact execution generation");
88
+ }
89
+ }
90
+
91
+ export async function createTaskNote(db: Database, input: CreateTaskNoteInput) {
92
+ assertAttemptClaims(input);
93
+ TaskNoteKind.parse(input.kind);
94
+ TaskNoteText.parse(input.text);
95
+ if (
96
+ !Number.isSafeInteger(input.expiresInDays) ||
97
+ input.expiresInDays < 1 ||
98
+ input.expiresInDays > 30
99
+ ) {
100
+ throw new Error("Task note expiry must be 1-30 whole days");
101
+ }
102
+ const rows = await withRlsContext(
103
+ db,
104
+ { accountId: input.accountId, workspaceId: input.workspaceId },
105
+ async (tx) =>
106
+ await rawRows<TaskNoteRow>(
107
+ tx,
108
+ sql`SELECT * FROM create_task_note_for_attempt(
109
+ ${input.accountId}::uuid,
110
+ ${input.workspaceId}::uuid,
111
+ ${input.sessionId}::uuid,
112
+ ${input.turnId}::uuid,
113
+ ${input.attemptId}::uuid,
114
+ ${input.executionGeneration}::integer,
115
+ ${input.operationId}::uuid,
116
+ ${input.kind}::text,
117
+ ${input.text}::text,
118
+ ${input.expiresInDays}::integer
119
+ )`,
120
+ ),
121
+ );
122
+ if (rows.length !== 1) throw new Error("Task note create returned no durable receipt");
123
+ return TaskNoteMutationResult.parse({ note: noteFromRow(rows[0]!), replayed: rows[0]!.replayed });
124
+ }
125
+
126
+ export async function archiveTaskNote(db: Database, input: ArchiveTaskNoteInput) {
127
+ assertAttemptClaims(input);
128
+ TaskNoteReason.parse(input.reason);
129
+ const rows = await withRlsContext(
130
+ db,
131
+ { accountId: input.accountId, workspaceId: input.workspaceId },
132
+ async (tx) =>
133
+ await rawRows<TaskNoteRow>(
134
+ tx,
135
+ sql`SELECT * FROM archive_task_note_for_attempt(
136
+ ${input.accountId}::uuid,
137
+ ${input.workspaceId}::uuid,
138
+ ${input.sessionId}::uuid,
139
+ ${input.turnId}::uuid,
140
+ ${input.attemptId}::uuid,
141
+ ${input.executionGeneration}::integer,
142
+ ${input.operationId}::uuid,
143
+ ${input.noteId}::uuid,
144
+ ${input.expectedVersion}::integer,
145
+ ${input.reason}::text
146
+ )`,
147
+ ),
148
+ );
149
+ if (rows.length !== 1) throw new Error("Task note archive returned no durable receipt");
150
+ return TaskNoteMutationResult.parse({ note: noteFromRow(rows[0]!), replayed: rows[0]!.replayed });
151
+ }
152
+
153
+ export async function listTaskNotes(db: Database, input: ListTaskNotesInput) {
154
+ assertAttemptClaims(input);
155
+ const limit = input.limit ?? TASK_NOTE_LIST_DEFAULT_LIMIT;
156
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > TASK_NOTE_LIST_MAX_LIMIT) {
157
+ throw new Error(`Task note list limit must be 1-${TASK_NOTE_LIST_MAX_LIMIT}`);
158
+ }
159
+ const rows = await withRlsContext(
160
+ db,
161
+ { accountId: input.accountId, workspaceId: input.workspaceId },
162
+ async (tx) =>
163
+ await rawRows<TaskNoteRow>(
164
+ tx,
165
+ sql`SELECT * FROM list_task_notes_for_attempt(
166
+ ${input.accountId}::uuid,
167
+ ${input.workspaceId}::uuid,
168
+ ${input.sessionId}::uuid,
169
+ ${input.turnId}::uuid,
170
+ ${input.attemptId}::uuid,
171
+ ${input.executionGeneration}::integer,
172
+ ${input.includeArchived ?? false}::boolean,
173
+ ${limit}::integer
174
+ )`,
175
+ ),
176
+ );
177
+ return TaskNoteListResponse.parse({ notes: rows.map(noteFromRow) });
178
+ }