@amalgm/automations 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/AXIOMS.md +37 -16
  2. package/PURPOSE.md +14 -1
  3. package/README.md +5 -2
  4. package/dist/host/config.d.ts +1 -0
  5. package/dist/host/config.js +1 -0
  6. package/dist/host/main.js +16 -4
  7. package/dist/host/server.d.ts +3 -0
  8. package/dist/host/server.js +27 -8
  9. package/dist/src/automations.d.ts +4 -7
  10. package/dist/src/automations.js +13 -65
  11. package/dist/src/client.d.ts +1 -0
  12. package/dist/src/client.js +3 -2
  13. package/dist/src/contract.d.ts +4 -30
  14. package/dist/src/crud/automations.js +3 -3
  15. package/dist/src/crud/context.d.ts +1 -0
  16. package/dist/src/crud/context.js +10 -1
  17. package/dist/src/events-http.js +4 -0
  18. package/dist/src/executor.d.ts +12 -3
  19. package/dist/src/executor.js +163 -44
  20. package/dist/src/http.js +4 -0
  21. package/dist/src/index.d.ts +4 -2
  22. package/dist/src/index.js +4 -2
  23. package/dist/src/machine-client.d.ts +1 -0
  24. package/dist/src/machine-client.js +2 -0
  25. package/dist/src/machine.d.ts +2 -1
  26. package/dist/src/machine.js +6 -1
  27. package/dist/src/mcp.d.ts +3 -0
  28. package/dist/src/mcp.js +53 -50
  29. package/dist/src/plan.d.ts +3 -0
  30. package/dist/src/plan.js +48 -0
  31. package/dist/src/run-contract.d.ts +46 -0
  32. package/dist/src/run-contract.js +1 -0
  33. package/dist/src/run-journal.d.ts +8 -0
  34. package/dist/src/run-journal.js +56 -0
  35. package/dist/src/runner.d.ts +14 -0
  36. package/dist/src/runner.js +70 -0
  37. package/dist/src/schema.d.ts +46 -46
  38. package/dist/src/schema.js +18 -3
  39. package/dist/src/supabase-crud/mappers.js +2 -0
  40. package/dist/src/supabase-crud/rows.d.ts +2 -0
  41. package/dist/src/supabase-machine.js +2 -0
  42. package/dist/src/supabase-store.d.ts +1 -4
  43. package/dist/src/supabase-store.js +0 -24
  44. package/dist/src/tool-surface.d.ts +46 -0
  45. package/dist/src/tool-surface.js +125 -0
  46. package/dist/src/types.d.ts +1 -16
  47. package/package.json +5 -5
  48. package/skills/automations/SKILL.md +20 -15
  49. package/supabase/migrations/20260830010000_durable_step_retries.sql +332 -0
@@ -0,0 +1,56 @@
1
+ export function emptyJournal() {
2
+ return { version: 1, steps: [] };
3
+ }
4
+ export function runJournal(value, plan) {
5
+ if (value === undefined)
6
+ return emptyJournal();
7
+ if (!value || typeof value !== 'object' || Array.isArray(value))
8
+ throw new Error('Run step journal is invalid');
9
+ const source = value;
10
+ if (source.version !== 1 || !Array.isArray(source.steps))
11
+ throw new Error('Run step journal is invalid');
12
+ const planIds = new Set(plan.map(({ id }) => id));
13
+ const steps = source.steps.map(runStep);
14
+ const ids = new Set();
15
+ for (const step of steps) {
16
+ if (!planIds.has(step.id))
17
+ throw new Error(`Run step is not in the immutable plan: ${step.id}`);
18
+ if (ids.has(step.id))
19
+ throw new Error(`Run step journal has a duplicate id: ${step.id}`);
20
+ ids.add(step.id);
21
+ }
22
+ return { version: 1, steps };
23
+ }
24
+ export function completed(journal, stepId) {
25
+ return journal.steps.some((step) => step.id === stepId && step.status === 'completed');
26
+ }
27
+ export function stepAttempt(journal, stepId) {
28
+ return journal.steps.find((step) => step.id === stepId)?.attempts ?? 0;
29
+ }
30
+ export function putStep(journal, step) {
31
+ const index = journal.steps.findIndex(({ id }) => id === step.id);
32
+ const steps = [...journal.steps];
33
+ if (index === -1)
34
+ steps.push(step);
35
+ else
36
+ steps[index] = step;
37
+ return { version: 1, steps };
38
+ }
39
+ /** Journals are constructed from JSON fields only; this is the persistence boundary. */
40
+ export function journalJson(journal) {
41
+ return journal;
42
+ }
43
+ function runStep(value) {
44
+ if (!value || typeof value !== 'object' || Array.isArray(value))
45
+ throw new Error('Run step is invalid');
46
+ const item = value;
47
+ if (typeof item.id !== 'string' || !item.id)
48
+ throw new Error('Run step id is invalid');
49
+ if (item.status !== 'running' && item.status !== 'completed' && item.status !== 'failed') {
50
+ throw new Error(`Run step status is invalid: ${item.id}`);
51
+ }
52
+ if (!Number.isInteger(item.attempts) || Number(item.attempts) < 1 || typeof item.startedAt !== 'string') {
53
+ throw new Error(`Run step attempt is invalid: ${item.id}`);
54
+ }
55
+ return item;
56
+ }
@@ -0,0 +1,14 @@
1
+ import type { ClaimedAutomationRun, MachineRuns } from './machine.js';
2
+ export interface AutomationMachineRunnerOptions {
3
+ readonly runs: MachineRuns;
4
+ readonly execute: (run: ClaimedAutomationRun) => Promise<void>;
5
+ readonly batchSize?: number;
6
+ readonly leaseSeconds?: number;
7
+ readonly pollIntervalMs?: number;
8
+ readonly maxBackoffMs?: number;
9
+ readonly log?: (event: string, details?: Readonly<Record<string, unknown>>) => void;
10
+ }
11
+ export declare function createAutomationMachineRunner(options: AutomationMachineRunnerOptions): Readonly<{
12
+ start(): void;
13
+ close(): Promise<void>;
14
+ }>;
@@ -0,0 +1,70 @@
1
+ export function createAutomationMachineRunner(options) {
2
+ const batchSize = integer(options.batchSize ?? 8, 1, 20, 'batchSize');
3
+ const leaseSeconds = integer(options.leaseSeconds ?? 60, 30, 900, 'leaseSeconds');
4
+ const pollIntervalMs = integer(options.pollIntervalMs ?? 1_000, 1, 60_000, 'pollIntervalMs');
5
+ const maxBackoffMs = integer(options.maxBackoffMs ?? Math.max(30_000, pollIntervalMs), pollIntervalMs, 300_000, 'maxBackoffMs');
6
+ let active = null;
7
+ let timer = null;
8
+ let stopped = true;
9
+ let failures = 0;
10
+ let nextDelay = pollIntervalMs;
11
+ const schedule = (delay) => {
12
+ if (stopped)
13
+ return;
14
+ timer = setTimeout(drain, delay);
15
+ timer.unref?.();
16
+ };
17
+ const drain = () => {
18
+ if (stopped || active)
19
+ return active;
20
+ active = options.runs.claim({ limit: batchSize, leaseSeconds })
21
+ .then(async (runs) => {
22
+ failures = 0;
23
+ if (runs.length)
24
+ options.log?.('automations.claimed', { count: runs.length });
25
+ const settled = await Promise.allSettled(runs.map(options.execute));
26
+ settled.forEach((result) => {
27
+ if (result.status === 'rejected') {
28
+ options.log?.('automations.run.failed', { error: safe(result.reason) });
29
+ }
30
+ });
31
+ nextDelay = runs.length === batchSize ? 0 : pollIntervalMs;
32
+ })
33
+ .catch((error) => {
34
+ failures += 1;
35
+ const delayMs = Math.min(maxBackoffMs, pollIntervalMs * (2 ** Math.min(failures - 1, 10)));
36
+ options.log?.('automations.poll.failed', { error: safe(error), retryInMs: delayMs });
37
+ nextDelay = delayMs;
38
+ })
39
+ .finally(() => {
40
+ active = null;
41
+ schedule(nextDelay);
42
+ });
43
+ return active;
44
+ };
45
+ return Object.freeze({
46
+ start() {
47
+ if (!stopped)
48
+ return;
49
+ stopped = false;
50
+ failures = 0;
51
+ void drain();
52
+ },
53
+ async close() {
54
+ stopped = true;
55
+ if (timer)
56
+ clearTimeout(timer);
57
+ timer = null;
58
+ await active;
59
+ },
60
+ });
61
+ }
62
+ function integer(value, minimum, maximum, name) {
63
+ if (!Number.isInteger(value) || value < minimum || value > maximum) {
64
+ throw new Error(`${name} must be an integer from ${minimum} to ${maximum}`);
65
+ }
66
+ return value;
67
+ }
68
+ function safe(error) {
69
+ return (error instanceof Error ? error.message : String(error)).replace(/[\r\n]+/g, ' ').slice(0, 500);
70
+ }
@@ -13,22 +13,22 @@ export declare const pageQuerySchema: z.ZodObject<{
13
13
  }>;
14
14
  export declare const createAutomationSchema: z.ZodObject<{
15
15
  id: z.ZodOptional<z.ZodString>;
16
- targetId: z.ZodString;
16
+ targetId: z.ZodOptional<z.ZodString>;
17
17
  name: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
18
18
  description: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
19
19
  enabled: z.ZodOptional<z.ZodBoolean>;
20
20
  }, "strict", z.ZodTypeAny, {
21
- id?: string | undefined;
22
- targetId: string;
21
+ targetId?: string | undefined;
22
+ enabled?: boolean | undefined;
23
23
  name?: string | undefined;
24
+ id?: string | undefined;
24
25
  description?: string | undefined;
25
- enabled?: boolean | undefined;
26
26
  }, {
27
- id?: string | undefined;
28
- targetId: string;
27
+ targetId?: string | undefined;
28
+ enabled?: boolean | undefined;
29
29
  name?: string | undefined;
30
+ id?: string | undefined;
30
31
  description?: string | undefined;
31
- enabled?: boolean | undefined;
32
32
  }>;
33
33
  export declare const updateAutomationSchema: z.ZodEffects<z.ZodObject<{
34
34
  targetId: z.ZodOptional<z.ZodString>;
@@ -37,24 +37,24 @@ export declare const updateAutomationSchema: z.ZodEffects<z.ZodObject<{
37
37
  enabled: z.ZodOptional<z.ZodBoolean>;
38
38
  }, "strict", z.ZodTypeAny, {
39
39
  targetId?: string | undefined;
40
+ enabled?: boolean | undefined;
40
41
  name?: string | null | undefined;
41
42
  description?: string | null | undefined;
42
- enabled?: boolean | undefined;
43
43
  }, {
44
44
  targetId?: string | undefined;
45
+ enabled?: boolean | undefined;
45
46
  name?: string | null | undefined;
46
47
  description?: string | null | undefined;
47
- enabled?: boolean | undefined;
48
48
  }>, {
49
49
  targetId?: string | undefined;
50
+ enabled?: boolean | undefined;
50
51
  name?: string | null | undefined;
51
52
  description?: string | null | undefined;
52
- enabled?: boolean | undefined;
53
53
  }, {
54
54
  targetId?: string | undefined;
55
+ enabled?: boolean | undefined;
55
56
  name?: string | null | undefined;
56
57
  description?: string | null | undefined;
57
- enabled?: boolean | undefined;
58
58
  }>;
59
59
  export declare const listAutomationsSchema: z.ZodObject<{
60
60
  limit: z.ZodOptional<z.ZodNumber>;
@@ -63,15 +63,15 @@ export declare const listAutomationsSchema: z.ZodObject<{
63
63
  targetId: z.ZodOptional<z.ZodString>;
64
64
  enabled: z.ZodOptional<z.ZodBoolean>;
65
65
  }, "strict", z.ZodTypeAny, {
66
- limit?: number | undefined;
67
- offset?: number | undefined;
68
66
  targetId?: string | undefined;
69
67
  enabled?: boolean | undefined;
70
- }, {
71
68
  limit?: number | undefined;
72
69
  offset?: number | undefined;
70
+ }, {
73
71
  targetId?: string | undefined;
74
72
  enabled?: boolean | undefined;
73
+ limit?: number | undefined;
74
+ offset?: number | undefined;
75
75
  }>;
76
76
  export declare const createScheduleTriggerSchema: z.ZodObject<{
77
77
  id: z.ZodOptional<z.ZodString>;
@@ -80,16 +80,16 @@ export declare const createScheduleTriggerSchema: z.ZodObject<{
80
80
  enabled: z.ZodOptional<z.ZodBoolean>;
81
81
  maxOccurrences: z.ZodOptional<z.ZodNumber>;
82
82
  }, "strict", z.ZodTypeAny, {
83
- id?: string | undefined;
84
83
  cron: string;
85
- timezone?: string | undefined;
86
84
  enabled?: boolean | undefined;
85
+ id?: string | undefined;
86
+ timezone?: string | undefined;
87
87
  maxOccurrences?: number | undefined;
88
88
  }, {
89
- id?: string | undefined;
90
89
  cron: string;
91
- timezone?: string | undefined;
92
90
  enabled?: boolean | undefined;
91
+ id?: string | undefined;
92
+ timezone?: string | undefined;
93
93
  maxOccurrences?: number | undefined;
94
94
  }>;
95
95
  export declare const updateScheduleTriggerSchema: z.ZodEffects<z.ZodObject<{
@@ -98,24 +98,24 @@ export declare const updateScheduleTriggerSchema: z.ZodEffects<z.ZodObject<{
98
98
  enabled: z.ZodOptional<z.ZodBoolean>;
99
99
  maxOccurrences: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
100
100
  }, "strict", z.ZodTypeAny, {
101
+ enabled?: boolean | undefined;
101
102
  cron?: string | undefined;
102
103
  timezone?: string | undefined;
103
- enabled?: boolean | undefined;
104
104
  maxOccurrences?: number | null | undefined;
105
105
  }, {
106
+ enabled?: boolean | undefined;
106
107
  cron?: string | undefined;
107
108
  timezone?: string | undefined;
108
- enabled?: boolean | undefined;
109
109
  maxOccurrences?: number | null | undefined;
110
110
  }>, {
111
+ enabled?: boolean | undefined;
111
112
  cron?: string | undefined;
112
113
  timezone?: string | undefined;
113
- enabled?: boolean | undefined;
114
114
  maxOccurrences?: number | null | undefined;
115
115
  }, {
116
+ enabled?: boolean | undefined;
116
117
  cron?: string | undefined;
117
118
  timezone?: string | undefined;
118
- enabled?: boolean | undefined;
119
119
  maxOccurrences?: number | null | undefined;
120
120
  }>;
121
121
  export declare const createWebhookTriggerSchema: z.ZodObject<{
@@ -125,17 +125,17 @@ export declare const createWebhookTriggerSchema: z.ZodObject<{
125
125
  secret: z.ZodString;
126
126
  enabled: z.ZodOptional<z.ZodBoolean>;
127
127
  }, "strict", z.ZodTypeAny, {
128
- id?: string | undefined;
129
- source?: string | undefined;
130
- event?: string | undefined;
131
128
  secret: string;
132
129
  enabled?: boolean | undefined;
133
- }, {
134
- id?: string | undefined;
135
- source?: string | undefined;
136
130
  event?: string | undefined;
131
+ source?: string | undefined;
132
+ id?: string | undefined;
133
+ }, {
137
134
  secret: string;
138
135
  enabled?: boolean | undefined;
136
+ event?: string | undefined;
137
+ source?: string | undefined;
138
+ id?: string | undefined;
139
139
  }>;
140
140
  export declare const updateWebhookTriggerSchema: z.ZodEffects<z.ZodObject<{
141
141
  source: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
@@ -143,25 +143,25 @@ export declare const updateWebhookTriggerSchema: z.ZodEffects<z.ZodObject<{
143
143
  secret: z.ZodOptional<z.ZodString>;
144
144
  enabled: z.ZodOptional<z.ZodBoolean>;
145
145
  }, "strict", z.ZodTypeAny, {
146
- source?: string | undefined;
146
+ enabled?: boolean | undefined;
147
147
  event?: string | undefined;
148
148
  secret?: string | undefined;
149
- enabled?: boolean | undefined;
150
- }, {
151
149
  source?: string | undefined;
150
+ }, {
151
+ enabled?: boolean | undefined;
152
152
  event?: string | undefined;
153
153
  secret?: string | undefined;
154
- enabled?: boolean | undefined;
155
- }>, {
156
154
  source?: string | undefined;
155
+ }>, {
156
+ enabled?: boolean | undefined;
157
157
  event?: string | undefined;
158
158
  secret?: string | undefined;
159
- enabled?: boolean | undefined;
160
- }, {
161
159
  source?: string | undefined;
160
+ }, {
161
+ enabled?: boolean | undefined;
162
162
  event?: string | undefined;
163
163
  secret?: string | undefined;
164
- enabled?: boolean | undefined;
164
+ source?: string | undefined;
165
165
  }>;
166
166
  export declare const createWorkflowSchema: z.ZodObject<{
167
167
  id: z.ZodOptional<z.ZodString>;
@@ -171,17 +171,17 @@ export declare const createWorkflowSchema: z.ZodObject<{
171
171
  allowlist: z.ZodOptional<z.ZodType<Json, z.ZodTypeDef, Json>>;
172
172
  limits: z.ZodOptional<z.ZodType<Json, z.ZodTypeDef, Json>>;
173
173
  }, "strict", z.ZodTypeAny, {
174
- id?: string | undefined;
175
- name?: string | undefined;
176
174
  script: string;
175
+ name?: string | undefined;
177
176
  compiled?: Json | undefined;
177
+ id?: string | undefined;
178
178
  allowlist?: Json | undefined;
179
179
  limits?: Json | undefined;
180
180
  }, {
181
- id?: string | undefined;
182
- name?: string | undefined;
183
181
  script: string;
182
+ name?: string | undefined;
184
183
  compiled?: Json | undefined;
184
+ id?: string | undefined;
185
185
  allowlist?: Json | undefined;
186
186
  limits?: Json | undefined;
187
187
  }>;
@@ -193,26 +193,26 @@ export declare const updateWorkflowSchema: z.ZodEffects<z.ZodObject<{
193
193
  limits: z.ZodOptional<z.ZodNullable<z.ZodType<Json, z.ZodTypeDef, Json>>>;
194
194
  }, "strict", z.ZodTypeAny, {
195
195
  name?: string | null | undefined;
196
- script?: string | undefined;
197
196
  compiled?: Json | undefined;
197
+ script?: string | undefined;
198
198
  allowlist?: Json | undefined;
199
199
  limits?: Json | undefined;
200
200
  }, {
201
201
  name?: string | null | undefined;
202
- script?: string | undefined;
203
202
  compiled?: Json | undefined;
203
+ script?: string | undefined;
204
204
  allowlist?: Json | undefined;
205
205
  limits?: Json | undefined;
206
206
  }>, {
207
207
  name?: string | null | undefined;
208
- script?: string | undefined;
209
208
  compiled?: Json | undefined;
209
+ script?: string | undefined;
210
210
  allowlist?: Json | undefined;
211
211
  limits?: Json | undefined;
212
212
  }, {
213
213
  name?: string | null | undefined;
214
- script?: string | undefined;
215
214
  compiled?: Json | undefined;
215
+ script?: string | undefined;
216
216
  allowlist?: Json | undefined;
217
217
  limits?: Json | undefined;
218
218
  }>;
@@ -222,13 +222,13 @@ export declare const listRunsSchema: z.ZodObject<{
222
222
  } & {
223
223
  status: z.ZodOptional<z.ZodEnum<["pending", "sent", "running", "completed", "failed"]>>;
224
224
  }, "strict", z.ZodTypeAny, {
225
+ status?: "pending" | "sent" | "running" | "completed" | "failed" | undefined;
225
226
  limit?: number | undefined;
226
227
  offset?: number | undefined;
227
- status?: "completed" | "failed" | "pending" | "running" | "sent" | undefined;
228
228
  }, {
229
+ status?: "pending" | "sent" | "running" | "completed" | "failed" | undefined;
229
230
  limit?: number | undefined;
230
231
  offset?: number | undefined;
231
- status?: "completed" | "failed" | "pending" | "running" | "sent" | undefined;
232
232
  }>;
233
233
  export declare function parseCreateAutomation(value: unknown): CreateAutomation;
234
234
  export declare function parseUpdateAutomation(value: unknown): UpdateAutomation;
@@ -1,5 +1,6 @@
1
1
  import { z } from 'zod/v3';
2
2
  import { ValidationError } from './errors.js';
3
+ import { compiledAutomationPlan } from './plan.js';
3
4
  import { IDENTIFIER } from './validation.js';
4
5
  const maxPageSize = 100;
5
6
  const identifierMessage = 'Identifier is invalid';
@@ -21,7 +22,7 @@ const jsonSchema = z.lazy(() => z.union([
21
22
  ]));
22
23
  export const createAutomationSchema = z.object({
23
24
  id: identifierSchema.optional(),
24
- targetId: identifierSchema,
25
+ targetId: identifierSchema.optional(),
25
26
  name: text(500, 'Automation name').optional(),
26
27
  description: text(10_000, 'Automation description').optional(),
27
28
  enabled: z.boolean().optional(),
@@ -102,10 +103,16 @@ export function parseUpdateWebhookTrigger(value) {
102
103
  return parse(updateWebhookTriggerSchema, value);
103
104
  }
104
105
  export function parseCreateWorkflow(value) {
105
- return parse(createWorkflowSchema, value);
106
+ const workflow = parse(createWorkflowSchema, value);
107
+ if (workflow.compiled !== undefined)
108
+ validateCompiledPlan(workflow.compiled);
109
+ return workflow;
106
110
  }
107
111
  export function parseUpdateWorkflow(value) {
108
- return parse(updateWorkflowSchema, value);
112
+ const workflow = parse(updateWorkflowSchema, value);
113
+ if (workflow.compiled !== undefined && workflow.compiled !== null)
114
+ validateCompiledPlan(workflow.compiled);
115
+ return workflow;
109
116
  }
110
117
  export function parsePageQuery(value) {
111
118
  return parse(pageQuerySchema, value);
@@ -119,3 +126,11 @@ export function parse(schema, value) {
119
126
  return result.data;
120
127
  throw new ValidationError(result.error.issues[0]?.message || 'Input is invalid');
121
128
  }
129
+ function validateCompiledPlan(value) {
130
+ try {
131
+ compiledAutomationPlan(value);
132
+ }
133
+ catch (error) {
134
+ throw new ValidationError(error instanceof Error ? error.message : String(error));
135
+ }
136
+ }
@@ -58,6 +58,8 @@ export function run(row) {
58
58
  workflowId: row.workflow_id,
59
59
  targetId: row.target_id,
60
60
  status: row.status,
61
+ attempts: row.attempts,
62
+ ...(row.retry_at ? { retryAt: timestamp(row.retry_at) } : {}),
61
63
  input: row.input,
62
64
  createdAt: timestamp(row.created_at),
63
65
  ...(row.sent_at ? { sentAt: timestamp(row.sent_at) } : {}),
@@ -42,6 +42,8 @@ export type RunRow = {
42
42
  workflow_id: string;
43
43
  target_id: string;
44
44
  status: AutomationRun['status'];
45
+ attempts: number;
46
+ retry_at: Date | string | null;
45
47
  input: AutomationRun['input'];
46
48
  created_at: Date | string;
47
49
  sent_at: Date | string | null;
@@ -43,6 +43,7 @@ function run(row) {
43
43
  input: row.input,
44
44
  status: row.status,
45
45
  attempts: row.attempts,
46
+ ...(row.retry_at ? { retryAt: timestamp(row.retry_at) } : {}),
46
47
  leaseToken: row.lease_token,
47
48
  leaseExpiresAt: timestamp(row.lease_expires_at),
48
49
  createdAt: timestamp(row.created_at),
@@ -56,6 +57,7 @@ function run(row) {
56
57
  function update(value) {
57
58
  return {
58
59
  status: value.status,
60
+ ...(value.retryAt === undefined ? {} : { retryAt: value.retryAt }),
59
61
  ...(value.output === undefined ? {} : { output: value.output }),
60
62
  ...(value.error === undefined ? {} : { error: value.error }),
61
63
  };
@@ -1,4 +1,4 @@
1
- import type { AutomationStore, AutomationTarget, AutomationRun, DueCronTrigger, RunInput, RunUpdate, StoredEventTrigger } from './types.js';
1
+ import type { AutomationStore, AutomationTarget, AutomationRun, DueCronTrigger, RunInput, StoredEventTrigger } from './types.js';
2
2
  export interface SupabaseRpcClient {
3
3
  rpc(functionName: string, arguments_: Record<string, unknown>): PromiseLike<{
4
4
  data: unknown;
@@ -17,7 +17,4 @@ export declare class SupabaseStore implements AutomationStore {
17
17
  kind: 'event';
18
18
  }>, now: Date): Promise<AutomationRun | null>;
19
19
  enqueueCron(trigger: DueCronTrigger, nextRunAt: string, now: Date): Promise<AutomationRun | null>;
20
- pendingRuns(target: AutomationTarget): Promise<AutomationRun[]>;
21
- markSent(runId: string, target: AutomationTarget, now: Date): Promise<boolean>;
22
- updateRun(target: AutomationTarget, runId: string, update: RunUpdate): Promise<AutomationRun | null>;
23
20
  }
@@ -61,30 +61,6 @@ export class SupabaseStore {
61
61
  scheduledFor: trigger.nextRunAt,
62
62
  }, now, nextRunAt);
63
63
  }
64
- async pendingRuns(target) {
65
- const rows = await this.#call('list_amalgm_pending_runs', {
66
- p_user_id: target.userId,
67
- p_target_id: target.targetId,
68
- });
69
- return rows.map(automationRun);
70
- }
71
- markSent(runId, target, now) {
72
- return this.#call('mark_amalgm_run_sent', {
73
- p_run_id: runId,
74
- p_user_id: target.userId,
75
- p_target_id: target.targetId,
76
- p_now: now.toISOString(),
77
- });
78
- }
79
- async updateRun(target, runId, update) {
80
- const rows = await this.#call('update_amalgm_run', {
81
- p_run_id: runId,
82
- p_user_id: target.userId,
83
- p_target_id: target.targetId,
84
- p_update: update,
85
- });
86
- return rows[0] ? automationRun(rows[0]) : null;
87
- }
88
64
  async #enqueue(trigger, input, now, nextRunAt) {
89
65
  const rows = await this.#call('enqueue_amalgm_run', {
90
66
  p_kind: trigger.kind,
@@ -0,0 +1,46 @@
1
+ import type { Automation, AutomationCrud, AutomationRun, CreateAutomation, CreateScheduleTrigger, CreateWebhookTrigger, CreateWorkflow, ListAutomations, ListRuns, Page, Trigger, UpdateAutomation, UpdateScheduleTrigger, UpdateWebhookTrigger, UpdateWorkflow, Workflow } from './contract.js';
2
+ export interface AutomationView {
3
+ automation: Automation;
4
+ triggers: Trigger[];
5
+ workflow: Workflow | null;
6
+ runs?: Page<AutomationRun>;
7
+ }
8
+ export interface CreateAutomationDefinition extends CreateAutomation {
9
+ schedules?: CreateScheduleTrigger[];
10
+ webhooks?: CreateWebhookTrigger[];
11
+ workflow?: CreateWorkflow;
12
+ }
13
+ interface Changes<Create extends {
14
+ id?: string;
15
+ }, Update> {
16
+ create?: Create[];
17
+ update?: Array<{
18
+ id: string;
19
+ patch: Update;
20
+ }>;
21
+ delete?: string[];
22
+ }
23
+ export type WorkflowChange = {
24
+ create: CreateWorkflow;
25
+ } | {
26
+ update: UpdateWorkflow;
27
+ } | {
28
+ delete: true;
29
+ };
30
+ export interface UpdateAutomationDefinition {
31
+ patch?: UpdateAutomation;
32
+ schedules?: Changes<CreateScheduleTrigger, UpdateScheduleTrigger>;
33
+ webhooks?: Changes<CreateWebhookTrigger, UpdateWebhookTrigger>;
34
+ workflow?: WorkflowChange;
35
+ }
36
+ export interface AutomationToolSurface {
37
+ create(input: CreateAutomationDefinition): Promise<AutomationView>;
38
+ list(query?: ListAutomations): Promise<Page<Automation>>;
39
+ get(automationId: string, runs?: false | ListRuns): Promise<AutomationView>;
40
+ update(automationId: string, input: UpdateAutomationDefinition): Promise<AutomationView>;
41
+ delete(automationId: string): Promise<{
42
+ deleted: string;
43
+ }>;
44
+ }
45
+ export declare function createAutomationToolSurface(sdk: AutomationCrud): AutomationToolSurface;
46
+ export {};