@penclipai/db 2026.704.0 → 2026.714.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 (122) hide show
  1. package/dist/backup-lib.test.js +1 -1
  2. package/dist/backup-lib.test.js.map +1 -1
  3. package/dist/check-migration-safety.d.ts +27 -0
  4. package/dist/check-migration-safety.d.ts.map +1 -0
  5. package/dist/check-migration-safety.js +811 -0
  6. package/dist/check-migration-safety.js.map +1 -0
  7. package/dist/check-migration-safety.test.d.ts +2 -0
  8. package/dist/check-migration-safety.test.d.ts.map +1 -0
  9. package/dist/check-migration-safety.test.js +391 -0
  10. package/dist/check-migration-safety.test.js.map +1 -0
  11. package/dist/client.test.js +743 -0
  12. package/dist/client.test.js.map +1 -1
  13. package/dist/issue-comment-derived-attribution-migration.test.d.ts +2 -0
  14. package/dist/issue-comment-derived-attribution-migration.test.d.ts.map +1 -0
  15. package/dist/issue-comment-derived-attribution-migration.test.js +287 -0
  16. package/dist/issue-comment-derived-attribution-migration.test.js.map +1 -0
  17. package/dist/migration-safety-baseline.d.ts +135 -0
  18. package/dist/migration-safety-baseline.d.ts.map +1 -0
  19. package/dist/migration-safety-baseline.js +150 -0
  20. package/dist/migration-safety-baseline.js.map +1 -0
  21. package/dist/migrations/0128_user_specific_secrets.sql +178 -0
  22. package/dist/migrations/0129_agent_api_key_responsible_user.sql +41 -0
  23. package/dist/migrations/0131_repair_run_responsible_user_context_refs.sql +67 -0
  24. package/dist/migrations/0132_issue_comment_derived_attribution_fast.sql +82 -0
  25. package/dist/migrations/0133_resource_membership_stars.sql +7 -0
  26. package/dist/migrations/0134_run_responsible_user_invariant.sql +211 -0
  27. package/dist/migrations/0135_repair_run_responsible_user_updated_at_sweep.sql +84 -0
  28. package/dist/migrations/0136_acpx_default_engine_migration.sql +97 -0
  29. package/dist/migrations/0137_skill_studio_server_foundation.sql +76 -0
  30. package/dist/migrations/0138_skill_studio_run_retention.sql +5 -0
  31. package/dist/migrations/0139_skill_studio_run_templates.sql +44 -0
  32. package/dist/migrations/0140_built_in_managed_resources.sql +43 -0
  33. package/dist/migrations/0141_heartbeat_runs_company_created_at_index.sql +2 -0
  34. package/dist/migrations/0142_company_search_sort_indexes.sql +3 -0
  35. package/dist/migrations/0143_cases_foundation.sql +248 -0
  36. package/dist/migrations/0144_case_document_annotations.sql +31 -0
  37. package/dist/migrations/0145_inbox_dismissal_snooze_kind.sql +15 -0
  38. package/dist/migrations/0146_routine_activity_gate.sql +3 -0
  39. package/dist/migrations/0147_cost_event_status.sql +1 -0
  40. package/dist/migrations/meta/_journal.json +132 -6
  41. package/dist/schema/agent_api_keys.d.ts +23 -0
  42. package/dist/schema/agent_api_keys.d.ts.map +1 -1
  43. package/dist/schema/agent_api_keys.js +1 -0
  44. package/dist/schema/agent_api_keys.js.map +1 -1
  45. package/dist/schema/agent_memberships.d.ts +17 -0
  46. package/dist/schema/agent_memberships.d.ts.map +1 -1
  47. package/dist/schema/agent_memberships.js +2 -0
  48. package/dist/schema/agent_memberships.js.map +1 -1
  49. package/dist/schema/built_in_managed_resources.d.ts +197 -0
  50. package/dist/schema/built_in_managed_resources.d.ts.map +1 -0
  51. package/dist/schema/built_in_managed_resources.js +22 -0
  52. package/dist/schema/built_in_managed_resources.js.map +1 -0
  53. package/dist/schema/cases.d.ts +982 -0
  54. package/dist/schema/cases.d.ts.map +1 -0
  55. package/dist/schema/cases.js +122 -0
  56. package/dist/schema/cases.js.map +1 -0
  57. package/dist/schema/companies.d.ts +17 -0
  58. package/dist/schema/companies.d.ts.map +1 -1
  59. package/dist/schema/companies.js +1 -0
  60. package/dist/schema/companies.js.map +1 -1
  61. package/dist/schema/company_secrets.d.ts +51 -0
  62. package/dist/schema/company_secrets.d.ts.map +1 -1
  63. package/dist/schema/company_secrets.js +27 -3
  64. package/dist/schema/company_secrets.js.map +1 -1
  65. package/dist/schema/company_skills.d.ts +788 -0
  66. package/dist/schema/company_skills.d.ts.map +1 -1
  67. package/dist/schema/company_skills.js +63 -0
  68. package/dist/schema/company_skills.js.map +1 -1
  69. package/dist/schema/cost_events.d.ts +17 -0
  70. package/dist/schema/cost_events.d.ts.map +1 -1
  71. package/dist/schema/cost_events.js +1 -0
  72. package/dist/schema/cost_events.js.map +1 -1
  73. package/dist/schema/document_annotation_comments.d.ts +17 -0
  74. package/dist/schema/document_annotation_comments.d.ts.map +1 -1
  75. package/dist/schema/document_annotation_comments.js +4 -1
  76. package/dist/schema/document_annotation_comments.js.map +1 -1
  77. package/dist/schema/document_annotation_threads.d.ts +17 -0
  78. package/dist/schema/document_annotation_threads.d.ts.map +1 -1
  79. package/dist/schema/document_annotation_threads.js +4 -1
  80. package/dist/schema/document_annotation_threads.js.map +1 -1
  81. package/dist/schema/heartbeat_runs.d.ts +17 -0
  82. package/dist/schema/heartbeat_runs.d.ts.map +1 -1
  83. package/dist/schema/heartbeat_runs.js +3 -0
  84. package/dist/schema/heartbeat_runs.js.map +1 -1
  85. package/dist/schema/inbox_dismissals.d.ts +36 -0
  86. package/dist/schema/inbox_dismissals.d.ts.map +1 -1
  87. package/dist/schema/inbox_dismissals.js +2 -0
  88. package/dist/schema/inbox_dismissals.js.map +1 -1
  89. package/dist/schema/index.d.ts +5 -1
  90. package/dist/schema/index.d.ts.map +1 -1
  91. package/dist/schema/index.js +5 -1
  92. package/dist/schema/index.js.map +1 -1
  93. package/dist/schema/issues.d.ts +34 -0
  94. package/dist/schema/issues.d.ts.map +1 -1
  95. package/dist/schema/issues.js +7 -0
  96. package/dist/schema/issues.js.map +1 -1
  97. package/dist/schema/project_memberships.d.ts +17 -0
  98. package/dist/schema/project_memberships.d.ts.map +1 -1
  99. package/dist/schema/project_memberships.js +2 -0
  100. package/dist/schema/project_memberships.js.map +1 -1
  101. package/dist/schema/routines.d.ts +85 -0
  102. package/dist/schema/routines.d.ts.map +1 -1
  103. package/dist/schema/routines.js +8 -0
  104. package/dist/schema/routines.js.map +1 -1
  105. package/dist/schema/secret_access_events.d.ts +103 -1
  106. package/dist/schema/secret_access_events.d.ts.map +1 -1
  107. package/dist/schema/secret_access_events.js +10 -1
  108. package/dist/schema/secret_access_events.js.map +1 -1
  109. package/dist/schema/user_secret_declarations.d.ts +229 -0
  110. package/dist/schema/user_secret_declarations.d.ts.map +1 -0
  111. package/dist/schema/user_secret_declarations.js +31 -0
  112. package/dist/schema/user_secret_declarations.js.map +1 -0
  113. package/dist/schema/user_secret_definitions.d.ts +316 -0
  114. package/dist/schema/user_secret_definitions.d.ts.map +1 -0
  115. package/dist/schema/user_secret_definitions.js +33 -0
  116. package/dist/schema/user_secret_definitions.js.map +1 -0
  117. package/dist/table-size-estimates.d.ts +372 -0
  118. package/dist/table-size-estimates.d.ts.map +1 -0
  119. package/dist/table-size-estimates.js +155 -0
  120. package/dist/table-size-estimates.js.map +1 -0
  121. package/package.json +3 -3
  122. package/dist/migrations/0126_issue_comment_derived_attribution.sql +0 -69
@@ -0,0 +1,211 @@
1
+ ALTER TABLE "companies" ADD COLUMN IF NOT EXISTS "default_responsible_user_id" text;
2
+ --> statement-breakpoint
3
+ WITH owner_defaults AS (
4
+ SELECT DISTINCT ON ("company_id")
5
+ "company_id",
6
+ "principal_id" AS "user_id"
7
+ FROM "company_memberships"
8
+ WHERE "principal_type" = 'user'
9
+ AND "status" = 'active'
10
+ AND "membership_role" = 'owner'
11
+ ORDER BY "company_id", "created_at" ASC, "id" ASC
12
+ )
13
+ UPDATE "companies" AS c
14
+ SET "default_responsible_user_id" = owner_defaults."user_id"
15
+ FROM owner_defaults
16
+ WHERE c."id" = owner_defaults."company_id"
17
+ AND c."default_responsible_user_id" IS NULL;
18
+ --> statement-breakpoint
19
+ WITH RECURSIVE issue_chain AS (
20
+ SELECT
21
+ child."id" AS "issue_id",
22
+ child."company_id",
23
+ child."parent_id",
24
+ child."responsible_user_id",
25
+ child."created_by_user_id",
26
+ 0 AS "depth"
27
+ FROM "issues" AS child
28
+ WHERE child."responsible_user_id" IS NULL
29
+ UNION ALL
30
+ SELECT
31
+ issue_chain."issue_id",
32
+ parent."company_id",
33
+ parent."parent_id",
34
+ parent."responsible_user_id",
35
+ parent."created_by_user_id",
36
+ issue_chain."depth" + 1
37
+ FROM issue_chain
38
+ JOIN "issues" AS parent
39
+ ON parent."id" = issue_chain."parent_id"
40
+ AND parent."company_id" = issue_chain."company_id"
41
+ WHERE issue_chain."depth" < 50
42
+ ),
43
+ resolved_issue_users AS (
44
+ SELECT DISTINCT ON ("issue_id")
45
+ "issue_id",
46
+ COALESCE("responsible_user_id", "created_by_user_id") AS "user_id"
47
+ FROM issue_chain
48
+ WHERE COALESCE("responsible_user_id", "created_by_user_id") IS NOT NULL
49
+ ORDER BY "issue_id", "depth" ASC
50
+ )
51
+ UPDATE "issues" AS i
52
+ SET "responsible_user_id" = resolved_issue_users."user_id"
53
+ FROM resolved_issue_users
54
+ WHERE i."id" = resolved_issue_users."issue_id"
55
+ AND i."responsible_user_id" IS NULL;
56
+ --> statement-breakpoint
57
+ UPDATE "issues" AS i
58
+ SET "responsible_user_id" = c."default_responsible_user_id"
59
+ FROM "companies" AS c
60
+ WHERE i."company_id" = c."id"
61
+ AND i."responsible_user_id" IS NULL
62
+ AND c."default_responsible_user_id" IS NOT NULL;
63
+ --> statement-breakpoint
64
+ WITH routine_responsible_users AS (
65
+ SELECT
66
+ r."id",
67
+ COALESCE(r."created_by_user_id", parent_issue."responsible_user_id", c."default_responsible_user_id") AS "user_id"
68
+ FROM "routines" AS r
69
+ JOIN "companies" AS c ON c."id" = r."company_id"
70
+ LEFT JOIN "issues" AS parent_issue
71
+ ON parent_issue."id" = r."parent_issue_id"
72
+ AND parent_issue."company_id" = r."company_id"
73
+ WHERE r."responsible_user_id" IS NULL
74
+ )
75
+ UPDATE "routines" AS r
76
+ SET "responsible_user_id" = routine_responsible_users."user_id"
77
+ FROM routine_responsible_users
78
+ WHERE r."id" = routine_responsible_users."id"
79
+ AND routine_responsible_users."user_id" IS NOT NULL;
80
+ --> statement-breakpoint
81
+ WITH routine_revision_responsible_users AS (
82
+ SELECT
83
+ rr."id",
84
+ COALESCE(rr."created_by_user_id", r."responsible_user_id", c."default_responsible_user_id") AS "user_id"
85
+ FROM "routine_revisions" AS rr
86
+ JOIN "routines" AS r
87
+ ON rr."routine_id" = r."id"
88
+ AND rr."company_id" = r."company_id"
89
+ JOIN "companies" AS c ON c."id" = rr."company_id"
90
+ WHERE rr."responsible_user_id" IS NULL
91
+ )
92
+ UPDATE "routine_revisions" AS rr
93
+ SET "responsible_user_id" = routine_revision_responsible_users."user_id"
94
+ FROM routine_revision_responsible_users
95
+ WHERE rr."id" = routine_revision_responsible_users."id"
96
+ AND routine_revision_responsible_users."user_id" IS NOT NULL;
97
+ --> statement-breakpoint
98
+ WITH routine_run_responsible_users AS (
99
+ SELECT
100
+ rr."id",
101
+ COALESCE(linked_issue."responsible_user_id", r."responsible_user_id", c."default_responsible_user_id") AS "user_id"
102
+ FROM "routine_runs" AS rr
103
+ JOIN "routines" AS r
104
+ ON rr."routine_id" = r."id"
105
+ AND rr."company_id" = r."company_id"
106
+ JOIN "companies" AS c ON c."id" = rr."company_id"
107
+ LEFT JOIN "issues" AS linked_issue
108
+ ON linked_issue."id" = rr."linked_issue_id"
109
+ AND linked_issue."company_id" = rr."company_id"
110
+ WHERE rr."responsible_user_id" IS NULL
111
+ )
112
+ UPDATE "routine_runs" AS rr
113
+ SET "responsible_user_id" = routine_run_responsible_users."user_id"
114
+ FROM routine_run_responsible_users
115
+ WHERE rr."id" = routine_run_responsible_users."id"
116
+ AND routine_run_responsible_users."user_id" IS NOT NULL;
117
+ --> statement-breakpoint
118
+ UPDATE "heartbeat_runs" AS h
119
+ SET "responsible_user_id" = original."responsible_user_id"
120
+ FROM "heartbeat_runs" AS original
121
+ WHERE h."retry_of_run_id" = original."id"
122
+ AND h."company_id" = original."company_id"
123
+ AND h."responsible_user_id" IS NULL
124
+ AND original."responsible_user_id" IS NOT NULL;
125
+ --> statement-breakpoint
126
+ WITH extracted_run_refs AS (
127
+ SELECT
128
+ h."id" AS "run_id",
129
+ h."company_id",
130
+ NULLIF(h."context_snapshot" ->> 'issueId', '') AS "issue_ref",
131
+ 1 AS "ref_priority"
132
+ FROM "heartbeat_runs" AS h
133
+ WHERE h."responsible_user_id" IS NULL
134
+ AND NULLIF(h."context_snapshot" ->> 'issueId', '') IS NOT NULL
135
+
136
+ UNION ALL
137
+
138
+ SELECT
139
+ h."id" AS "run_id",
140
+ h."company_id",
141
+ NULLIF(h."context_snapshot" ->> 'taskId', '') AS "issue_ref",
142
+ 2 AS "ref_priority"
143
+ FROM "heartbeat_runs" AS h
144
+ WHERE h."responsible_user_id" IS NULL
145
+ AND NULLIF(h."context_snapshot" ->> 'taskId', '') IS NOT NULL
146
+ ),
147
+ uuid_run_refs AS (
148
+ SELECT
149
+ "run_id",
150
+ "company_id",
151
+ "issue_ref"::uuid AS "issue_id",
152
+ "ref_priority"
153
+ FROM extracted_run_refs
154
+ WHERE "issue_ref" ~* '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'
155
+ ),
156
+ resolved_run_users AS (
157
+ SELECT DISTINCT ON ("run_id")
158
+ "run_id",
159
+ "responsible_user_id"
160
+ FROM (
161
+ SELECT
162
+ refs."run_id",
163
+ i."responsible_user_id",
164
+ refs."ref_priority",
165
+ 1 AS "match_priority"
166
+ FROM uuid_run_refs AS refs
167
+ JOIN "issues" AS i
168
+ ON i."id" = refs."issue_id"
169
+ AND i."company_id" = refs."company_id"
170
+ WHERE i."responsible_user_id" IS NOT NULL
171
+
172
+ UNION ALL
173
+
174
+ SELECT
175
+ refs."run_id",
176
+ i."responsible_user_id",
177
+ refs."ref_priority",
178
+ 2 AS "match_priority"
179
+ FROM extracted_run_refs AS refs
180
+ JOIN "issues" AS i
181
+ ON i."identifier" = refs."issue_ref"
182
+ AND i."company_id" = refs."company_id"
183
+ WHERE refs."issue_ref" IS NOT NULL
184
+ AND i."responsible_user_id" IS NOT NULL
185
+ ) AS candidates
186
+ ORDER BY "run_id", "ref_priority" ASC, "match_priority" ASC
187
+ )
188
+ UPDATE "heartbeat_runs" AS h
189
+ SET "responsible_user_id" = resolved_run_users."responsible_user_id"
190
+ FROM resolved_run_users
191
+ WHERE h."id" = resolved_run_users."run_id"
192
+ AND h."responsible_user_id" IS NULL;
193
+ --> statement-breakpoint
194
+ UPDATE "heartbeat_runs" AS h
195
+ SET "responsible_user_id" = awr."requested_by_actor_id"
196
+ FROM "agent_wakeup_requests" AS awr
197
+ WHERE h."wakeup_request_id" = awr."id"
198
+ AND h."company_id" = awr."company_id"
199
+ AND h."responsible_user_id" IS NULL
200
+ AND awr."requested_by_actor_type" = 'user'
201
+ AND awr."requested_by_actor_id" IS NOT NULL;
202
+ --> statement-breakpoint
203
+ UPDATE "heartbeat_runs" AS h
204
+ SET "responsible_user_id" = c."default_responsible_user_id"
205
+ FROM "companies" AS c
206
+ WHERE h."company_id" = c."id"
207
+ AND h."responsible_user_id" IS NULL
208
+ AND c."default_responsible_user_id" IS NOT NULL;
209
+ --> statement-breakpoint
210
+ CREATE INDEX IF NOT EXISTS "companies_default_responsible_user_idx"
211
+ ON "companies" ("default_responsible_user_id");
@@ -0,0 +1,84 @@
1
+ DROP TABLE IF EXISTS "run_responsible_user_updated_at_sweeps";
2
+ --> statement-breakpoint
3
+ CREATE TEMP TABLE "run_responsible_user_updated_at_sweeps" ON COMMIT DROP AS
4
+ SELECT i."company_id", i."updated_at" AS "sweep_at"
5
+ FROM "issues" AS i
6
+ WHERE EXISTS (
7
+ SELECT 1
8
+ FROM "heartbeat_runs" AS h
9
+ WHERE h."company_id" = i."company_id"
10
+ AND h."updated_at" = i."updated_at"
11
+ )
12
+ AND EXISTS (
13
+ SELECT 1
14
+ FROM "companies" AS c
15
+ WHERE c."id" = i."company_id"
16
+ AND c."updated_at" = i."updated_at"
17
+ )
18
+ GROUP BY i."company_id", i."updated_at"
19
+ HAVING count(*) > 100;
20
+ --> statement-breakpoint
21
+ UPDATE "issues" AS i
22
+ SET "updated_at" = GREATEST(
23
+ i."created_at",
24
+ COALESCE(CASE WHEN i."started_at" <= sweep."sweep_at" THEN i."started_at" END, i."created_at"),
25
+ COALESCE(CASE WHEN i."completed_at" <= sweep."sweep_at" THEN i."completed_at" END, i."created_at"),
26
+ COALESCE(CASE WHEN i."cancelled_at" <= sweep."sweep_at" THEN i."cancelled_at" END, i."created_at"),
27
+ COALESCE(CASE WHEN i."monitor_wake_requested_at" <= sweep."sweep_at" THEN i."monitor_wake_requested_at" END, i."created_at"),
28
+ COALESCE(CASE WHEN i."monitor_last_triggered_at" <= sweep."sweep_at" THEN i."monitor_last_triggered_at" END, i."created_at"),
29
+ COALESCE(
30
+ (
31
+ SELECT max(GREATEST(c."created_at", c."updated_at"))
32
+ FROM "issue_comments" AS c
33
+ WHERE c."company_id" = i."company_id"
34
+ AND c."issue_id" = i."id"
35
+ AND c."created_at" <= sweep."sweep_at"
36
+ AND c."updated_at" <= sweep."sweep_at"
37
+ ),
38
+ i."created_at"
39
+ )
40
+ )
41
+ FROM "run_responsible_user_updated_at_sweeps" AS sweep
42
+ WHERE i."company_id" = sweep."company_id"
43
+ AND i."updated_at" = sweep."sweep_at";
44
+ --> statement-breakpoint
45
+ UPDATE "heartbeat_runs" AS h
46
+ SET "updated_at" = GREATEST(
47
+ h."created_at",
48
+ COALESCE(CASE WHEN h."started_at" <= sweep."sweep_at" THEN h."started_at" END, h."created_at"),
49
+ COALESCE(CASE WHEN h."process_started_at" <= sweep."sweep_at" THEN h."process_started_at" END, h."created_at"),
50
+ COALESCE(CASE WHEN h."last_output_at" <= sweep."sweep_at" THEN h."last_output_at" END, h."created_at"),
51
+ COALESCE(CASE WHEN h."scheduled_retry_at" <= sweep."sweep_at" THEN h."scheduled_retry_at" END, h."created_at"),
52
+ COALESCE(CASE WHEN h."finished_at" <= sweep."sweep_at" THEN h."finished_at" END, h."created_at")
53
+ )
54
+ FROM "run_responsible_user_updated_at_sweeps" AS sweep
55
+ WHERE h."company_id" = sweep."company_id"
56
+ AND h."updated_at" = sweep."sweep_at";
57
+ --> statement-breakpoint
58
+ UPDATE "routine_runs" AS rr
59
+ SET "updated_at" = GREATEST(
60
+ rr."created_at",
61
+ COALESCE(CASE WHEN rr."triggered_at" <= sweep."sweep_at" THEN rr."triggered_at" END, rr."created_at"),
62
+ COALESCE(CASE WHEN rr."completed_at" <= sweep."sweep_at" THEN rr."completed_at" END, rr."created_at")
63
+ )
64
+ FROM "run_responsible_user_updated_at_sweeps" AS sweep
65
+ WHERE rr."company_id" = sweep."company_id"
66
+ AND rr."updated_at" = sweep."sweep_at";
67
+ --> statement-breakpoint
68
+ UPDATE "routines" AS r
69
+ SET "updated_at" = GREATEST(
70
+ r."created_at",
71
+ COALESCE(CASE WHEN r."last_triggered_at" <= sweep."sweep_at" THEN r."last_triggered_at" END, r."created_at"),
72
+ COALESCE(CASE WHEN r."last_enqueued_at" <= sweep."sweep_at" THEN r."last_enqueued_at" END, r."created_at")
73
+ )
74
+ FROM "run_responsible_user_updated_at_sweeps" AS sweep
75
+ WHERE r."company_id" = sweep."company_id"
76
+ AND r."updated_at" = sweep."sweep_at";
77
+ --> statement-breakpoint
78
+ UPDATE "companies" AS c
79
+ SET "updated_at" = c."created_at"
80
+ FROM "run_responsible_user_updated_at_sweeps" AS sweep
81
+ WHERE c."id" = sweep."company_id"
82
+ AND c."updated_at" = sweep."sweep_at";
83
+ --> statement-breakpoint
84
+ DROP TABLE IF EXISTS "run_responsible_user_updated_at_sweeps";
@@ -0,0 +1,97 @@
1
+ WITH migrated_agents AS (
2
+ SELECT
3
+ "id",
4
+ "company_id",
5
+ CASE lower(COALESCE(NULLIF("adapter_config" ->> 'agent', ''), 'claude'))
6
+ WHEN 'codex' THEN 'codex_local'
7
+ ELSE 'claude_local'
8
+ END AS "next_adapter_type",
9
+ CASE lower(COALESCE(NULLIF("adapter_config" ->> 'agent', ''), 'claude'))
10
+ WHEN 'codex' THEN
11
+ (
12
+ "adapter_config"
13
+ - 'agent'
14
+ - 'effort'
15
+ - 'reasoningEffort'
16
+ - 'thinkingEffort'
17
+ )
18
+ || jsonb_build_object('engine', 'acp')
19
+ || CASE
20
+ WHEN COALESCE(
21
+ "adapter_config" -> 'modelReasoningEffort',
22
+ "adapter_config" -> 'reasoningEffort',
23
+ "adapter_config" -> 'thinkingEffort',
24
+ "adapter_config" -> 'effort'
25
+ ) IS NULL THEN '{}'::jsonb
26
+ ELSE jsonb_build_object(
27
+ 'modelReasoningEffort',
28
+ COALESCE(
29
+ "adapter_config" -> 'modelReasoningEffort',
30
+ "adapter_config" -> 'reasoningEffort',
31
+ "adapter_config" -> 'thinkingEffort',
32
+ "adapter_config" -> 'effort'
33
+ )
34
+ )
35
+ END
36
+ ELSE
37
+ (
38
+ "adapter_config"
39
+ - 'agent'
40
+ - 'modelReasoningEffort'
41
+ - 'reasoningEffort'
42
+ - 'thinkingEffort'
43
+ )
44
+ || jsonb_build_object('engine', 'acp')
45
+ || CASE
46
+ WHEN COALESCE(
47
+ "adapter_config" -> 'effort',
48
+ "adapter_config" -> 'thinkingEffort',
49
+ "adapter_config" -> 'reasoningEffort',
50
+ "adapter_config" -> 'modelReasoningEffort'
51
+ ) IS NULL THEN '{}'::jsonb
52
+ ELSE jsonb_build_object(
53
+ 'effort',
54
+ COALESCE(
55
+ "adapter_config" -> 'effort',
56
+ "adapter_config" -> 'thinkingEffort',
57
+ "adapter_config" -> 'reasoningEffort',
58
+ "adapter_config" -> 'modelReasoningEffort'
59
+ )
60
+ )
61
+ END
62
+ END AS "next_adapter_config"
63
+ FROM "agents"
64
+ WHERE "adapter_type" = 'acpx_local'
65
+ AND lower(COALESCE(NULLIF("adapter_config" ->> 'agent', ''), 'claude')) IN ('claude', 'codex')
66
+ ),
67
+ updated_agents AS (
68
+ UPDATE "agents"
69
+ SET
70
+ "adapter_type" = migrated_agents."next_adapter_type",
71
+ "adapter_config" = migrated_agents."next_adapter_config",
72
+ "updated_at" = now()
73
+ FROM migrated_agents
74
+ WHERE "agents"."id" = migrated_agents."id"
75
+ RETURNING
76
+ "agents"."id",
77
+ "agents"."company_id",
78
+ migrated_agents."next_adapter_type"
79
+ ),
80
+ cleared_task_sessions AS (
81
+ DELETE FROM "agent_task_sessions"
82
+ USING updated_agents
83
+ WHERE "agent_task_sessions"."agent_id" = updated_agents."id"
84
+ AND "agent_task_sessions"."company_id" = updated_agents."company_id"
85
+ AND "agent_task_sessions"."adapter_type" = 'acpx_local'
86
+ RETURNING "agent_task_sessions"."id"
87
+ )
88
+ UPDATE "agent_runtime_state"
89
+ SET
90
+ "adapter_type" = updated_agents."next_adapter_type",
91
+ "session_id" = NULL,
92
+ "state_json" = '{}'::jsonb,
93
+ "last_error" = NULL,
94
+ "updated_at" = now()
95
+ FROM updated_agents
96
+ WHERE "agent_runtime_state"."agent_id" = updated_agents."id"
97
+ AND "agent_runtime_state"."company_id" = updated_agents."company_id";
@@ -0,0 +1,76 @@
1
+ ALTER TABLE "issues" ADD COLUMN IF NOT EXISTS "harness_kind" text;--> statement-breakpoint
2
+ CREATE INDEX IF NOT EXISTS "issues_company_harness_kind_idx" ON "issues" USING btree ("company_id","harness_kind");--> statement-breakpoint
3
+ CREATE TABLE IF NOT EXISTS "company_skill_test_inputs" (
4
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
5
+ "company_id" uuid NOT NULL,
6
+ "skill_id" uuid NOT NULL,
7
+ "name" text NOT NULL,
8
+ "content" text NOT NULL,
9
+ "created_by" text,
10
+ "deleted_at" timestamp with time zone,
11
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
12
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
13
+ );--> statement-breakpoint
14
+ CREATE TABLE IF NOT EXISTS "company_skill_test_runs" (
15
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
16
+ "company_id" uuid NOT NULL,
17
+ "skill_id" uuid NOT NULL,
18
+ "input_id" uuid,
19
+ "input_snapshot" text NOT NULL,
20
+ "skill_version_id" uuid NOT NULL,
21
+ "agent_id" uuid NOT NULL,
22
+ "agent_config_snapshot" jsonb DEFAULT '{}'::jsonb NOT NULL,
23
+ "issue_id" uuid NOT NULL,
24
+ "status" text DEFAULT 'queued' NOT NULL,
25
+ "output_document_key" text DEFAULT 'output' NOT NULL,
26
+ "output_snapshot" text DEFAULT '' NOT NULL,
27
+ "error" text,
28
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
29
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
30
+ );--> statement-breakpoint
31
+ DO $$ BEGIN
32
+ ALTER TABLE "company_skill_test_inputs" ADD CONSTRAINT "company_skill_test_inputs_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
33
+ EXCEPTION
34
+ WHEN duplicate_object THEN null;
35
+ END $$;--> statement-breakpoint
36
+ DO $$ BEGIN
37
+ ALTER TABLE "company_skill_test_inputs" ADD CONSTRAINT "company_skill_test_inputs_skill_id_company_skills_id_fk" FOREIGN KEY ("skill_id") REFERENCES "public"."company_skills"("id") ON DELETE cascade ON UPDATE no action;
38
+ EXCEPTION
39
+ WHEN duplicate_object THEN null;
40
+ END $$;--> statement-breakpoint
41
+ DO $$ BEGIN
42
+ ALTER TABLE "company_skill_test_runs" ADD CONSTRAINT "company_skill_test_runs_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
43
+ EXCEPTION
44
+ WHEN duplicate_object THEN null;
45
+ END $$;--> statement-breakpoint
46
+ DO $$ BEGIN
47
+ ALTER TABLE "company_skill_test_runs" ADD CONSTRAINT "company_skill_test_runs_skill_id_company_skills_id_fk" FOREIGN KEY ("skill_id") REFERENCES "public"."company_skills"("id") ON DELETE cascade ON UPDATE no action;
48
+ EXCEPTION
49
+ WHEN duplicate_object THEN null;
50
+ END $$;--> statement-breakpoint
51
+ DO $$ BEGIN
52
+ ALTER TABLE "company_skill_test_runs" ADD CONSTRAINT "company_skill_test_runs_input_id_company_skill_test_inputs_id_fk" FOREIGN KEY ("input_id") REFERENCES "public"."company_skill_test_inputs"("id") ON DELETE set null ON UPDATE no action;
53
+ EXCEPTION
54
+ WHEN duplicate_object THEN null;
55
+ END $$;--> statement-breakpoint
56
+ DO $$ BEGIN
57
+ ALTER TABLE "company_skill_test_runs" ADD CONSTRAINT "company_skill_test_runs_skill_version_id_company_skill_versions_id_fk" FOREIGN KEY ("skill_version_id") REFERENCES "public"."company_skill_versions"("id") ON DELETE restrict ON UPDATE no action;
58
+ EXCEPTION
59
+ WHEN duplicate_object THEN null;
60
+ END $$;--> statement-breakpoint
61
+ DO $$ BEGIN
62
+ ALTER TABLE "company_skill_test_runs" ADD CONSTRAINT "company_skill_test_runs_agent_id_agents_id_fk" FOREIGN KEY ("agent_id") REFERENCES "public"."agents"("id") ON DELETE restrict ON UPDATE no action;
63
+ EXCEPTION
64
+ WHEN duplicate_object THEN null;
65
+ END $$;--> statement-breakpoint
66
+ DO $$ BEGIN
67
+ ALTER TABLE "company_skill_test_runs" ADD CONSTRAINT "company_skill_test_runs_issue_id_issues_id_fk" FOREIGN KEY ("issue_id") REFERENCES "public"."issues"("id") ON DELETE restrict ON UPDATE no action;
68
+ EXCEPTION
69
+ WHEN duplicate_object THEN null;
70
+ END $$;--> statement-breakpoint
71
+ CREATE INDEX IF NOT EXISTS "company_skill_test_inputs_company_skill_name_idx" ON "company_skill_test_inputs" USING btree ("company_id","skill_id","name");--> statement-breakpoint
72
+ CREATE INDEX IF NOT EXISTS "company_skill_test_inputs_company_skill_active_idx" ON "company_skill_test_inputs" USING btree ("company_id","skill_id","deleted_at");--> statement-breakpoint
73
+ CREATE INDEX IF NOT EXISTS "company_skill_test_runs_company_skill_created_idx" ON "company_skill_test_runs" USING btree ("company_id","skill_id","created_at");--> statement-breakpoint
74
+ CREATE UNIQUE INDEX IF NOT EXISTS "company_skill_test_runs_company_issue_idx" ON "company_skill_test_runs" USING btree ("company_id","issue_id");--> statement-breakpoint
75
+ CREATE INDEX IF NOT EXISTS "company_skill_test_runs_company_input_created_idx" ON "company_skill_test_runs" USING btree ("company_id","input_id","created_at");--> statement-breakpoint
76
+ CREATE INDEX IF NOT EXISTS "company_skill_test_runs_company_status_idx" ON "company_skill_test_runs" USING btree ("company_id","status");
@@ -0,0 +1,5 @@
1
+ ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "deleted_at" timestamp with time zone;--> statement-breakpoint
2
+ ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "superseded_at" timestamp with time zone;--> statement-breakpoint
3
+ ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "harness_issue_expires_at" timestamp with time zone;--> statement-breakpoint
4
+ ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "harness_issue_deleted_at" timestamp with time zone;--> statement-breakpoint
5
+ CREATE INDEX IF NOT EXISTS "company_skill_test_runs_company_harness_expires_idx" ON "company_skill_test_runs" USING btree ("company_id","harness_issue_expires_at");
@@ -0,0 +1,44 @@
1
+ CREATE TABLE IF NOT EXISTS "company_skill_test_run_templates" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "company_id" uuid NOT NULL,
4
+ "name" text NOT NULL,
5
+ "description" text,
6
+ "body" text NOT NULL,
7
+ "created_by_agent_id" uuid,
8
+ "created_by_user_id" text,
9
+ "updated_by_agent_id" uuid,
10
+ "updated_by_user_id" text,
11
+ "deleted_at" timestamp with time zone,
12
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
13
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
14
+ );
15
+ --> statement-breakpoint
16
+ DO $$ BEGIN
17
+ ALTER TABLE "company_skill_test_run_templates" ADD CONSTRAINT "company_skill_test_run_templates_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
18
+ EXCEPTION
19
+ WHEN duplicate_object THEN null;
20
+ END $$;
21
+ --> statement-breakpoint
22
+ DO $$ BEGIN
23
+ ALTER TABLE "company_skill_test_run_templates" ADD CONSTRAINT "company_skill_test_run_templates_created_by_agent_id_agents_id_fk" FOREIGN KEY ("created_by_agent_id") REFERENCES "public"."agents"("id") ON DELETE set null ON UPDATE no action;
24
+ EXCEPTION
25
+ WHEN duplicate_object THEN null;
26
+ END $$;
27
+ --> statement-breakpoint
28
+ DO $$ BEGIN
29
+ ALTER TABLE "company_skill_test_run_templates" ADD CONSTRAINT "company_skill_test_run_templates_updated_by_agent_id_agents_id_fk" FOREIGN KEY ("updated_by_agent_id") REFERENCES "public"."agents"("id") ON DELETE set null ON UPDATE no action;
30
+ EXCEPTION
31
+ WHEN duplicate_object THEN null;
32
+ END $$;
33
+ --> statement-breakpoint
34
+ CREATE INDEX IF NOT EXISTS "company_skill_test_run_templates_company_active_idx" ON "company_skill_test_run_templates" USING btree ("company_id","deleted_at","name");
35
+ --> statement-breakpoint
36
+ ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "template_id" text;
37
+ --> statement-breakpoint
38
+ ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "template_name" text;
39
+ --> statement-breakpoint
40
+ ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "template_body" text;
41
+ --> statement-breakpoint
42
+ ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "rendered_template_body" text;
43
+ --> statement-breakpoint
44
+ ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "harness_issue_description" text DEFAULT '' NOT NULL;
@@ -0,0 +1,43 @@
1
+ CREATE TABLE IF NOT EXISTS "built_in_managed_resources" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "company_id" uuid NOT NULL,
4
+ "bundle_key" text NOT NULL,
5
+ "resource_kind" text NOT NULL,
6
+ "resource_key" text NOT NULL,
7
+ "resource_id" uuid NOT NULL,
8
+ "stock_version" text NOT NULL,
9
+ "stock_hash" text NOT NULL,
10
+ "defaults_json" jsonb DEFAULT '{}'::jsonb NOT NULL,
11
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
12
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
13
+ );
14
+ --> statement-breakpoint
15
+
16
+ DO $$
17
+ BEGIN
18
+ IF NOT EXISTS (
19
+ SELECT 1
20
+ FROM "pg_constraint" c
21
+ JOIN "pg_class" t ON t.oid = c.conrelid
22
+ JOIN "pg_namespace" n ON n.oid = t.relnamespace
23
+ WHERE n.nspname = 'public'
24
+ AND t.relname = 'built_in_managed_resources'
25
+ AND c.conname = 'built_in_managed_resources_company_id_companies_id_fk'
26
+ ) THEN
27
+ ALTER TABLE "built_in_managed_resources"
28
+ ADD CONSTRAINT "built_in_managed_resources_company_id_companies_id_fk"
29
+ FOREIGN KEY ("company_id") REFERENCES "companies"("id") ON DELETE cascade ON UPDATE no action;
30
+ END IF;
31
+ END $$;
32
+ --> statement-breakpoint
33
+
34
+ CREATE INDEX IF NOT EXISTS "built_in_managed_resources_company_idx"
35
+ ON "built_in_managed_resources" ("company_id");
36
+ --> statement-breakpoint
37
+
38
+ CREATE INDEX IF NOT EXISTS "built_in_managed_resources_resource_idx"
39
+ ON "built_in_managed_resources" ("resource_kind", "resource_id");
40
+ --> statement-breakpoint
41
+
42
+ CREATE UNIQUE INDEX IF NOT EXISTS "built_in_managed_resources_company_bundle_resource_uq"
43
+ ON "built_in_managed_resources" ("company_id", "bundle_key", "resource_kind", "resource_key");
@@ -0,0 +1,2 @@
1
+ CREATE INDEX IF NOT EXISTS "heartbeat_runs_company_created_at_desc_idx"
2
+ ON "heartbeat_runs" USING btree ("company_id", "created_at" DESC);
@@ -0,0 +1,3 @@
1
+ CREATE INDEX IF NOT EXISTS "issues_company_updated_idx" ON "issues" ("company_id","updated_at");--> statement-breakpoint
2
+ CREATE INDEX IF NOT EXISTS "issues_company_created_idx" ON "issues" ("company_id","created_at");--> statement-breakpoint
3
+ CREATE INDEX IF NOT EXISTS "issues_company_priority_idx" ON "issues" ("company_id","priority");